Compare commits
124 Commits
v2.5.4.8d2
...
v2.5.7.f77
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f77c87dca8 | ||
|
|
198b62f3fc | ||
|
|
3e5f129fce | ||
|
|
ad214ea42a | ||
|
|
25b557cf46 | ||
|
|
7fd1c334d3 | ||
|
|
696bcc60af | ||
|
|
af0db8a29f | ||
|
|
ea20bb1836 | ||
|
|
420ab89f8d | ||
|
|
1212969ff7 | ||
|
|
e49e584ae1 | ||
|
|
89c1e041e1 | ||
|
|
655e58f424 | ||
|
|
0ec1684718 | ||
|
|
05e4a639a1 | ||
|
|
fb9f361052 | ||
|
|
37448205b5 | ||
|
|
015f7335b0 | ||
|
|
48d8b85a3b | ||
|
|
363fd8ab98 | ||
|
|
323e7503ea | ||
|
|
4e4431560e | ||
|
|
a8c216f4f8 | ||
|
|
9d0729c83f | ||
|
|
3c89716074 | ||
|
|
ec96256bcd | ||
|
|
1f2d972e18 | ||
|
|
cc87002a8a | ||
|
|
8ab772221d | ||
|
|
d55c08d5cd | ||
|
|
e8f287a36f | ||
|
|
b769799410 | ||
|
|
f5f9fd54a1 | ||
|
|
f82585d9b0 | ||
|
|
1b04d41b9a | ||
|
|
3b21856a76 | ||
|
|
519ca9c0aa | ||
|
|
23a52ee625 | ||
|
|
7ff4bafe22 | ||
|
|
149620f071 | ||
|
|
0cbade989e | ||
|
|
411834afba | ||
|
|
1096973828 | ||
|
|
dc9aa6aff7 | ||
|
|
ad8747d914 | ||
|
|
ddd4a45bc3 | ||
|
|
4f8f96ab29 | ||
|
|
ee5091fee5 | ||
|
|
876993f095 | ||
|
|
a05b009379 | ||
|
|
5db4918413 | ||
|
|
a0dd7b43d5 | ||
|
|
b1f045cab8 | ||
|
|
2e5399dbe4 | ||
|
|
d005b1e49c | ||
|
|
9d9258a59b | ||
|
|
37f294d0a6 | ||
|
|
411aedaf5d | ||
|
|
1c54388bb8 | ||
|
|
94ecbad904 | ||
|
|
53f189fff4 | ||
|
|
93d874b013 | ||
|
|
234a56446b | ||
|
|
830281803f | ||
|
|
bb9f003c24 | ||
|
|
001a845ac3 | ||
|
|
7febb41727 | ||
|
|
ad031dd69f | ||
|
|
ebc3a66d10 | ||
|
|
553e572eb5 | ||
|
|
01df3ff477 | ||
|
|
a3a97d3025 | ||
|
|
0952d1b252 | ||
|
|
8a370c5381 | ||
|
|
a6f96cb9b4 | ||
|
|
d650001caa | ||
|
|
0c90a2274f | ||
|
|
dac433ed2f | ||
|
|
8acc9ccf5f | ||
|
|
243421b2a5 | ||
|
|
6d6ed55ed7 | ||
|
|
783466f116 | ||
|
|
55049ed547 | ||
|
|
e182ae75c2 | ||
|
|
7e946d15ca | ||
|
|
c3b9d493b6 | ||
|
|
4db0c75c8e | ||
|
|
e7cfadacd8 | ||
|
|
673fe294f3 | ||
|
|
236374491b | ||
|
|
d6f26c682d | ||
|
|
befc2ece6f | ||
|
|
b2b60eccdb | ||
|
|
07d4e6f5be | ||
|
|
0a93261c06 | ||
|
|
00f15459ec | ||
|
|
b8044c4983 | ||
|
|
18f12584ab | ||
|
|
e1e7bbc420 | ||
|
|
5f974d2961 | ||
|
|
cae2e43dc6 | ||
|
|
0d175a918c | ||
|
|
3440c640c3 | ||
|
|
b769d9f854 | ||
|
|
e6e05dda1e | ||
|
|
82f1be33aa | ||
|
|
db4a793aa9 | ||
|
|
b39aca8d11 | ||
|
|
6c327d960d | ||
|
|
cd480846e9 | ||
|
|
9f3a1c1214 | ||
|
|
c4c85777d0 | ||
|
|
ca8d2204ba | ||
|
|
a388e78842 | ||
|
|
35cdc81d45 | ||
|
|
0c42f79038 | ||
|
|
4fc3782ea3 | ||
|
|
9ac4a0114f | ||
|
|
9188786581 | ||
|
|
b2417f651a | ||
|
|
d02ba45109 | ||
|
|
c6bffd7d7f | ||
|
|
a5b79528b3 |
6
.github/actions/build-variant/action.yml
vendored
@@ -31,6 +31,10 @@ inputs:
|
|||||||
description: Include the web UI in the build
|
description: Include the web UI in the build
|
||||||
required: false
|
required: false
|
||||||
default: "false"
|
default: "false"
|
||||||
|
arch:
|
||||||
|
description: Processor arch name
|
||||||
|
required: true
|
||||||
|
default: "esp32"
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: composite
|
using: composite
|
||||||
@@ -84,7 +88,7 @@ runs:
|
|||||||
- name: Store binaries as an artifact
|
- name: Store binaries as an artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
|
name: firmware-${{ inputs.arch }}-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
${{ inputs.artifact-paths }}
|
${{ inputs.artifact-paths }}
|
||||||
|
|||||||
5
.github/actions/setup-base/action.yml
vendored
@@ -11,6 +11,11 @@ runs:
|
|||||||
ref: ${{github.event.pull_request.head.ref}}
|
ref: ${{github.event.pull_request.head.ref}}
|
||||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||||
|
|
||||||
|
- name: Uncomment build epoch
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
sed -i 's/#-DBUILD_EPOCH=$UNIX_TIME/-DBUILD_EPOCH=$UNIX_TIME/' platformio.ini
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
1
.github/workflows/build_esp32.yml
vendored
@@ -31,3 +31,4 @@ jobs:
|
|||||||
release/*.bin
|
release/*.bin
|
||||||
release/*.elf
|
release/*.elf
|
||||||
include-web-ui: true
|
include-web-ui: true
|
||||||
|
arch: esp32
|
||||||
|
|||||||
1
.github/workflows/build_esp32_c3.yml
vendored
@@ -32,3 +32,4 @@ jobs:
|
|||||||
artifact-paths: |
|
artifact-paths: |
|
||||||
release/*.bin
|
release/*.bin
|
||||||
release/*.elf
|
release/*.elf
|
||||||
|
arch: esp32c3
|
||||||
|
|||||||
1
.github/workflows/build_esp32_c6.yml
vendored
@@ -33,3 +33,4 @@ jobs:
|
|||||||
artifact-paths: |
|
artifact-paths: |
|
||||||
release/*.bin
|
release/*.bin
|
||||||
release/*.elf
|
release/*.elf
|
||||||
|
arch: esp32c6
|
||||||
|
|||||||
1
.github/workflows/build_esp32_s3.yml
vendored
@@ -31,3 +31,4 @@ jobs:
|
|||||||
release/*.bin
|
release/*.bin
|
||||||
release/*.elf
|
release/*.elf
|
||||||
include-web-ui: true
|
include-web-ui: true
|
||||||
|
arch: esp32s3
|
||||||
|
|||||||
1
.github/workflows/build_nrf52.yml
vendored
@@ -25,3 +25,4 @@ jobs:
|
|||||||
release/*.uf2
|
release/*.uf2
|
||||||
release/*.elf
|
release/*.elf
|
||||||
release/*.zip
|
release/*.zip
|
||||||
|
arch: nrf52840
|
||||||
|
|||||||
1
.github/workflows/build_rpi2040.yml
vendored
@@ -23,3 +23,4 @@ jobs:
|
|||||||
artifact-paths: |
|
artifact-paths: |
|
||||||
release/*.uf2
|
release/*.uf2
|
||||||
release/*.elf
|
release/*.elf
|
||||||
|
arch: rp2040
|
||||||
|
|||||||
2
.github/workflows/build_stm32.yml
vendored
@@ -23,3 +23,5 @@ jobs:
|
|||||||
artifact-paths: |
|
artifact-paths: |
|
||||||
release/*.hex
|
release/*.hex
|
||||||
release/*.bin
|
release/*.bin
|
||||||
|
release/*.elf
|
||||||
|
arch: stm32
|
||||||
|
|||||||
35
.github/workflows/generate-userprefs.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
name: Generate UsersPrefs JSON manifest
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- userPrefs.h
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
generate-userprefs:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install Clang
|
||||||
|
run: sudo apt-get install -y clang
|
||||||
|
|
||||||
|
- name: Install trunk
|
||||||
|
run: curl https://get.trunk.io -fsSL | bash
|
||||||
|
|
||||||
|
- name: Generate userPrefs.jsom
|
||||||
|
run: python3 ./bin/build-userprefs-json.py
|
||||||
|
|
||||||
|
- name: Trunk format json
|
||||||
|
run: trunk format userPrefs.json
|
||||||
|
|
||||||
|
- name: Commit userPrefs.json
|
||||||
|
run: |
|
||||||
|
git config --global user.email "actions@github.com"
|
||||||
|
git config --global user.name "GitHub Actions"
|
||||||
|
git add userPrefs.json
|
||||||
|
git commit -m "Update userPrefs.json"
|
||||||
|
git push
|
||||||
198
.github/workflows/main_matrix.yml
vendored
@@ -2,9 +2,6 @@ name: CI
|
|||||||
concurrency:
|
concurrency:
|
||||||
group: ci-${{ github.head_ref || github.run_id }}
|
group: ci-${{ github.head_ref || github.run_id }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
#concurrency:
|
|
||||||
# group: ${{ github.ref }}
|
|
||||||
# cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
|
|
||||||
on:
|
on:
|
||||||
# # Triggers the workflow on push but only for the master branch
|
# # Triggers the workflow on push but only for the master branch
|
||||||
push:
|
push:
|
||||||
@@ -137,8 +134,8 @@ jobs:
|
|||||||
package-raspbian-armv7l:
|
package-raspbian-armv7l:
|
||||||
uses: ./.github/workflows/package_raspbian_armv7l.yml
|
uses: ./.github/workflows/package_raspbian_armv7l.yml
|
||||||
|
|
||||||
# package-native:
|
package-native:
|
||||||
# uses: ./.github/workflows/package_amd64.yml
|
uses: ./.github/workflows/package_amd64.yml
|
||||||
|
|
||||||
after-checks:
|
after-checks:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -155,8 +152,13 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
arch: [esp32, esp32s3, esp32c3, esp32c6, nrf52840, rp2040, stm32]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [
|
needs:
|
||||||
|
[
|
||||||
build-esp32,
|
build-esp32,
|
||||||
build-esp32-s3,
|
build-esp32-s3,
|
||||||
build-esp32-c3,
|
build-esp32-c3,
|
||||||
@@ -164,9 +166,6 @@ jobs:
|
|||||||
build-nrf52,
|
build-nrf52,
|
||||||
build-rpi2040,
|
build-rpi2040,
|
||||||
build-stm32,
|
build-stm32,
|
||||||
package-raspbian,
|
|
||||||
package-raspbian-armv7l,
|
|
||||||
# package-native,
|
|
||||||
]
|
]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
@@ -178,6 +177,7 @@ jobs:
|
|||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: ./
|
path: ./
|
||||||
|
pattern: firmware-${{matrix.arch}}-*
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
|
|
||||||
- name: Display structure of downloaded files
|
- name: Display structure of downloaded files
|
||||||
@@ -188,12 +188,12 @@ jobs:
|
|||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Move files up
|
- name: Move files up
|
||||||
run: mv -b -t ./ ./release/meshtasticd_linux_* ./bin/config-dist.yaml ./bin/device-*.sh ./bin/device-*.bat
|
run: mv -b -t ./ ./bin/device-*.sh ./bin/device-*.bat
|
||||||
|
|
||||||
- name: Repackage in single firmware zip
|
- name: Repackage in single firmware zip
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-${{ steps.version.outputs.version }}
|
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: |
|
path: |
|
||||||
./firmware-*.bin
|
./firmware-*.bin
|
||||||
@@ -202,16 +202,14 @@ jobs:
|
|||||||
./firmware-*-ota.zip
|
./firmware-*-ota.zip
|
||||||
./device-*.sh
|
./device-*.sh
|
||||||
./device-*.bat
|
./device-*.bat
|
||||||
./meshtasticd_linux_*
|
|
||||||
./config-dist.yaml
|
|
||||||
./littlefs-*.bin
|
./littlefs-*.bin
|
||||||
./bleota*bin
|
./bleota*bin
|
||||||
./Meshtastic_nRF52_factory_erase*.uf2
|
./Meshtastic_nRF52_factory_erase*.uf2
|
||||||
retention-days: 90
|
retention-days: 30
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: firmware-${{ steps.version.outputs.version }}
|
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
path: ./output
|
path: ./output
|
||||||
|
|
||||||
@@ -225,12 +223,12 @@ jobs:
|
|||||||
chmod +x ./output/device-update.sh
|
chmod +x ./output/device-update.sh
|
||||||
|
|
||||||
- name: Zip firmware
|
- name: Zip firmware
|
||||||
run: zip -j -9 -r ./firmware-${{ steps.version.outputs.version }}.zip ./output
|
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./output
|
||||||
|
|
||||||
- name: Repackage in single elfs zip
|
- name: Repackage in single elfs zip
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: debug-elfs-${{ steps.version.outputs.version }}.zip
|
name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
|
||||||
overwrite: true
|
overwrite: true
|
||||||
path: ./*.elf
|
path: ./*.elf
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
@@ -238,14 +236,21 @@ jobs:
|
|||||||
- uses: scruplelesswizard/comment-artifact@main
|
- uses: scruplelesswizard/comment-artifact@main
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
with:
|
with:
|
||||||
name: firmware-${{ steps.version.outputs.version }}
|
name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
|
||||||
description: "Download firmware-${{ steps.version.outputs.version }}.zip. This artifact will be available for 90 days from creation"
|
description: "Download firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip. This artifact will be available for 90 days from creation"
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
release-artifacts:
|
release-artifacts:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||||
needs: [gather-artifacts]
|
outputs:
|
||||||
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
|
needs: [
|
||||||
|
gather-artifacts,
|
||||||
|
package-raspbian,
|
||||||
|
package-raspbian-armv7l,
|
||||||
|
package-native,
|
||||||
|
]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -259,36 +264,6 @@ jobs:
|
|||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: firmware-${{ steps.version.outputs.version }}
|
|
||||||
merge-multiple: true
|
|
||||||
path: ./output
|
|
||||||
|
|
||||||
- name: Display structure of downloaded files
|
|
||||||
run: ls -R
|
|
||||||
|
|
||||||
- name: Device scripts permissions
|
|
||||||
run: |
|
|
||||||
chmod +x ./output/device-install.sh
|
|
||||||
chmod +x ./output/device-update.sh
|
|
||||||
|
|
||||||
- name: Zip firmware
|
|
||||||
run: zip -j -9 -r ./firmware-${{ steps.version.outputs.version }}.zip ./output -x meshtasticd_*
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: debug-elfs-${{ steps.version.outputs.version }}.zip
|
|
||||||
merge-multiple: true
|
|
||||||
path: ./elfs
|
|
||||||
|
|
||||||
- name: Zip Elfs
|
|
||||||
run: zip -j -9 -r ./debug-elfs-${{ steps.version.outputs.version }}.zip ./elfs
|
|
||||||
|
|
||||||
# For diagnostics
|
|
||||||
- name: Show artifacts
|
|
||||||
run: ls -lR
|
|
||||||
|
|
||||||
- name: Create release
|
- name: Create release
|
||||||
uses: actions/create-release@v1
|
uses: actions/create-release@v1
|
||||||
id: create_release
|
id: create_release
|
||||||
@@ -302,32 +277,17 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
|
|
||||||
- name: Add bins to release
|
- name: Download deb files
|
||||||
uses: actions/upload-release-asset@v1
|
uses: actions/download-artifact@v4
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
|
||||||
asset_path: ./firmware-${{ steps.version.outputs.version }}.zip
|
|
||||||
asset_name: firmware-${{ steps.version.outputs.version }}.zip
|
|
||||||
asset_content_type: application/zip
|
|
||||||
|
|
||||||
- name: Add debug elfs to release
|
|
||||||
uses: actions/upload-release-asset@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
|
||||||
asset_path: ./debug-elfs-${{ steps.version.outputs.version }}.zip
|
|
||||||
asset_name: debug-elfs-${{ steps.version.outputs.version }}.zip
|
|
||||||
asset_content_type: application/zip
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
with:
|
||||||
pattern: meshtasticd_${{ steps.version.outputs.version }}_*.deb
|
pattern: meshtasticd_${{ steps.version.outputs.version }}_*.deb
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
path: ./output
|
path: ./output
|
||||||
|
|
||||||
|
# For diagnostics
|
||||||
|
- name: Display structure of downloaded files
|
||||||
|
run: ls -lR
|
||||||
|
|
||||||
- name: Add raspbian aarch64 .deb
|
- name: Add raspbian aarch64 .deb
|
||||||
uses: actions/upload-release-asset@v1
|
uses: actions/upload-release-asset@v1
|
||||||
env:
|
env:
|
||||||
@@ -348,15 +308,15 @@ jobs:
|
|||||||
asset_name: meshtasticd_${{ steps.version.outputs.version }}_armhf.deb
|
asset_name: meshtasticd_${{ steps.version.outputs.version }}_armhf.deb
|
||||||
asset_content_type: application/vnd.debian.binary-package
|
asset_content_type: application/vnd.debian.binary-package
|
||||||
|
|
||||||
# - name: Add raspbian amd64 .deb
|
- name: Add raspbian amd64 .deb
|
||||||
# uses: actions/upload-release-asset@v1
|
uses: actions/upload-release-asset@v1
|
||||||
# env:
|
env:
|
||||||
# GITHUB_TOKEN: ${{ github.token }}
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
# with:
|
with:
|
||||||
# upload_url: ${{ steps.create_release.outputs.upload_url }}
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
# asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
|
asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
|
||||||
# asset_name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
|
asset_name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb
|
||||||
# asset_content_type: application/vnd.debian.binary-package
|
asset_content_type: application/vnd.debian.binary-package
|
||||||
|
|
||||||
- name: Bump version.properties
|
- name: Bump version.properties
|
||||||
run: >-
|
run: >-
|
||||||
@@ -369,29 +329,73 @@ jobs:
|
|||||||
add-paths: |
|
add-paths: |
|
||||||
version.properties
|
version.properties
|
||||||
|
|
||||||
- name: Checkout meshtastic/meshtastic.github.io
|
release-firmware:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
arch: [esp32, esp32s3, esp32c3, esp32c6, nrf52840, rp2040, stm32]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||||
|
needs: [release-artifacts]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
repository: meshtastic/meshtastic.github.io
|
python-version: 3.x
|
||||||
token: ${{ secrets.ARTIFACTS_TOKEN }}
|
|
||||||
path: meshtastic.github.io
|
- name: Get release version string
|
||||||
|
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
pattern: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}
|
||||||
|
merge-multiple: true
|
||||||
|
path: ./output
|
||||||
|
|
||||||
- name: Display structure of downloaded files
|
- name: Display structure of downloaded files
|
||||||
run: ls -R
|
run: ls -lR
|
||||||
|
|
||||||
- name: Extract firmware.zip
|
- name: Device scripts permissions
|
||||||
run: |
|
run: |
|
||||||
unzip ./firmware-${{ steps.version.outputs.version }}.zip -d meshtastic.github.io/firmware-${{ steps.version.outputs.version }}
|
chmod +x ./output/device-install.sh
|
||||||
|
chmod +x ./output/device-update.sh
|
||||||
|
|
||||||
|
- name: Zip firmware
|
||||||
|
run: zip -j -9 -r ./firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./output
|
||||||
|
|
||||||
|
- uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
|
||||||
|
merge-multiple: true
|
||||||
|
path: ./elfs
|
||||||
|
|
||||||
|
- name: Zip firmware
|
||||||
|
run: zip -j -9 -r ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip ./elfs
|
||||||
|
|
||||||
|
# For diagnostics
|
||||||
- name: Display structure of downloaded files
|
- name: Display structure of downloaded files
|
||||||
run: ls -R
|
run: ls -lR
|
||||||
|
|
||||||
- name: Commit and push changes
|
- name: Add bins to release
|
||||||
run: |
|
uses: actions/upload-release-asset@v1
|
||||||
cd meshtastic.github.io
|
env:
|
||||||
find . -type f -name 'meshtasticd_*' -exec rm -f {} +
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
git config --global user.name "github-actions[bot]"
|
with:
|
||||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
upload_url: ${{needs.release-artifacts.outputs.upload_url}}
|
||||||
git add .
|
asset_path: ./firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
|
||||||
git commit -m "Add firmware version ${{ steps.version.outputs.version }}"
|
asset_name: firmware-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
|
||||||
git push
|
asset_content_type: application/zip
|
||||||
|
|
||||||
|
- name: Add debug elfs to release
|
||||||
|
uses: actions/upload-release-asset@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
|
with:
|
||||||
|
upload_url: ${{needs.release-artifacts.outputs.upload_url}}
|
||||||
|
asset_path: ./debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
|
||||||
|
asset_name: debug-elfs-${{matrix.arch}}-${{ steps.version.outputs.version }}.zip
|
||||||
|
asset_content_type: application/zip
|
||||||
|
|||||||
6
.github/workflows/update_protobufs.yml
vendored
@@ -17,9 +17,9 @@ jobs:
|
|||||||
|
|
||||||
- name: Download nanopb
|
- name: Download nanopb
|
||||||
run: |
|
run: |
|
||||||
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8-linux-x86.tar.gz
|
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.9-linux-x86.tar.gz
|
||||||
tar xvzf nanopb-0.4.8-linux-x86.tar.gz
|
tar xvzf nanopb-0.4.9-linux-x86.tar.gz
|
||||||
mv nanopb-0.4.8-linux-x86 nanopb-0.4.8
|
mv nanopb-0.4.9-linux-x86 nanopb-0.4.9
|
||||||
|
|
||||||
- name: Re-generate protocol buffers
|
- name: Re-generate protocol buffers
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
4
.gitignore
vendored
@@ -1,6 +1,4 @@
|
|||||||
.pio
|
.pio
|
||||||
main/configuration.h
|
|
||||||
main/credentials.h
|
|
||||||
|
|
||||||
# ignore vscode IDE settings files
|
# ignore vscode IDE settings files
|
||||||
.vscode/*
|
.vscode/*
|
||||||
@@ -32,4 +30,4 @@ release/
|
|||||||
.vscode/extensions.json
|
.vscode/extensions.json
|
||||||
/compile_commands.json
|
/compile_commands.json
|
||||||
src/mesh/raspihttp/certificate.pem
|
src/mesh/raspihttp/certificate.pem
|
||||||
src/mesh/raspihttp/private_key.pem
|
src/mesh/raspihttp/private_key.pem
|
||||||
|
|||||||
@@ -1,34 +1,34 @@
|
|||||||
version: 0.1
|
version: 0.1
|
||||||
cli:
|
cli:
|
||||||
version: 1.22.5
|
version: 1.22.6
|
||||||
plugins:
|
plugins:
|
||||||
sources:
|
sources:
|
||||||
- id: trunk
|
- id: trunk
|
||||||
ref: v1.6.2
|
ref: v1.6.3
|
||||||
uri: https://github.com/trunk-io/plugins
|
uri: https://github.com/trunk-io/plugins
|
||||||
lint:
|
lint:
|
||||||
enabled:
|
enabled:
|
||||||
- trufflehog@3.82.5
|
- trufflehog@3.82.6
|
||||||
- yamllint@1.35.1
|
- yamllint@1.35.1
|
||||||
- bandit@1.7.10
|
- bandit@1.7.10
|
||||||
- checkov@3.2.255
|
- checkov@3.2.256
|
||||||
- terrascan@1.19.1
|
- terrascan@1.19.1
|
||||||
- trivy@0.55.2
|
- trivy@0.55.2
|
||||||
#- trufflehog@3.63.2-rc0
|
#- trufflehog@3.63.2-rc0
|
||||||
- taplo@0.9.3
|
- taplo@0.9.3
|
||||||
- ruff@0.6.7
|
- ruff@0.6.8
|
||||||
- isort@5.13.2
|
- isort@5.13.2
|
||||||
- markdownlint@0.42.0
|
- markdownlint@0.42.0
|
||||||
- oxipng@9.1.2
|
- oxipng@9.1.2
|
||||||
- svgo@3.3.2
|
- svgo@3.3.2
|
||||||
- actionlint@1.7.2
|
- actionlint@1.7.3
|
||||||
- flake8@7.1.1
|
- flake8@7.1.1
|
||||||
- hadolint@2.12.0
|
- hadolint@2.12.0
|
||||||
- shfmt@3.6.0
|
- shfmt@3.6.0
|
||||||
- shellcheck@0.10.0
|
- shellcheck@0.10.0
|
||||||
- black@24.8.0
|
- black@24.8.0
|
||||||
- git-diff-check
|
- git-diff-check
|
||||||
- gitleaks@8.19.2
|
- gitleaks@8.20.0
|
||||||
- clang-format@16.0.3
|
- clang-format@16.0.3
|
||||||
- prettier@3.3.3
|
- prettier@3.3.3
|
||||||
ignore:
|
ignore:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
[esp32_base]
|
[esp32_base]
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
custom_esp32_kind = esp32
|
custom_esp32_kind = esp32
|
||||||
platform = platformio/espressif32@6.7.0
|
platform = platformio/espressif32@6.9.0
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>
|
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp>
|
||||||
@@ -46,7 +46,7 @@ lib_deps =
|
|||||||
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
|
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
|
||||||
h2zero/NimBLE-Arduino@^1.4.2
|
h2zero/NimBLE-Arduino@^1.4.2
|
||||||
https://github.com/dbSuS/libpax.git#7bcd3fcab75037505be9b122ab2b24cc5176b587
|
https://github.com/dbSuS/libpax.git#7bcd3fcab75037505be9b122ab2b24cc5176b587
|
||||||
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
|
lewisxhe/XPowersLib@^0.2.6
|
||||||
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
|
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
|
||||||
rweather/Crypto@^0.4.0
|
rweather/Crypto@^0.4.0
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ lib_deps =
|
|||||||
${arduino_base.lib_deps}
|
${arduino_base.lib_deps}
|
||||||
${networking_base.lib_deps}
|
${networking_base.lib_deps}
|
||||||
${environmental_base.lib_deps}
|
${environmental_base.lib_deps}
|
||||||
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
|
lewisxhe/XPowersLib@^0.2.6
|
||||||
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
|
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
|
||||||
rweather/Crypto@^0.4.0
|
rweather/Crypto@^0.4.0
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ lib_deps =
|
|||||||
${env.lib_deps}
|
${env.lib_deps}
|
||||||
${networking_base.lib_deps}
|
${networking_base.lib_deps}
|
||||||
rweather/Crypto@^0.4.0
|
rweather/Crypto@^0.4.0
|
||||||
https://github.com/lovyan03/LovyanGFX.git#5a39989aa2c9492572255b22f033843ec8900233
|
lovyan03/LovyanGFX@^1.1.16
|
||||||
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${arduino_base.build_flags}
|
${arduino_base.build_flags}
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
; 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#60d6ae81fcc73c34b1493ca9e261695e471bc0c2
|
platform = https://github.com/maxgerhardt/platform-raspberrypi.git#v1.2.0-gcc12
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#3.7.2
|
platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#4.0.3
|
||||||
|
|
||||||
board_build.core = earlephilhower
|
board_build.core = earlephilhower
|
||||||
board_build.filesystem_size = 0.5m
|
board_build.filesystem_size = 0.5m
|
||||||
build_flags =
|
build_flags =
|
||||||
${arduino_base.build_flags} -Wno-unused-variable -Wcast-align
|
${arduino_base.build_flags} -Wno-unused-variable -Wcast-align
|
||||||
-Isrc/platform/rp2xx0
|
-Isrc/platform/rp2xx0
|
||||||
|
-Isrc/platform/rp2xx0/hardware_rosc/include
|
||||||
|
-Isrc/platform/rp2xx0/pico_sleep/include
|
||||||
-D__PLAT_RP2040__
|
-D__PLAT_RP2040__
|
||||||
# -D _POSIX_THREADS
|
# -D _POSIX_THREADS
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[stm32_base]
|
[stm32_base]
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform = ststm32
|
platform = ststm32
|
||||||
platform_packages = platformio/framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32.git#361a7fdb67e2a7104e99b4f42a802469eef8b129
|
platform_packages = platformio/framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32.git#ea74156acd823b6d14739f389e6cdc648f8ee36e
|
||||||
|
|
||||||
build_type = release
|
build_type = release
|
||||||
|
|
||||||
@@ -33,5 +33,5 @@ lib_deps =
|
|||||||
https://github.com/caveman99/Crypto.git#f61ae26a53f7a2d0ba5511625b8bf8eff3a35d5e
|
https://github.com/caveman99/Crypto.git#f61ae26a53f7a2d0ba5511625b8bf8eff3a35d5e
|
||||||
|
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
https://github.com/mathertel/OneButton@~2.6.1
|
mathertel/OneButton@~2.6.1
|
||||||
Wire
|
Wire
|
||||||
48
bin/build-userprefs-json.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
|
||||||
|
def get_macros_from_header(header_file):
|
||||||
|
# Run clang to preprocess the header file and capture the output
|
||||||
|
result = subprocess.run(['clang', '-E', '-dM', header_file], capture_output=True, text=True)
|
||||||
|
if result.returncode != 0:
|
||||||
|
raise RuntimeError(f"Clang preprocessing failed: {result.stderr}")
|
||||||
|
|
||||||
|
# Extract macros from the output
|
||||||
|
macros = {}
|
||||||
|
macro_pattern = re.compile(r'#define\s+(\w+)\s+(.*)')
|
||||||
|
for line in result.stdout.splitlines():
|
||||||
|
match = macro_pattern.match(line)
|
||||||
|
if match and 'USERPREFS_' in line and '_USERPREFS_' not in line:
|
||||||
|
macros[match.group(1)] = match.group(2)
|
||||||
|
|
||||||
|
return macros
|
||||||
|
|
||||||
|
def write_macros_to_json(macros, output_file):
|
||||||
|
with open(output_file, 'w') as f:
|
||||||
|
json.dump(macros, f, indent=4)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
header_file = 'userPrefs.h'
|
||||||
|
output_file = 'userPrefs.json'
|
||||||
|
# Uncomment all macros in the header file
|
||||||
|
with open(header_file, 'r') as file:
|
||||||
|
lines = file.readlines()
|
||||||
|
|
||||||
|
uncommented_lines = []
|
||||||
|
for line in lines:
|
||||||
|
stripped_line = line.strip().replace('/*', '').replace('*/', '')
|
||||||
|
if stripped_line.startswith('//') and 'USERPREFS_' in stripped_line:
|
||||||
|
# Replace "//"
|
||||||
|
stripped_line = stripped_line.replace('//', '')
|
||||||
|
uncommented_lines.append(stripped_line + '\n')
|
||||||
|
|
||||||
|
with open(header_file, 'w') as file:
|
||||||
|
for line in uncommented_lines:
|
||||||
|
file.write(line)
|
||||||
|
macros = get_macros_from_header(header_file)
|
||||||
|
write_macros_to_json(macros, output_file)
|
||||||
|
print(f"Macros have been written to {output_file}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -1 +1 @@
|
|||||||
cd protobufs && ..\nanopb-0.4.8\generator-bin\protoc.exe --experimental_allow_proto3_optional "--nanopb_out=-S.cpp -v:..\src\mesh\generated" -I=..\protobufs\ ..\protobufs\meshtastic\*.proto
|
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
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
echo "This script requires https://jpa.kapsi.fi/nanopb/download/ version 0.4.8 to be located in the"
|
echo "This script requires https://jpa.kapsi.fi/nanopb/download/ version 0.4.9 to be located in the"
|
||||||
echo "firmware root directory if the following step fails, you should download the correct"
|
echo "firmware root directory if the following step fails, you should download the correct"
|
||||||
echo "prebuilt binaries for your computer into nanopb-0.4.8"
|
echo "prebuilt binaries for your computer into nanopb-0.4.9"
|
||||||
|
|
||||||
# the nanopb tool seems to require that the .options file be in the current directory!
|
# the nanopb tool seems to require that the .options file be in the current directory!
|
||||||
cd protobufs
|
cd protobufs
|
||||||
../nanopb-0.4.8/generator-bin/protoc --experimental_allow_proto3_optional "--nanopb_out=-S.cpp -v:../src/mesh/generated/" -I=../protobufs meshtastic/*.proto
|
../nanopb-0.4.9/generator-bin/protoc --experimental_allow_proto3_optional "--nanopb_out=-S.cpp -v:../src/mesh/generated/" -I=../protobufs meshtastic/*.proto
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
{
|
|
||||||
"build": {
|
|
||||||
"arduino": {
|
|
||||||
"ldscript": "nrf52840_s140_v6.ld"
|
|
||||||
},
|
|
||||||
"core": "nRF5",
|
|
||||||
"cpu": "cortex-m4",
|
|
||||||
"extra_flags": "-DARDUINO_NRF52840_LORA_RELAY_V1 -DNRF52840_XXAA",
|
|
||||||
"f_cpu": "64000000L",
|
|
||||||
"hwids": [["0x239A", "0x4404"]],
|
|
||||||
"usb_product": "LORA_RELAY",
|
|
||||||
"mcu": "nrf52840",
|
|
||||||
"variant": "lora_relay_v1",
|
|
||||||
"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": "Meshtastic Lora Relay V1 (Adafruit BSP)",
|
|
||||||
"upload": {
|
|
||||||
"maximum_ram_size": 248832,
|
|
||||||
"maximum_size": 815104,
|
|
||||||
"require_upload_port": true,
|
|
||||||
"speed": 115200,
|
|
||||||
"protocol": "jlink",
|
|
||||||
"protocols": ["jlink", "nrfjprog", "stlink"]
|
|
||||||
},
|
|
||||||
"url": "https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay",
|
|
||||||
"vendor": "BigCorvus"
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
{
|
|
||||||
"build": {
|
|
||||||
"arduino": {
|
|
||||||
"ldscript": "nrf52840_s140_v6.ld"
|
|
||||||
},
|
|
||||||
"core": "nRF5",
|
|
||||||
"cpu": "cortex-m4",
|
|
||||||
"extra_flags": "-DARDUINO_NRF52840_LORA_RELAY_V2 -DNRF52840_XXAA",
|
|
||||||
"f_cpu": "64000000L",
|
|
||||||
"hwids": [["0x239A", "0x4406"]],
|
|
||||||
"usb_product": "LORA_RELAY",
|
|
||||||
"mcu": "nrf52840",
|
|
||||||
"variant": "lora_relay_v2",
|
|
||||||
"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": "Meshtastic Lora Relay V1 (Adafruit BSP)",
|
|
||||||
"upload": {
|
|
||||||
"maximum_ram_size": 248832,
|
|
||||||
"maximum_size": 815104,
|
|
||||||
"require_upload_port": true,
|
|
||||||
"speed": 115200,
|
|
||||||
"protocol": "jlink",
|
|
||||||
"protocols": ["jlink", "nrfjprog", "stlink"]
|
|
||||||
},
|
|
||||||
"url": "https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay",
|
|
||||||
"vendor": "BigCorvus"
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
{
|
|
||||||
"build": {
|
|
||||||
"arduino": {
|
|
||||||
"ldscript": "nrf52840_s113_v7.ld"
|
|
||||||
},
|
|
||||||
"core": "nRF5",
|
|
||||||
"cpu": "cortex-m4",
|
|
||||||
"extra_flags": "-DARDUINO_NRF52840_PCA10056 -DNRF52840_XXAA",
|
|
||||||
"f_cpu": "64000000L",
|
|
||||||
"hwids": [["0x239A", "0x4404"]],
|
|
||||||
"usb_product": "nrf52840dk",
|
|
||||||
"mcu": "nrf52840",
|
|
||||||
"variant": "pca10056-rc-clock",
|
|
||||||
"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": "A modified NRF52840-DK devboard (Adafruit BSP)",
|
|
||||||
"upload": {
|
|
||||||
"maximum_ram_size": 248832,
|
|
||||||
"maximum_size": 815104,
|
|
||||||
"require_upload_port": true,
|
|
||||||
"speed": 115200,
|
|
||||||
"protocol": "jlink",
|
|
||||||
"protocols": ["jlink", "nrfjprog", "stlink"]
|
|
||||||
},
|
|
||||||
"url": "https://meshtastic.org/",
|
|
||||||
"vendor": "Nordic Semi"
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
{
|
|
||||||
"build": {
|
|
||||||
"arduino": {
|
|
||||||
"ldscript": "nrf52840_s140_v6.ld"
|
|
||||||
},
|
|
||||||
"core": "nRF5",
|
|
||||||
"cpu": "cortex-m4",
|
|
||||||
"extra_flags": "-DARDUINO_NRF52840_PPR -DNRF52840_XXAA",
|
|
||||||
"f_cpu": "64000000L",
|
|
||||||
"hwids": [["0x239A", "0x4403"]],
|
|
||||||
"usb_product": "PPR",
|
|
||||||
"mcu": "nrf52840",
|
|
||||||
"variant": "ppr",
|
|
||||||
"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": "Meshtastic PPR (Adafruit BSP)",
|
|
||||||
"upload": {
|
|
||||||
"maximum_ram_size": 248832,
|
|
||||||
"maximum_size": 815104,
|
|
||||||
"require_upload_port": true,
|
|
||||||
"speed": 115200,
|
|
||||||
"protocol": "jlink",
|
|
||||||
"protocols": ["jlink", "nrfjprog", "stlink"]
|
|
||||||
},
|
|
||||||
"url": "https://meshtastic.org/",
|
|
||||||
"vendor": "Othernet"
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
{
|
|
||||||
"build": {
|
|
||||||
"arduino": {
|
|
||||||
"ldscript": "nrf52833_s113_v7.ld"
|
|
||||||
},
|
|
||||||
"core": "nRF5",
|
|
||||||
"cpu": "cortex-m4",
|
|
||||||
"extra_flags": "-DARDUINO_NRF52833_PPR -DNRF52833_XXAA",
|
|
||||||
"f_cpu": "64000000L",
|
|
||||||
"hwids": [["0x239A", "0x4406"]],
|
|
||||||
"usb_product": "PPR",
|
|
||||||
"mcu": "nrf52833",
|
|
||||||
"variant": "ppr",
|
|
||||||
"variants_dir": "variants",
|
|
||||||
"bsp": {
|
|
||||||
"name": "adafruit"
|
|
||||||
},
|
|
||||||
"softdevice": {
|
|
||||||
"sd_flags": "-DS113",
|
|
||||||
"sd_name": "s113",
|
|
||||||
"sd_version": "7.2.0",
|
|
||||||
"sd_fwid": "0x00b6"
|
|
||||||
},
|
|
||||||
"bootloader": {
|
|
||||||
"settings_addr": "0xFF000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"connectivity": ["bluetooth"],
|
|
||||||
"debug": {
|
|
||||||
"jlink_device": "nRF52833_xxAA",
|
|
||||||
"onboard_tools": ["jlink"],
|
|
||||||
"svd_path": "nrf52833.svd",
|
|
||||||
"openocd_target": "nrf52840-mdk-rs"
|
|
||||||
},
|
|
||||||
"frameworks": ["arduino"],
|
|
||||||
"name": "Meshtastic PPR1 (Adafruit BSP)",
|
|
||||||
"upload": {
|
|
||||||
"maximum_ram_size": 248832,
|
|
||||||
"maximum_size": 815104,
|
|
||||||
"require_upload_port": true,
|
|
||||||
"speed": 115200,
|
|
||||||
"protocol": "jlink",
|
|
||||||
"protocols": ["jlink", "nrfjprog", "stlink"]
|
|
||||||
},
|
|
||||||
"url": "https://meshtastic.org/",
|
|
||||||
"vendor": "Othernet"
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 845 B After Width: | Height: | Size: 594 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M9 11.75c-.69 0-1.25.56-1.25 1.25s.56 1.25 1.25 1.25 1.25-.56 1.25-1.25-.56-1.25-1.25-1.25zm6 0c-.69 0-1.25.56-1.25 1.25s.56 1.25 1.25 1.25 1.25-.56 1.25-1.25-.56-1.25-1.25-1.25zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8 0-.29.02-.58.05-.86 2.36-1.05 4.23-2.98 5.21-5.37C11.07 8.33 14.05 10 17.42 10c.78 0 1.53-.09 2.25-.26.21.71.33 1.47.33 2.26 0 4.41-3.59 8-8 8z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M9 11.75a1.25 1.25 0 1 0 0 2.5 1.25 1.25 0 0 0 0-2.5m6 0a1.25 1.25 0 1 0 0 2.5 1.25 1.25 0 0 0 0-2.5M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2m0 18c-4.41 0-8-3.59-8-8 0-.29.02-.58.05-.86 2.36-1.05 4.23-2.98 5.21-5.37a9.97 9.97 0 0 0 10.41 3.97c.21.71.33 1.47.33 2.26 0 4.41-3.59 8-8 8"/><path fill="none" d="M0 0h24v24H0z"/></svg>
|
||||||
|
Before Width: | Height: | Size: 550 B After Width: | Height: | Size: 445 B |
BIN
images/face.png
|
Before Width: | Height: | Size: 329 B After Width: | Height: | Size: 225 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M20.94 11c-.46-4.17-3.77-7.48-7.94-7.94V1h-2v2.06C6.83 3.52 3.52 6.83 3.06 11H1v2h2.06c.46 4.17 3.77 7.48 7.94 7.94V23h2v-2.06c4.17-.46 7.48-3.77 7.94-7.94H23v-2h-2.06zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M20.94 11A8.994 8.994 0 0 0 13 3.06V1h-2v2.06A8.994 8.994 0 0 0 3.06 11H1v2h2.06A8.994 8.994 0 0 0 11 20.94V23h2v-2.06A8.994 8.994 0 0 0 20.94 13H23v-2zM12 19c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7"/></svg>
|
||||||
|
Before Width: | Height: | Size: 365 B After Width: | Height: | Size: 348 B |
BIN
images/pin.png
|
Before Width: | Height: | Size: 288 B After Width: | Height: | Size: 203 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7m0 9.5a2.5 2.5 0 0 1 0-5 2.5 2.5 0 0 1 0 5"/><path fill="none" d="M0 0h24v24H0z"/></svg>
|
||||||
|
Before Width: | Height: | Size: 292 B After Width: | Height: | Size: 250 B |
@@ -1 +1 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM9 11H7V9h2v2zm4 0h-2V9h2v2zm4 0h-2V9h2v2z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2M9 11H7V9h2zm4 0h-2V9h2zm4 0h-2V9h2z"/><path fill="none" d="M0 0h24v24H0z"/></svg>
|
||||||
|
Before Width: | Height: | Size: 253 B After Width: | Height: | Size: 246 B |
@@ -17,11 +17,9 @@ default_envs = tbeam
|
|||||||
;default_envs = tlora-v2-1-1_6
|
;default_envs = tlora-v2-1-1_6
|
||||||
;default_envs = tlora-v2-1-1_6-tcxo
|
;default_envs = tlora-v2-1-1_6-tcxo
|
||||||
;default_envs = tlora-t3s3-v1
|
;default_envs = tlora-t3s3-v1
|
||||||
;default_envs = lora-relay-v1 # nrf board
|
|
||||||
;default_envs = t-echo
|
;default_envs = t-echo
|
||||||
;default_envs = canaryone
|
;default_envs = canaryone
|
||||||
;default_envs = nrf52840dk-geeksville
|
;default_envs = native
|
||||||
;default_envs = native # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here
|
|
||||||
;default_envs = nano-g1
|
;default_envs = nano-g1
|
||||||
;default_envs = pca10059_diy_eink
|
;default_envs = pca10059_diy_eink
|
||||||
;default_envs = meshtastic-diy-v1
|
;default_envs = meshtastic-diy-v1
|
||||||
@@ -29,6 +27,7 @@ default_envs = tbeam
|
|||||||
;default_envs = meshtastic-dr-dev
|
;default_envs = meshtastic-dr-dev
|
||||||
;default_envs = m5stack-coreink
|
;default_envs = m5stack-coreink
|
||||||
;default_envs = rak4631
|
;default_envs = rak4631
|
||||||
|
;default_envs = rak4631_eth_gw
|
||||||
;default_envs = rak2560
|
;default_envs = rak2560
|
||||||
;default_envs = rak10701
|
;default_envs = rak10701
|
||||||
;default_envs = wio-e5
|
;default_envs = wio-e5
|
||||||
@@ -82,7 +81,7 @@ build_flags = -Wno-missing-field-initializers
|
|||||||
-DRADIOLIB_EXCLUDE_LORAWAN=1
|
-DRADIOLIB_EXCLUDE_LORAWAN=1
|
||||||
-DMESHTASTIC_EXCLUDE_DROPZONE=1
|
-DMESHTASTIC_EXCLUDE_DROPZONE=1
|
||||||
-DMESHTASTIC_EXCLUDE_REMOTEHARDWARE=1
|
-DMESHTASTIC_EXCLUDE_REMOTEHARDWARE=1
|
||||||
-DBUILD_EPOCH=$UNIX_TIME
|
#-DBUILD_EPOCH=$UNIX_TIME
|
||||||
;-D OLED_PL
|
;-D OLED_PL
|
||||||
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
@@ -91,13 +90,13 @@ monitor_filters = direct
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
jgromes/RadioLib@~7.0.2
|
jgromes/RadioLib@~7.0.2
|
||||||
https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95 ; ESP8266_SSD1306
|
https://github.com/meshtastic/esp8266-oled-ssd1306.git#e16cee124fe26490cb14880c679321ad8ac89c95 ; ESP8266_SSD1306
|
||||||
https://github.com/mathertel/OneButton@~2.6.1 ; OneButton library for non-blocking button debounce
|
mathertel/OneButton@~2.6.1 ; OneButton library for non-blocking button debounce
|
||||||
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
||||||
https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4
|
https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4
|
||||||
https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0
|
https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0
|
||||||
nanopb/Nanopb@^0.4.8
|
nanopb/Nanopb@^0.4.9
|
||||||
erriez/ErriezCRC32@^1.0.1
|
erriez/ErriezCRC32@^1.0.1
|
||||||
|
|
||||||
; Used for the code analysis in PIO Home / Inspect
|
; Used for the code analysis in PIO Home / Inspect
|
||||||
check_tool = cppcheck
|
check_tool = cppcheck
|
||||||
check_skip_packages = yes
|
check_skip_packages = yes
|
||||||
@@ -128,7 +127,7 @@ lib_deps =
|
|||||||
; (not included in native / portduino)
|
; (not included in native / portduino)
|
||||||
[environmental_base]
|
[environmental_base]
|
||||||
lib_deps =
|
lib_deps =
|
||||||
adafruit/Adafruit BusIO@^1.15.0
|
adafruit/Adafruit BusIO@^1.16.1
|
||||||
adafruit/Adafruit Unified Sensor@^1.1.11
|
adafruit/Adafruit Unified Sensor@^1.1.11
|
||||||
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
|
||||||
@@ -141,9 +140,9 @@ lib_deps =
|
|||||||
adafruit/Adafruit SHTC3 Library@^1.0.0
|
adafruit/Adafruit SHTC3 Library@^1.0.0
|
||||||
adafruit/Adafruit LPS2X@^2.0.4
|
adafruit/Adafruit LPS2X@^2.0.4
|
||||||
adafruit/Adafruit SHT31 Library@^2.2.2
|
adafruit/Adafruit SHT31 Library@^2.2.2
|
||||||
adafruit/Adafruit PM25 AQI Sensor@^1.0.6
|
adafruit/Adafruit PM25 AQI Sensor@^1.1.1
|
||||||
adafruit/Adafruit MPU6050@^2.2.4
|
adafruit/Adafruit MPU6050@^2.2.4
|
||||||
adafruit/Adafruit LIS3DH@^1.2.4
|
adafruit/Adafruit LIS3DH@^1.3.0
|
||||||
adafruit/Adafruit AHTX0@^2.0.5
|
adafruit/Adafruit AHTX0@^2.0.5
|
||||||
adafruit/Adafruit LSM6DS@^4.7.2
|
adafruit/Adafruit LSM6DS@^4.7.2
|
||||||
adafruit/Adafruit VEML7700 Library@^2.1.6
|
adafruit/Adafruit VEML7700 Library@^2.1.6
|
||||||
@@ -154,6 +153,8 @@ lib_deps =
|
|||||||
ClosedCube OPT3001@^1.1.2
|
ClosedCube OPT3001@^1.1.2
|
||||||
emotibit/EmotiBit MLX90632@^1.0.8
|
emotibit/EmotiBit MLX90632@^1.0.8
|
||||||
dfrobot/DFRobot_RTU@^1.0.3
|
dfrobot/DFRobot_RTU@^1.0.3
|
||||||
|
sparkfun/SparkFun MAX3010x Pulse and Proximity Sensor Library@^1.1.2
|
||||||
|
adafruit/Adafruit MLX90614 Library@^2.1.5
|
||||||
|
|
||||||
https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502
|
https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.7.2502
|
||||||
boschsensortec/BME68x Sensor Library@^1.1.40407
|
boschsensortec/BME68x Sensor Library@^1.1.40407
|
||||||
@@ -161,5 +162,5 @@ lib_deps =
|
|||||||
lewisxhe/SensorLib@0.2.0
|
lewisxhe/SensorLib@0.2.0
|
||||||
mprograms/QMC5883LCompass@^1.2.0
|
mprograms/QMC5883LCompass@^1.2.0
|
||||||
|
|
||||||
https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee
|
https://github.com/meshtastic/DFRobot_LarkWeatherStation#4de3a9cadef0f6a5220a8a906cf9775b02b0040d
|
||||||
https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1
|
https://github.com/gjelsoe/STK8xxx-Accelerometer.git#v0.1.1
|
||||||
|
|||||||
@@ -42,18 +42,18 @@ class AmbientLightingThread : public concurrency::OSThread
|
|||||||
#ifdef HAS_NCP5623
|
#ifdef HAS_NCP5623
|
||||||
_type = type;
|
_type = type;
|
||||||
if (_type == ScanI2C::DeviceType::NONE) {
|
if (_type == ScanI2C::DeviceType::NONE) {
|
||||||
LOG_DEBUG("AmbientLightingThread disabling due to no RGB leds found on I2C bus\n");
|
LOG_DEBUG("AmbientLightingThread disabling due to no RGB leds found on I2C bus");
|
||||||
disable();
|
disable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
|
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
|
||||||
if (!moduleConfig.ambient_lighting.led_state) {
|
if (!moduleConfig.ambient_lighting.led_state) {
|
||||||
LOG_DEBUG("AmbientLightingThread disabling due to moduleConfig.ambient_lighting.led_state OFF\n");
|
LOG_DEBUG("AmbientLightingThread disabling due to moduleConfig.ambient_lighting.led_state OFF");
|
||||||
disable();
|
disable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG_DEBUG("AmbientLightingThread initializing\n");
|
LOG_DEBUG("AmbientLightingThread initializing");
|
||||||
#ifdef HAS_NCP5623
|
#ifdef HAS_NCP5623
|
||||||
if (_type == ScanI2C::NCP5623) {
|
if (_type == ScanI2C::NCP5623) {
|
||||||
rgb.begin();
|
rgb.begin();
|
||||||
@@ -106,27 +106,27 @@ class AmbientLightingThread : public concurrency::OSThread
|
|||||||
rgb.setRed(0);
|
rgb.setRed(0);
|
||||||
rgb.setGreen(0);
|
rgb.setGreen(0);
|
||||||
rgb.setBlue(0);
|
rgb.setBlue(0);
|
||||||
LOG_INFO("Turn Off NCP5623 Ambient lighting.\n");
|
LOG_INFO("Turn Off NCP5623 Ambient lighting.");
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_NEOPIXEL
|
#ifdef HAS_NEOPIXEL
|
||||||
pixels.clear();
|
pixels.clear();
|
||||||
pixels.show();
|
pixels.show();
|
||||||
LOG_INFO("Turn Off NeoPixel Ambient lighting.\n");
|
LOG_INFO("Turn Off NeoPixel Ambient lighting.");
|
||||||
#endif
|
#endif
|
||||||
#ifdef RGBLED_CA
|
#ifdef RGBLED_CA
|
||||||
analogWrite(RGBLED_RED, 255 - 0);
|
analogWrite(RGBLED_RED, 255 - 0);
|
||||||
analogWrite(RGBLED_GREEN, 255 - 0);
|
analogWrite(RGBLED_GREEN, 255 - 0);
|
||||||
analogWrite(RGBLED_BLUE, 255 - 0);
|
analogWrite(RGBLED_BLUE, 255 - 0);
|
||||||
LOG_INFO("Turn Off Ambient lighting RGB Common Anode.\n");
|
LOG_INFO("Turn Off Ambient lighting RGB Common Anode.");
|
||||||
#elif defined(RGBLED_RED)
|
#elif defined(RGBLED_RED)
|
||||||
analogWrite(RGBLED_RED, 0);
|
analogWrite(RGBLED_RED, 0);
|
||||||
analogWrite(RGBLED_GREEN, 0);
|
analogWrite(RGBLED_GREEN, 0);
|
||||||
analogWrite(RGBLED_BLUE, 0);
|
analogWrite(RGBLED_BLUE, 0);
|
||||||
LOG_INFO("Turn Off Ambient lighting RGB Common Cathode.\n");
|
LOG_INFO("Turn Off Ambient lighting RGB Common Cathode.");
|
||||||
#endif
|
#endif
|
||||||
#ifdef UNPHONE
|
#ifdef UNPHONE
|
||||||
unphone.rgb(0, 0, 0);
|
unphone.rgb(0, 0, 0);
|
||||||
LOG_INFO("Turn Off unPhone Ambient lighting.\n");
|
LOG_INFO("Turn Off unPhone Ambient lighting.");
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -138,7 +138,7 @@ class AmbientLightingThread : public concurrency::OSThread
|
|||||||
rgb.setRed(moduleConfig.ambient_lighting.red);
|
rgb.setRed(moduleConfig.ambient_lighting.red);
|
||||||
rgb.setGreen(moduleConfig.ambient_lighting.green);
|
rgb.setGreen(moduleConfig.ambient_lighting.green);
|
||||||
rgb.setBlue(moduleConfig.ambient_lighting.blue);
|
rgb.setBlue(moduleConfig.ambient_lighting.blue);
|
||||||
LOG_DEBUG("Initializing NCP5623 Ambient lighting w/ current=%d, red=%d, green=%d, blue=%d\n",
|
LOG_DEBUG("Initializing NCP5623 Ambient lighting w/ current=%d, red=%d, green=%d, blue=%d",
|
||||||
moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
|
moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
|
||||||
moduleConfig.ambient_lighting.blue);
|
moduleConfig.ambient_lighting.blue);
|
||||||
#endif
|
#endif
|
||||||
@@ -158,7 +158,7 @@ class AmbientLightingThread : public concurrency::OSThread
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
pixels.show();
|
pixels.show();
|
||||||
LOG_DEBUG("Initializing NeoPixel Ambient lighting w/ brightness(current)=%d, red=%d, green=%d, blue=%d\n",
|
LOG_DEBUG("Initializing NeoPixel Ambient lighting w/ brightness(current)=%d, red=%d, green=%d, blue=%d",
|
||||||
moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
|
moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
|
||||||
moduleConfig.ambient_lighting.blue);
|
moduleConfig.ambient_lighting.blue);
|
||||||
#endif
|
#endif
|
||||||
@@ -166,18 +166,18 @@ class AmbientLightingThread : public concurrency::OSThread
|
|||||||
analogWrite(RGBLED_RED, 255 - moduleConfig.ambient_lighting.red);
|
analogWrite(RGBLED_RED, 255 - moduleConfig.ambient_lighting.red);
|
||||||
analogWrite(RGBLED_GREEN, 255 - moduleConfig.ambient_lighting.green);
|
analogWrite(RGBLED_GREEN, 255 - moduleConfig.ambient_lighting.green);
|
||||||
analogWrite(RGBLED_BLUE, 255 - moduleConfig.ambient_lighting.blue);
|
analogWrite(RGBLED_BLUE, 255 - moduleConfig.ambient_lighting.blue);
|
||||||
LOG_DEBUG("Initializing Ambient lighting RGB Common Anode w/ red=%d, green=%d, blue=%d\n",
|
LOG_DEBUG("Initializing Ambient lighting RGB Common Anode w/ red=%d, green=%d, blue=%d",
|
||||||
moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
|
moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
|
||||||
#elif defined(RGBLED_RED)
|
#elif defined(RGBLED_RED)
|
||||||
analogWrite(RGBLED_RED, moduleConfig.ambient_lighting.red);
|
analogWrite(RGBLED_RED, moduleConfig.ambient_lighting.red);
|
||||||
analogWrite(RGBLED_GREEN, moduleConfig.ambient_lighting.green);
|
analogWrite(RGBLED_GREEN, moduleConfig.ambient_lighting.green);
|
||||||
analogWrite(RGBLED_BLUE, moduleConfig.ambient_lighting.blue);
|
analogWrite(RGBLED_BLUE, moduleConfig.ambient_lighting.blue);
|
||||||
LOG_DEBUG("Initializing Ambient lighting RGB Common Cathode w/ red=%d, green=%d, blue=%d\n",
|
LOG_DEBUG("Initializing Ambient lighting RGB Common Cathode w/ red=%d, green=%d, blue=%d",
|
||||||
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 UNPHONE
|
#ifdef UNPHONE
|
||||||
unphone.rgb(moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
|
unphone.rgb(moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
|
||||||
LOG_DEBUG("Initializing unPhone Ambient lighting w/ red=%d, green=%d, blue=%d\n", moduleConfig.ambient_lighting.red,
|
LOG_DEBUG("Initializing unPhone Ambient lighting w/ red=%d, green=%d, blue=%d", moduleConfig.ambient_lighting.red,
|
||||||
moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
|
moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ ButtonThread::ButtonThread() : OSThread("Button")
|
|||||||
#if defined(ARCH_PORTDUINO)
|
#if defined(ARCH_PORTDUINO)
|
||||||
if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) {
|
if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) {
|
||||||
this->userButton = OneButton(settingsMap[user], true, true);
|
this->userButton = OneButton(settingsMap[user], true, true);
|
||||||
LOG_DEBUG("Using GPIO%02d for button\n", settingsMap[user]);
|
LOG_DEBUG("Using GPIO%02d for button", settingsMap[user]);
|
||||||
}
|
}
|
||||||
#elif defined(BUTTON_PIN)
|
#elif defined(BUTTON_PIN)
|
||||||
int pin = config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN; // Resolved button pin
|
int pin = config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN; // Resolved button pin
|
||||||
@@ -47,7 +47,7 @@ ButtonThread::ButtonThread() : OSThread("Button")
|
|||||||
#else
|
#else
|
||||||
this->userButton = OneButton(pin, true, true);
|
this->userButton = OneButton(pin, true, true);
|
||||||
#endif
|
#endif
|
||||||
LOG_DEBUG("Using GPIO%02d for button\n", pin);
|
LOG_DEBUG("Using GPIO%02d for button", pin);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef INPUT_PULLUP_SENSE
|
#ifdef INPUT_PULLUP_SENSE
|
||||||
@@ -123,7 +123,7 @@ int32_t ButtonThread::runOnce()
|
|||||||
if (btnEvent != BUTTON_EVENT_NONE) {
|
if (btnEvent != BUTTON_EVENT_NONE) {
|
||||||
switch (btnEvent) {
|
switch (btnEvent) {
|
||||||
case BUTTON_EVENT_PRESSED: {
|
case BUTTON_EVENT_PRESSED: {
|
||||||
LOG_BUTTON("press!\n");
|
LOG_BUTTON("press!");
|
||||||
// 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();
|
||||||
@@ -148,7 +148,7 @@ int32_t ButtonThread::runOnce()
|
|||||||
}
|
}
|
||||||
|
|
||||||
case BUTTON_EVENT_DOUBLE_PRESSED: {
|
case BUTTON_EVENT_DOUBLE_PRESSED: {
|
||||||
LOG_BUTTON("Double press!\n");
|
LOG_BUTTON("Double press!");
|
||||||
service->refreshLocalMeshNode();
|
service->refreshLocalMeshNode();
|
||||||
auto sentPosition = service->trySendPosition(NODENUM_BROADCAST, true);
|
auto sentPosition = service->trySendPosition(NODENUM_BROADCAST, true);
|
||||||
if (screen) {
|
if (screen) {
|
||||||
@@ -162,7 +162,7 @@ int32_t ButtonThread::runOnce()
|
|||||||
}
|
}
|
||||||
|
|
||||||
case BUTTON_EVENT_MULTI_PRESSED: {
|
case BUTTON_EVENT_MULTI_PRESSED: {
|
||||||
LOG_BUTTON("Mulitipress! %hux\n", multipressClickCount);
|
LOG_BUTTON("Mulitipress! %hux", multipressClickCount);
|
||||||
switch (multipressClickCount) {
|
switch (multipressClickCount) {
|
||||||
#if HAS_GPS
|
#if HAS_GPS
|
||||||
// 3 clicks: toggle GPS
|
// 3 clicks: toggle GPS
|
||||||
@@ -189,7 +189,7 @@ int32_t ButtonThread::runOnce()
|
|||||||
} // end multipress event
|
} // end multipress event
|
||||||
|
|
||||||
case BUTTON_EVENT_LONG_PRESSED: {
|
case BUTTON_EVENT_LONG_PRESSED: {
|
||||||
LOG_BUTTON("Long press!\n");
|
LOG_BUTTON("Long press!");
|
||||||
powerFSM.trigger(EVENT_PRESS);
|
powerFSM.trigger(EVENT_PRESS);
|
||||||
if (screen) {
|
if (screen) {
|
||||||
screen->startAlert("Shutting down...");
|
screen->startAlert("Shutting down...");
|
||||||
@@ -201,7 +201,7 @@ int32_t ButtonThread::runOnce()
|
|||||||
// Do actual shutdown when button released, otherwise the button release
|
// Do actual shutdown when button released, otherwise the button release
|
||||||
// may wake the board immediatedly.
|
// may wake the board immediatedly.
|
||||||
case BUTTON_EVENT_LONG_RELEASED: {
|
case BUTTON_EVENT_LONG_RELEASED: {
|
||||||
LOG_INFO("Shutdown from long press\n");
|
LOG_INFO("Shutdown from long press");
|
||||||
playShutdownMelody();
|
playShutdownMelody();
|
||||||
delay(3000);
|
delay(3000);
|
||||||
power->shutdown();
|
power->shutdown();
|
||||||
@@ -210,7 +210,7 @@ int32_t ButtonThread::runOnce()
|
|||||||
|
|
||||||
#ifdef BUTTON_PIN_TOUCH
|
#ifdef BUTTON_PIN_TOUCH
|
||||||
case BUTTON_EVENT_TOUCH_LONG_PRESSED: {
|
case BUTTON_EVENT_TOUCH_LONG_PRESSED: {
|
||||||
LOG_BUTTON("Touch press!\n");
|
LOG_BUTTON("Touch press!");
|
||||||
if (screen) {
|
if (screen) {
|
||||||
// Wake if asleep
|
// Wake if asleep
|
||||||
if (powerFSM.getState() == &stateDARK)
|
if (powerFSM.getState() == &stateDARK)
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ bool lfs_assert_failed =
|
|||||||
|
|
||||||
extern "C" void lfs_assert(const char *reason)
|
extern "C" void lfs_assert(const char *reason)
|
||||||
{
|
{
|
||||||
LOG_ERROR("LFS assert: %s\n", reason);
|
LOG_ERROR("LFS assert: %s", reason);
|
||||||
lfs_assert_failed = true;
|
lfs_assert_failed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,19 +75,19 @@ bool copyFile(const char *from, const char *to)
|
|||||||
r = OSFS::getFile(from, cbuffer);
|
r = OSFS::getFile(from, cbuffer);
|
||||||
|
|
||||||
if (r == notfound) {
|
if (r == notfound) {
|
||||||
LOG_ERROR("Failed to open source file %s\n", from);
|
LOG_ERROR("Failed to open source file %s", from);
|
||||||
return false;
|
return false;
|
||||||
} else if (r == noerr) {
|
} else if (r == noerr) {
|
||||||
r = OSFS::newFile(to, cbuffer, true);
|
r = OSFS::newFile(to, cbuffer, true);
|
||||||
if (r == noerr) {
|
if (r == noerr) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("OSFS Error %d\n", r);
|
LOG_ERROR("OSFS Error %d", r);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("OSFS Error %d\n", r);
|
LOG_ERROR("OSFS Error %d", r);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -97,13 +97,13 @@ bool copyFile(const char *from, const char *to)
|
|||||||
|
|
||||||
File f1 = FSCom.open(from, FILE_O_READ);
|
File f1 = FSCom.open(from, FILE_O_READ);
|
||||||
if (!f1) {
|
if (!f1) {
|
||||||
LOG_ERROR("Failed to open source file %s\n", from);
|
LOG_ERROR("Failed to open source file %s", from);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
File f2 = FSCom.open(to, FILE_O_WRITE);
|
File f2 = FSCom.open(to, FILE_O_WRITE);
|
||||||
if (!f2) {
|
if (!f2) {
|
||||||
LOG_ERROR("Failed to open destination file %s\n", to);
|
LOG_ERROR("Failed to open destination file %s", to);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +231,7 @@ void listDir(const char *dirname, uint8_t levels, bool del)
|
|||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
listDir(file.path(), levels - 1, del);
|
listDir(file.path(), levels - 1, del);
|
||||||
if (del) {
|
if (del) {
|
||||||
LOG_DEBUG("Removing %s\n", file.path());
|
LOG_DEBUG("Removing %s", file.path());
|
||||||
strncpy(buffer, file.path(), sizeof(buffer));
|
strncpy(buffer, file.path(), sizeof(buffer));
|
||||||
file.close();
|
file.close();
|
||||||
FSCom.rmdir(buffer);
|
FSCom.rmdir(buffer);
|
||||||
@@ -241,7 +241,7 @@ void listDir(const char *dirname, uint8_t levels, bool del)
|
|||||||
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
|
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
|
||||||
listDir(file.name(), levels - 1, del);
|
listDir(file.name(), levels - 1, del);
|
||||||
if (del) {
|
if (del) {
|
||||||
LOG_DEBUG("Removing %s\n", file.name());
|
LOG_DEBUG("Removing %s", file.name());
|
||||||
strncpy(buffer, file.name(), sizeof(buffer));
|
strncpy(buffer, file.name(), sizeof(buffer));
|
||||||
file.close();
|
file.close();
|
||||||
FSCom.rmdir(buffer);
|
FSCom.rmdir(buffer);
|
||||||
@@ -249,7 +249,7 @@ void listDir(const char *dirname, uint8_t levels, bool del)
|
|||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
LOG_DEBUG(" %s (directory)\n", file.name());
|
LOG_DEBUG(" %s (directory)", file.name());
|
||||||
listDir(file.name(), levels - 1, del);
|
listDir(file.name(), levels - 1, del);
|
||||||
file.close();
|
file.close();
|
||||||
#endif
|
#endif
|
||||||
@@ -257,26 +257,26 @@ void listDir(const char *dirname, uint8_t levels, bool del)
|
|||||||
} else {
|
} else {
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
if (del) {
|
if (del) {
|
||||||
LOG_DEBUG("Deleting %s\n", file.path());
|
LOG_DEBUG("Deleting %s", file.path());
|
||||||
strncpy(buffer, file.path(), sizeof(buffer));
|
strncpy(buffer, file.path(), sizeof(buffer));
|
||||||
file.close();
|
file.close();
|
||||||
FSCom.remove(buffer);
|
FSCom.remove(buffer);
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG(" %s (%i Bytes)\n", file.path(), file.size());
|
LOG_DEBUG(" %s (%i Bytes)", file.path(), file.size());
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
|
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
|
||||||
if (del) {
|
if (del) {
|
||||||
LOG_DEBUG("Deleting %s\n", file.name());
|
LOG_DEBUG("Deleting %s", file.name());
|
||||||
strncpy(buffer, file.name(), sizeof(buffer));
|
strncpy(buffer, file.name(), sizeof(buffer));
|
||||||
file.close();
|
file.close();
|
||||||
FSCom.remove(buffer);
|
FSCom.remove(buffer);
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG(" %s (%i Bytes)\n", file.name(), file.size());
|
LOG_DEBUG(" %s (%i Bytes)", file.name(), file.size());
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
LOG_DEBUG(" %s (%i Bytes)\n", file.name(), file.size());
|
LOG_DEBUG(" %s (%i Bytes)", file.name(), file.size());
|
||||||
file.close();
|
file.close();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -284,7 +284,7 @@ void listDir(const char *dirname, uint8_t levels, bool del)
|
|||||||
}
|
}
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
if (del) {
|
if (del) {
|
||||||
LOG_DEBUG("Removing %s\n", root.path());
|
LOG_DEBUG("Removing %s", root.path());
|
||||||
strncpy(buffer, root.path(), sizeof(buffer));
|
strncpy(buffer, root.path(), sizeof(buffer));
|
||||||
root.close();
|
root.close();
|
||||||
FSCom.rmdir(buffer);
|
FSCom.rmdir(buffer);
|
||||||
@@ -293,7 +293,7 @@ void listDir(const char *dirname, uint8_t levels, bool del)
|
|||||||
}
|
}
|
||||||
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
|
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
|
||||||
if (del) {
|
if (del) {
|
||||||
LOG_DEBUG("Removing %s\n", root.name());
|
LOG_DEBUG("Removing %s", root.name());
|
||||||
strncpy(buffer, root.name(), sizeof(buffer));
|
strncpy(buffer, root.name(), sizeof(buffer));
|
||||||
root.close();
|
root.close();
|
||||||
FSCom.rmdir(buffer);
|
FSCom.rmdir(buffer);
|
||||||
@@ -329,13 +329,13 @@ void fsInit()
|
|||||||
{
|
{
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
if (!FSBegin()) {
|
if (!FSBegin()) {
|
||||||
LOG_ERROR("Filesystem mount Failed.\n");
|
LOG_ERROR("Filesystem mount Failed.");
|
||||||
// assert(0); This auto-formats the partition, so no need to fail here.
|
// assert(0); This auto-formats the partition, so no need to fail here.
|
||||||
}
|
}
|
||||||
#if defined(ARCH_ESP32)
|
#if defined(ARCH_ESP32)
|
||||||
LOG_DEBUG("Filesystem files (%d/%d Bytes):\n", FSCom.usedBytes(), FSCom.totalBytes());
|
LOG_DEBUG("Filesystem files (%d/%d Bytes):", FSCom.usedBytes(), FSCom.totalBytes());
|
||||||
#else
|
#else
|
||||||
LOG_DEBUG("Filesystem files:\n");
|
LOG_DEBUG("Filesystem files:");
|
||||||
#endif
|
#endif
|
||||||
listDir("/", 10);
|
listDir("/", 10);
|
||||||
#endif
|
#endif
|
||||||
@@ -350,28 +350,28 @@ void setupSDCard()
|
|||||||
SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
|
SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
|
||||||
|
|
||||||
if (!SD.begin(SDCARD_CS, SDHandler)) {
|
if (!SD.begin(SDCARD_CS, SDHandler)) {
|
||||||
LOG_DEBUG("No SD_MMC card detected\n");
|
LOG_DEBUG("No SD_MMC card detected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint8_t cardType = SD.cardType();
|
uint8_t cardType = SD.cardType();
|
||||||
if (cardType == CARD_NONE) {
|
if (cardType == CARD_NONE) {
|
||||||
LOG_DEBUG("No SD_MMC card attached\n");
|
LOG_DEBUG("No SD_MMC card attached");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG_DEBUG("SD_MMC Card Type: ");
|
LOG_DEBUG("SD_MMC Card Type: ");
|
||||||
if (cardType == CARD_MMC) {
|
if (cardType == CARD_MMC) {
|
||||||
LOG_DEBUG("MMC\n");
|
LOG_DEBUG("MMC");
|
||||||
} else if (cardType == CARD_SD) {
|
} else if (cardType == CARD_SD) {
|
||||||
LOG_DEBUG("SDSC\n");
|
LOG_DEBUG("SDSC");
|
||||||
} else if (cardType == CARD_SDHC) {
|
} else if (cardType == CARD_SDHC) {
|
||||||
LOG_DEBUG("SDHC\n");
|
LOG_DEBUG("SDHC");
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("UNKNOWN\n");
|
LOG_DEBUG("UNKNOWN");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
|
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
|
||||||
LOG_DEBUG("SD Card Size: %lu MB\n", (uint32_t)cardSize);
|
LOG_DEBUG("SD Card Size: %lu MB", (uint32_t)cardSize);
|
||||||
LOG_DEBUG("Total space: %lu MB\n", (uint32_t)(SD.totalBytes() / (1024 * 1024)));
|
LOG_DEBUG("Total space: %lu MB", (uint32_t)(SD.totalBytes() / (1024 * 1024)));
|
||||||
LOG_DEBUG("Used space: %lu MB\n", (uint32_t)(SD.usedBytes() / (1024 * 1024)));
|
LOG_DEBUG("Used space: %lu MB", (uint32_t)(SD.usedBytes() / (1024 * 1024)));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@ class GPSStatus : public Status
|
|||||||
{
|
{
|
||||||
if (config.position.fixed_position) {
|
if (config.position.fixed_position) {
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
LOG_WARN("Using fixed latitude\n");
|
LOG_WARN("Using fixed latitude");
|
||||||
#endif
|
#endif
|
||||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
||||||
return node->position.latitude_i;
|
return node->position.latitude_i;
|
||||||
@@ -64,7 +64,7 @@ class GPSStatus : public Status
|
|||||||
{
|
{
|
||||||
if (config.position.fixed_position) {
|
if (config.position.fixed_position) {
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
LOG_WARN("Using fixed longitude\n");
|
LOG_WARN("Using fixed longitude");
|
||||||
#endif
|
#endif
|
||||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
||||||
return node->position.longitude_i;
|
return node->position.longitude_i;
|
||||||
@@ -77,7 +77,7 @@ class GPSStatus : public Status
|
|||||||
{
|
{
|
||||||
if (config.position.fixed_position) {
|
if (config.position.fixed_position) {
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
LOG_WARN("Using fixed altitude\n");
|
LOG_WARN("Using fixed altitude");
|
||||||
#endif
|
#endif
|
||||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
||||||
return node->position.altitude;
|
return node->position.altitude;
|
||||||
@@ -95,7 +95,7 @@ class GPSStatus : public Status
|
|||||||
bool matches(const GPSStatus *newStatus) const
|
bool matches(const GPSStatus *newStatus) const
|
||||||
{
|
{
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
LOG_DEBUG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.timestamp, p.timestamp);
|
LOG_DEBUG("GPSStatus.match() new pos@%x to old pos@%x", newStatus->p.timestamp, p.timestamp);
|
||||||
#endif
|
#endif
|
||||||
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected ||
|
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected ||
|
||||||
newStatus->isPowerSaving != isPowerSaving || newStatus->p.latitude_i != p.latitude_i ||
|
newStatus->isPowerSaving != isPowerSaving || newStatus->p.latitude_i != p.latitude_i ||
|
||||||
@@ -112,7 +112,7 @@ class GPSStatus : public Status
|
|||||||
|
|
||||||
if (isDirty && p.timestamp && (newStatus->p.timestamp == p.timestamp)) {
|
if (isDirty && p.timestamp && (newStatus->p.timestamp == p.timestamp)) {
|
||||||
// We can NEVER be in two locations at the same time! (also PR #886)
|
// We can NEVER be in two locations at the same time! (also PR #886)
|
||||||
LOG_ERROR("BUG: Positional timestamp unchanged from prev solution\n");
|
LOG_ERROR("BUG: Positional timestamp unchanged from prev solution");
|
||||||
}
|
}
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
@@ -124,11 +124,11 @@ class GPSStatus : public Status
|
|||||||
if (isDirty) {
|
if (isDirty) {
|
||||||
if (hasLock) {
|
if (hasLock) {
|
||||||
// In debug logs, identify position by @timestamp:stage (stage 3 = notify)
|
// In debug logs, identify position by @timestamp:stage (stage 3 = notify)
|
||||||
LOG_DEBUG("New GPS pos@%x:3 lat=%f lon=%f alt=%d pdop=%.2f track=%.2f speed=%.2f sats=%d\n", p.timestamp,
|
LOG_DEBUG("New GPS pos@%x:3 lat=%f lon=%f alt=%d pdop=%.2f track=%.2f speed=%.2f sats=%d", p.timestamp,
|
||||||
p.latitude_i * 1e-7, p.longitude_i * 1e-7, p.altitude, p.PDOP * 1e-2, p.ground_track * 1e-5,
|
p.latitude_i * 1e-7, p.longitude_i * 1e-7, p.altitude, p.PDOP * 1e-2, p.ground_track * 1e-5,
|
||||||
p.ground_speed * 1e-2, p.sats_in_view);
|
p.ground_speed * 1e-2, p.sats_in_view);
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("No GPS lock\n");
|
LOG_DEBUG("No GPS lock");
|
||||||
}
|
}
|
||||||
onNewStatus.notifyObservers(this);
|
onNewStatus.notifyObservers(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ void GpioVirtPin::set(bool value)
|
|||||||
|
|
||||||
void GpioHwPin::set(bool value)
|
void GpioHwPin::set(bool value)
|
||||||
{
|
{
|
||||||
// if (num == 3) LOG_DEBUG("Setting pin %d to %d\n", num, value);
|
// if (num == 3) LOG_DEBUG("Setting pin %d to %d", num, value);
|
||||||
pinMode(num, OUTPUT);
|
pinMode(num, OUTPUT);
|
||||||
digitalWrite(num, value);
|
digitalWrite(num, value);
|
||||||
}
|
}
|
||||||
@@ -88,7 +88,7 @@ void GpioBinaryTransformer::update()
|
|||||||
newValue = (GpioVirtPin::PinState)(p1 && p2);
|
newValue = (GpioVirtPin::PinState)(p1 && p2);
|
||||||
break;
|
break;
|
||||||
case Or:
|
case Or:
|
||||||
// LOG_DEBUG("Doing GPIO OR\n");
|
// LOG_DEBUG("Doing GPIO OR");
|
||||||
newValue = (GpioVirtPin::PinState)(p1 || p2);
|
newValue = (GpioVirtPin::PinState)(p1 || p2);
|
||||||
break;
|
break;
|
||||||
case Xor:
|
case Xor:
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class NodeStatus : public Status
|
|||||||
numTotal = newStatus->getNumTotal();
|
numTotal = newStatus->getNumTotal();
|
||||||
}
|
}
|
||||||
if (isDirty || newStatus->forceUpdate) {
|
if (isDirty || newStatus->forceUpdate) {
|
||||||
LOG_DEBUG("Node status update: %d online, %d total\n", numOnline, numTotal);
|
LOG_DEBUG("Node status update: %d online, %d total", numOnline, numTotal);
|
||||||
onNewStatus.notifyObservers(this);
|
onNewStatus.notifyObservers(this);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(HAS_PMU) && \
|
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(HAS_PMU) && \
|
||||||
!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||||
if (hasINA()) {
|
if (hasINA()) {
|
||||||
LOG_DEBUG("Using INA on I2C addr 0x%x for device battery voltage\n", config.power.device_battery_ina_address);
|
LOG_DEBUG("Using INA on I2C addr 0x%x for device battery voltage", config.power.device_battery_ina_address);
|
||||||
return getINAVoltage();
|
return getINAVoltage();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -290,7 +290,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
last_read_value += (scaled - last_read_value) * 0.5; // Virtual LPF
|
last_read_value += (scaled - last_read_value) * 0.5; // Virtual LPF
|
||||||
}
|
}
|
||||||
|
|
||||||
// LOG_DEBUG("battery gpio %d raw val=%u scaled=%u filtered=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled), (uint32_t)
|
// LOG_DEBUG("battery gpio %d raw val=%u scaled=%u filtered=%u", BATTERY_PIN, raw, (uint32_t)(scaled), (uint32_t)
|
||||||
// (last_read_value));
|
// (last_read_value));
|
||||||
}
|
}
|
||||||
return last_read_value;
|
return last_read_value;
|
||||||
@@ -335,7 +335,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
raw += adc_buf;
|
raw += adc_buf;
|
||||||
raw_c++; // Count valid samples
|
raw_c++; // Count valid samples
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("An attempt to sample ADC2 failed\n");
|
LOG_DEBUG("An attempt to sample ADC2 failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,7 +495,7 @@ bool Power::analogInit()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BATTERY_PIN
|
#ifdef BATTERY_PIN
|
||||||
LOG_DEBUG("Using analog input %d for battery level\n", BATTERY_PIN);
|
LOG_DEBUG("Using analog input %d for battery level", BATTERY_PIN);
|
||||||
|
|
||||||
// disable any internal pullups
|
// disable any internal pullups
|
||||||
pinMode(BATTERY_PIN, INPUT);
|
pinMode(BATTERY_PIN, INPUT);
|
||||||
@@ -526,18 +526,18 @@ bool Power::analogInit()
|
|||||||
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_characs);
|
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_characs);
|
||||||
// show ADC characterization base
|
// show ADC characterization base
|
||||||
if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
|
if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
|
||||||
LOG_INFO("ADCmod: ADC characterization based on Two Point values stored in eFuse\n");
|
LOG_INFO("ADCmod: ADC characterization based on Two Point values stored in eFuse");
|
||||||
} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
|
} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
|
||||||
LOG_INFO("ADCmod: ADC characterization based on reference voltage stored in eFuse\n");
|
LOG_INFO("ADCmod: ADC characterization based on reference voltage stored in eFuse");
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_IDF_TARGET_ESP32S3
|
#ifdef CONFIG_IDF_TARGET_ESP32S3
|
||||||
// ESP32S3
|
// ESP32S3
|
||||||
else if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP_FIT) {
|
else if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP_FIT) {
|
||||||
LOG_INFO("ADCmod: ADC Characterization based on Two Point values and fitting curve coefficients stored in eFuse\n");
|
LOG_INFO("ADCmod: ADC Characterization based on Two Point values and fitting curve coefficients stored in eFuse");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
LOG_INFO("ADCmod: ADC characterization based on default reference voltage\n");
|
LOG_INFO("ADCmod: ADC characterization based on default reference voltage");
|
||||||
}
|
}
|
||||||
#endif // ARCH_ESP32
|
#endif // ARCH_ESP32
|
||||||
|
|
||||||
@@ -586,9 +586,9 @@ bool Power::setup()
|
|||||||
|
|
||||||
void Power::shutdown()
|
void Power::shutdown()
|
||||||
{
|
{
|
||||||
LOG_INFO("Shutting down\n");
|
LOG_INFO("Shutting down");
|
||||||
|
|
||||||
#if defined(ARCH_NRF52) || defined(ARCH_ESP32)
|
#if defined(ARCH_NRF52) || defined(ARCH_ESP32) || defined(ARCH_RP2040)
|
||||||
#ifdef PIN_LED1
|
#ifdef PIN_LED1
|
||||||
ledOff(PIN_LED1);
|
ledOff(PIN_LED1);
|
||||||
#endif
|
#endif
|
||||||
@@ -641,7 +641,7 @@ void Power::readPowerStatus()
|
|||||||
// changes.
|
// changes.
|
||||||
|
|
||||||
nrfx_power_usb_state_t nrf_usb_state = nrfx_power_usbstatus_get();
|
nrfx_power_usb_state_t nrf_usb_state = nrfx_power_usbstatus_get();
|
||||||
// LOG_DEBUG("NRF Power %d\n", nrf_usb_state);
|
// LOG_DEBUG("NRF Power %d", nrf_usb_state);
|
||||||
|
|
||||||
// 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)
|
||||||
@@ -654,22 +654,22 @@ void Power::readPowerStatus()
|
|||||||
|
|
||||||
// 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, isCharging, batteryVoltageMv, batteryChargePercent);
|
||||||
LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d\n", powerStatus2.getHasUSB(),
|
LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d", powerStatus2.getHasUSB(), powerStatus2.getIsCharging(),
|
||||||
powerStatus2.getIsCharging(), powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
|
powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
|
||||||
newStatus.notifyObservers(&powerStatus2);
|
newStatus.notifyObservers(&powerStatus2);
|
||||||
#ifdef DEBUG_HEAP
|
#ifdef DEBUG_HEAP
|
||||||
if (lastheap != memGet.getFreeHeap()) {
|
if (lastheap != memGet.getFreeHeap()) {
|
||||||
LOG_DEBUG("Threads running:");
|
std::string threadlist = "Threads running:";
|
||||||
int running = 0;
|
int running = 0;
|
||||||
for (int i = 0; i < MAX_THREADS; i++) {
|
for (int i = 0; i < MAX_THREADS; i++) {
|
||||||
auto thread = concurrency::mainController.get(i);
|
auto thread = concurrency::mainController.get(i);
|
||||||
if ((thread != nullptr) && (thread->enabled)) {
|
if ((thread != nullptr) && (thread->enabled)) {
|
||||||
LOG_DEBUG(" %s", thread->ThreadName.c_str());
|
threadlist += vformat(" %s", thread->ThreadName.c_str());
|
||||||
running++;
|
running++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_DEBUG("\n");
|
LOG_DEBUG(threadlist.c_str());
|
||||||
LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads\n", memGet.getFreeHeap(), memGet.getHeapSize(),
|
LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads", memGet.getFreeHeap(), memGet.getHeapSize(),
|
||||||
memGet.getFreeHeap() - lastheap, running, concurrency::mainController.size(false));
|
memGet.getFreeHeap() - lastheap, running, concurrency::mainController.size(false));
|
||||||
lastheap = memGet.getFreeHeap();
|
lastheap = memGet.getFreeHeap();
|
||||||
}
|
}
|
||||||
@@ -702,13 +702,13 @@ void Power::readPowerStatus()
|
|||||||
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++;
|
||||||
LOG_DEBUG("Low voltage counter: %d/10\n", low_voltage_counter);
|
LOG_DEBUG("Low voltage counter: %d/10", low_voltage_counter);
|
||||||
if (low_voltage_counter > 10) {
|
if (low_voltage_counter > 10) {
|
||||||
#ifdef ARCH_NRF52
|
#ifdef ARCH_NRF52
|
||||||
// We can't trigger deep sleep on NRF52, it's freezing the board
|
// We can't trigger deep sleep on NRF52, it's freezing the board
|
||||||
LOG_DEBUG("Low voltage detected, but not triggering deep sleep\n");
|
LOG_DEBUG("Low voltage detected, but not triggering deep sleep");
|
||||||
#else
|
#else
|
||||||
LOG_INFO("Low voltage detected, triggering deep sleep\n");
|
LOG_INFO("Low voltage detected, triggering deep sleep");
|
||||||
powerFSM.trigger(EVENT_LOW_BATTERY);
|
powerFSM.trigger(EVENT_LOW_BATTERY);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -730,12 +730,12 @@ int32_t Power::runOnce()
|
|||||||
PMU->getIrqStatus();
|
PMU->getIrqStatus();
|
||||||
|
|
||||||
if (PMU->isVbusRemoveIrq()) {
|
if (PMU->isVbusRemoveIrq()) {
|
||||||
LOG_INFO("USB unplugged\n");
|
LOG_INFO("USB unplugged");
|
||||||
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
|
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PMU->isVbusInsertIrq()) {
|
if (PMU->isVbusInsertIrq()) {
|
||||||
LOG_INFO("USB plugged In\n");
|
LOG_INFO("USB plugged In");
|
||||||
powerFSM.trigger(EVENT_POWER_CONNECTED);
|
powerFSM.trigger(EVENT_POWER_CONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -743,21 +743,21 @@ int32_t Power::runOnce()
|
|||||||
Other things we could check if we cared...
|
Other things we could check if we cared...
|
||||||
|
|
||||||
if (PMU->isBatChagerStartIrq()) {
|
if (PMU->isBatChagerStartIrq()) {
|
||||||
LOG_DEBUG("Battery start charging\n");
|
LOG_DEBUG("Battery start charging");
|
||||||
}
|
}
|
||||||
if (PMU->isBatChagerDoneIrq()) {
|
if (PMU->isBatChagerDoneIrq()) {
|
||||||
LOG_DEBUG("Battery fully charged\n");
|
LOG_DEBUG("Battery fully charged");
|
||||||
}
|
}
|
||||||
if (PMU->isBatInsertIrq()) {
|
if (PMU->isBatInsertIrq()) {
|
||||||
LOG_DEBUG("Battery inserted\n");
|
LOG_DEBUG("Battery inserted");
|
||||||
}
|
}
|
||||||
if (PMU->isBatRemoveIrq()) {
|
if (PMU->isBatRemoveIrq()) {
|
||||||
LOG_DEBUG("Battery removed\n");
|
LOG_DEBUG("Battery removed");
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
#ifndef T_WATCH_S3 // FIXME - why is this triggering on the T-Watch S3?
|
#ifndef T_WATCH_S3 // FIXME - why is this triggering on the T-Watch S3?
|
||||||
if (PMU->isPekeyLongPressIrq()) {
|
if (PMU->isPekeyLongPressIrq()) {
|
||||||
LOG_DEBUG("PEK long button press\n");
|
LOG_DEBUG("PEK long button press");
|
||||||
screen->setOn(false);
|
screen->setOn(false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -800,22 +800,22 @@ bool Power::axpChipInit()
|
|||||||
if (!PMU) {
|
if (!PMU) {
|
||||||
PMU = new XPowersAXP2101(*w);
|
PMU = new XPowersAXP2101(*w);
|
||||||
if (!PMU->init()) {
|
if (!PMU->init()) {
|
||||||
LOG_WARN("Failed to find AXP2101 power management\n");
|
LOG_WARN("Failed to find AXP2101 power management");
|
||||||
delete PMU;
|
delete PMU;
|
||||||
PMU = NULL;
|
PMU = NULL;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("AXP2101 PMU init succeeded, using AXP2101 PMU\n");
|
LOG_INFO("AXP2101 PMU init succeeded, using AXP2101 PMU");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PMU) {
|
if (!PMU) {
|
||||||
PMU = new XPowersAXP192(*w);
|
PMU = new XPowersAXP192(*w);
|
||||||
if (!PMU->init()) {
|
if (!PMU->init()) {
|
||||||
LOG_WARN("Failed to find AXP192 power management\n");
|
LOG_WARN("Failed to find AXP192 power management");
|
||||||
delete PMU;
|
delete PMU;
|
||||||
PMU = NULL;
|
PMU = NULL;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("AXP192 PMU init succeeded, using AXP192 PMU\n");
|
LOG_INFO("AXP192 PMU init succeeded, using AXP192 PMU");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -971,56 +971,54 @@ bool Power::axpChipInit()
|
|||||||
PMU->enableVbusVoltageMeasure();
|
PMU->enableVbusVoltageMeasure();
|
||||||
PMU->enableBattVoltageMeasure();
|
PMU->enableBattVoltageMeasure();
|
||||||
|
|
||||||
LOG_DEBUG("=======================================================================\n");
|
|
||||||
if (PMU->isChannelAvailable(XPOWERS_DCDC1)) {
|
if (PMU->isChannelAvailable(XPOWERS_DCDC1)) {
|
||||||
LOG_DEBUG("DC1 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-",
|
LOG_DEBUG("DC1 : %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-",
|
||||||
PMU->getPowerChannelVoltage(XPOWERS_DCDC1));
|
PMU->getPowerChannelVoltage(XPOWERS_DCDC1));
|
||||||
}
|
}
|
||||||
if (PMU->isChannelAvailable(XPOWERS_DCDC2)) {
|
if (PMU->isChannelAvailable(XPOWERS_DCDC2)) {
|
||||||
LOG_DEBUG("DC2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-",
|
LOG_DEBUG("DC2 : %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-",
|
||||||
PMU->getPowerChannelVoltage(XPOWERS_DCDC2));
|
PMU->getPowerChannelVoltage(XPOWERS_DCDC2));
|
||||||
}
|
}
|
||||||
if (PMU->isChannelAvailable(XPOWERS_DCDC3)) {
|
if (PMU->isChannelAvailable(XPOWERS_DCDC3)) {
|
||||||
LOG_DEBUG("DC3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-",
|
LOG_DEBUG("DC3 : %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-",
|
||||||
PMU->getPowerChannelVoltage(XPOWERS_DCDC3));
|
PMU->getPowerChannelVoltage(XPOWERS_DCDC3));
|
||||||
}
|
}
|
||||||
if (PMU->isChannelAvailable(XPOWERS_DCDC4)) {
|
if (PMU->isChannelAvailable(XPOWERS_DCDC4)) {
|
||||||
LOG_DEBUG("DC4 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-",
|
LOG_DEBUG("DC4 : %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-",
|
||||||
PMU->getPowerChannelVoltage(XPOWERS_DCDC4));
|
PMU->getPowerChannelVoltage(XPOWERS_DCDC4));
|
||||||
}
|
}
|
||||||
if (PMU->isChannelAvailable(XPOWERS_LDO2)) {
|
if (PMU->isChannelAvailable(XPOWERS_LDO2)) {
|
||||||
LOG_DEBUG("LDO2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-",
|
LOG_DEBUG("LDO2 : %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-",
|
||||||
PMU->getPowerChannelVoltage(XPOWERS_LDO2));
|
PMU->getPowerChannelVoltage(XPOWERS_LDO2));
|
||||||
}
|
}
|
||||||
if (PMU->isChannelAvailable(XPOWERS_LDO3)) {
|
if (PMU->isChannelAvailable(XPOWERS_LDO3)) {
|
||||||
LOG_DEBUG("LDO3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-",
|
LOG_DEBUG("LDO3 : %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-",
|
||||||
PMU->getPowerChannelVoltage(XPOWERS_LDO3));
|
PMU->getPowerChannelVoltage(XPOWERS_LDO3));
|
||||||
}
|
}
|
||||||
if (PMU->isChannelAvailable(XPOWERS_ALDO1)) {
|
if (PMU->isChannelAvailable(XPOWERS_ALDO1)) {
|
||||||
LOG_DEBUG("ALDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-",
|
LOG_DEBUG("ALDO1: %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-",
|
||||||
PMU->getPowerChannelVoltage(XPOWERS_ALDO1));
|
PMU->getPowerChannelVoltage(XPOWERS_ALDO1));
|
||||||
}
|
}
|
||||||
if (PMU->isChannelAvailable(XPOWERS_ALDO2)) {
|
if (PMU->isChannelAvailable(XPOWERS_ALDO2)) {
|
||||||
LOG_DEBUG("ALDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-",
|
LOG_DEBUG("ALDO2: %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-",
|
||||||
PMU->getPowerChannelVoltage(XPOWERS_ALDO2));
|
PMU->getPowerChannelVoltage(XPOWERS_ALDO2));
|
||||||
}
|
}
|
||||||
if (PMU->isChannelAvailable(XPOWERS_ALDO3)) {
|
if (PMU->isChannelAvailable(XPOWERS_ALDO3)) {
|
||||||
LOG_DEBUG("ALDO3: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-",
|
LOG_DEBUG("ALDO3: %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-",
|
||||||
PMU->getPowerChannelVoltage(XPOWERS_ALDO3));
|
PMU->getPowerChannelVoltage(XPOWERS_ALDO3));
|
||||||
}
|
}
|
||||||
if (PMU->isChannelAvailable(XPOWERS_ALDO4)) {
|
if (PMU->isChannelAvailable(XPOWERS_ALDO4)) {
|
||||||
LOG_DEBUG("ALDO4: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-",
|
LOG_DEBUG("ALDO4: %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-",
|
||||||
PMU->getPowerChannelVoltage(XPOWERS_ALDO4));
|
PMU->getPowerChannelVoltage(XPOWERS_ALDO4));
|
||||||
}
|
}
|
||||||
if (PMU->isChannelAvailable(XPOWERS_BLDO1)) {
|
if (PMU->isChannelAvailable(XPOWERS_BLDO1)) {
|
||||||
LOG_DEBUG("BLDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-",
|
LOG_DEBUG("BLDO1: %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-",
|
||||||
PMU->getPowerChannelVoltage(XPOWERS_BLDO1));
|
PMU->getPowerChannelVoltage(XPOWERS_BLDO1));
|
||||||
}
|
}
|
||||||
if (PMU->isChannelAvailable(XPOWERS_BLDO2)) {
|
if (PMU->isChannelAvailable(XPOWERS_BLDO2)) {
|
||||||
LOG_DEBUG("BLDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-",
|
LOG_DEBUG("BLDO2: %s Voltage:%u mV ", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-",
|
||||||
PMU->getPowerChannelVoltage(XPOWERS_BLDO2));
|
PMU->getPowerChannelVoltage(XPOWERS_BLDO2));
|
||||||
}
|
}
|
||||||
LOG_DEBUG("=======================================================================\n");
|
|
||||||
|
|
||||||
// We can safely ignore this approach for most (or all) boards because MCU turned off
|
// We can safely ignore this approach for most (or all) boards because MCU turned off
|
||||||
// earlier than battery discharged to 2.6V.
|
// earlier than battery discharged to 2.6V.
|
||||||
@@ -1126,7 +1124,7 @@ LipoBatteryLevel lipoLevel;
|
|||||||
bool Power::lipoInit()
|
bool Power::lipoInit()
|
||||||
{
|
{
|
||||||
bool result = lipoLevel.runOnce();
|
bool result = lipoLevel.runOnce();
|
||||||
LOG_DEBUG("Power::lipoInit lipo sensor is %s\n", result ? "ready" : "not ready yet");
|
LOG_DEBUG("Power::lipoInit lipo sensor is %s", result ? "ready" : "not ready yet");
|
||||||
if (!result)
|
if (!result)
|
||||||
return false;
|
return false;
|
||||||
batteryLevel = &lipoLevel;
|
batteryLevel = &lipoLevel;
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ static bool isPowered()
|
|||||||
|
|
||||||
static void sdsEnter()
|
static void sdsEnter()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Enter state: SDS\n");
|
LOG_DEBUG("Enter state: SDS");
|
||||||
// FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw
|
// FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw
|
||||||
doDeepSleep(Default::getConfiguredOrDefaultMs(config.power.sds_secs), false);
|
doDeepSleep(Default::getConfiguredOrDefaultMs(config.power.sds_secs), false);
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ extern Power *power;
|
|||||||
|
|
||||||
static void shutdownEnter()
|
static void shutdownEnter()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Enter state: SHUTDOWN\n");
|
LOG_DEBUG("Enter state: SHUTDOWN");
|
||||||
power->shutdown();
|
power->shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,16 +72,16 @@ static uint32_t secsSlept;
|
|||||||
|
|
||||||
static void lsEnter()
|
static void lsEnter()
|
||||||
{
|
{
|
||||||
LOG_INFO("lsEnter begin, ls_secs=%u\n", config.power.ls_secs);
|
LOG_INFO("lsEnter begin, ls_secs=%u", config.power.ls_secs);
|
||||||
screen->setOn(false);
|
screen->setOn(false);
|
||||||
secsSlept = 0; // How long have we been sleeping this time
|
secsSlept = 0; // How long have we been sleeping this time
|
||||||
|
|
||||||
// LOG_INFO("lsEnter end\n");
|
// LOG_INFO("lsEnter end");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lsIdle()
|
static void lsIdle()
|
||||||
{
|
{
|
||||||
// LOG_INFO("lsIdle begin ls_secs=%u\n", getPref_ls_secs());
|
// LOG_INFO("lsIdle begin ls_secs=%u", getPref_ls_secs());
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ static void lsIdle()
|
|||||||
wakeCause2 = doLightSleep(100); // leave led on for 1ms
|
wakeCause2 = doLightSleep(100); // leave led on for 1ms
|
||||||
|
|
||||||
secsSlept += sleepTime;
|
secsSlept += sleepTime;
|
||||||
// LOG_INFO("sleeping, flash led!\n");
|
// LOG_INFO("sleeping, flash led!");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ESP_SLEEP_WAKEUP_UART:
|
case ESP_SLEEP_WAKEUP_UART:
|
||||||
@@ -137,7 +137,7 @@ static void lsIdle()
|
|||||||
} else {
|
} else {
|
||||||
// Time to stop sleeping!
|
// Time to stop sleeping!
|
||||||
ledBlink.set(false);
|
ledBlink.set(false);
|
||||||
LOG_INFO("Reached ls_secs, servicing loop()\n");
|
LOG_INFO("Reached ls_secs, servicing loop()");
|
||||||
powerFSM.trigger(EVENT_WAKE_TIMER);
|
powerFSM.trigger(EVENT_WAKE_TIMER);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -145,12 +145,12 @@ static void lsIdle()
|
|||||||
|
|
||||||
static void lsExit()
|
static void lsExit()
|
||||||
{
|
{
|
||||||
LOG_INFO("Exit state: LS\n");
|
LOG_INFO("Exit state: LS");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nbEnter()
|
static void nbEnter()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Enter state: NB\n");
|
LOG_DEBUG("Enter state: NB");
|
||||||
screen->setOn(false);
|
screen->setOn(false);
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
// Only ESP32 should turn off bluetooth
|
// Only ESP32 should turn off bluetooth
|
||||||
@@ -168,7 +168,7 @@ static void darkEnter()
|
|||||||
|
|
||||||
static void serialEnter()
|
static void serialEnter()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Enter state: SERIAL\n");
|
LOG_DEBUG("Enter state: SERIAL");
|
||||||
setBluetoothEnable(false);
|
setBluetoothEnable(false);
|
||||||
screen->setOn(true);
|
screen->setOn(true);
|
||||||
screen->print("Serial connected\n");
|
screen->print("Serial connected\n");
|
||||||
@@ -183,10 +183,10 @@ static void serialExit()
|
|||||||
|
|
||||||
static void powerEnter()
|
static void powerEnter()
|
||||||
{
|
{
|
||||||
// LOG_DEBUG("Enter state: POWER\n");
|
// LOG_DEBUG("Enter state: POWER");
|
||||||
if (!isPowered()) {
|
if (!isPowered()) {
|
||||||
// If we got here, we are in the wrong state - we should be in powered, let that state ahndle things
|
// If we got here, we are in the wrong state - we should be in powered, let that state ahndle things
|
||||||
LOG_INFO("Loss of power in Powered\n");
|
LOG_INFO("Loss of power in Powered");
|
||||||
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
|
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
|
||||||
} else {
|
} else {
|
||||||
screen->setOn(true);
|
screen->setOn(true);
|
||||||
@@ -205,7 +205,7 @@ static void powerIdle()
|
|||||||
{
|
{
|
||||||
if (!isPowered()) {
|
if (!isPowered()) {
|
||||||
// If we got here, we are in the wrong state
|
// If we got here, we are in the wrong state
|
||||||
LOG_INFO("Loss of power in Powered\n");
|
LOG_INFO("Loss of power in Powered");
|
||||||
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
|
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,7 +222,7 @@ static void powerExit()
|
|||||||
|
|
||||||
static void onEnter()
|
static void onEnter()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Enter state: ON\n");
|
LOG_DEBUG("Enter state: ON");
|
||||||
screen->setOn(true);
|
screen->setOn(true);
|
||||||
setBluetoothEnable(true);
|
setBluetoothEnable(true);
|
||||||
}
|
}
|
||||||
@@ -242,7 +242,7 @@ static void screenPress()
|
|||||||
|
|
||||||
static void bootEnter()
|
static void bootEnter()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Enter state: BOOT\n");
|
LOG_DEBUG("Enter state: BOOT");
|
||||||
}
|
}
|
||||||
|
|
||||||
State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN");
|
State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN");
|
||||||
@@ -264,7 +264,7 @@ void PowerFSM_setup()
|
|||||||
config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR;
|
config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR;
|
||||||
bool hasPower = isPowered();
|
bool hasPower = isPowered();
|
||||||
|
|
||||||
LOG_INFO("PowerFSM init, USB power=%d\n", hasPower ? 1 : 0);
|
LOG_INFO("PowerFSM init, USB power=%d", hasPower ? 1 : 0);
|
||||||
powerFSM.add_timed_transition(&stateBOOT, hasPower ? &statePOWER : &stateON, 3 * 1000, NULL, "boot timeout");
|
powerFSM.add_timed_transition(&stateBOOT, hasPower ? &statePOWER : &stateON, 3 * 1000, NULL, "boot timeout");
|
||||||
|
|
||||||
// wake timer expired or a packet arrived
|
// wake timer expired or a packet arrived
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ void PowerMon::emitLog(const char *reason)
|
|||||||
{
|
{
|
||||||
#ifdef USE_POWERMON
|
#ifdef USE_POWERMON
|
||||||
// The nrf52 printf doesn't understand 64 bit ints, so if we ever reach that point this function will need to change.
|
// The nrf52 printf doesn't understand 64 bit ints, so if we ever reach that point this function will need to change.
|
||||||
LOG_INFO("S:PM:0x%08lx,%s\n", (uint32_t)states, reason);
|
LOG_INFO("S:PM:0x%08lx,%s", (uint32_t)states, reason);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ class PowerStatus : public Status
|
|||||||
isCharging = newStatus->isCharging;
|
isCharging = newStatus->isCharging;
|
||||||
}
|
}
|
||||||
if (isDirty) {
|
if (isDirty) {
|
||||||
// LOG_DEBUG("Battery %dmV %d%%\n", batteryVoltageMv, batteryChargePercent);
|
// LOG_DEBUG("Battery %dmV %d%%", batteryVoltageMv, batteryChargePercent);
|
||||||
onNewStatus.notifyObservers(this);
|
onNewStatus.notifyObservers(this);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -98,81 +98,75 @@ void RedirectablePrint::log_to_serial(const char *logLevel, const char *format,
|
|||||||
{
|
{
|
||||||
size_t r = 0;
|
size_t r = 0;
|
||||||
|
|
||||||
// Cope with 0 len format strings, but look for new line terminator
|
|
||||||
bool hasNewline = *format && format[strlen(format) - 1] == '\n';
|
|
||||||
#ifdef ARCH_PORTDUINO
|
#ifdef ARCH_PORTDUINO
|
||||||
bool color = !settingsMap[ascii_logs];
|
bool color = !settingsMap[ascii_logs];
|
||||||
#else
|
#else
|
||||||
bool color = true;
|
bool color = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// If we are the first message on a report, include the header
|
// include the header
|
||||||
if (!isContinuationMessage) {
|
if (color) {
|
||||||
|
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0)
|
||||||
|
Print::write("\u001b[34m", 6);
|
||||||
|
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0)
|
||||||
|
Print::write("\u001b[32m", 6);
|
||||||
|
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0)
|
||||||
|
Print::write("\u001b[33m", 6);
|
||||||
|
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_ERROR) == 0)
|
||||||
|
Print::write("\u001b[31m", 6);
|
||||||
|
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0)
|
||||||
|
Print::write("\u001b[35m", 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // display local time on logfile
|
||||||
|
if (rtc_sec > 0) {
|
||||||
|
long hms = rtc_sec % SEC_PER_DAY;
|
||||||
|
// hms += tz.tz_dsttime * SEC_PER_HOUR;
|
||||||
|
// hms -= tz.tz_minuteswest * SEC_PER_MIN;
|
||||||
|
// mod `hms` to ensure in positive range of [0...SEC_PER_DAY)
|
||||||
|
hms = (hms + SEC_PER_DAY) % SEC_PER_DAY;
|
||||||
|
|
||||||
|
// Tear apart hms into h:m:s
|
||||||
|
int hour = hms / SEC_PER_HOUR;
|
||||||
|
int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN;
|
||||||
|
int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN
|
||||||
|
#ifdef ARCH_PORTDUINO
|
||||||
|
::printf("%s ", logLevel);
|
||||||
if (color) {
|
if (color) {
|
||||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0)
|
::printf("\u001b[0m");
|
||||||
Print::write("\u001b[34m", 6);
|
|
||||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0)
|
|
||||||
Print::write("\u001b[32m", 6);
|
|
||||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0)
|
|
||||||
Print::write("\u001b[33m", 6);
|
|
||||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_ERROR) == 0)
|
|
||||||
Print::write("\u001b[31m", 6);
|
|
||||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0)
|
|
||||||
Print::write("\u001b[35m", 6);
|
|
||||||
}
|
}
|
||||||
|
::printf("| %02d:%02d:%02d %u ", hour, min, sec, millis() / 1000);
|
||||||
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice, true); // display local time on logfile
|
|
||||||
if (rtc_sec > 0) {
|
|
||||||
long hms = rtc_sec % SEC_PER_DAY;
|
|
||||||
// hms += tz.tz_dsttime * SEC_PER_HOUR;
|
|
||||||
// hms -= tz.tz_minuteswest * SEC_PER_MIN;
|
|
||||||
// mod `hms` to ensure in positive range of [0...SEC_PER_DAY)
|
|
||||||
hms = (hms + SEC_PER_DAY) % SEC_PER_DAY;
|
|
||||||
|
|
||||||
// Tear apart hms into h:m:s
|
|
||||||
int hour = hms / SEC_PER_HOUR;
|
|
||||||
int min = (hms % SEC_PER_HOUR) / SEC_PER_MIN;
|
|
||||||
int sec = (hms % SEC_PER_HOUR) % SEC_PER_MIN; // or hms % SEC_PER_MIN
|
|
||||||
#ifdef ARCH_PORTDUINO
|
|
||||||
::printf("%s ", logLevel);
|
|
||||||
if (color) {
|
|
||||||
::printf("\u001b[0m");
|
|
||||||
}
|
|
||||||
::printf("| %02d:%02d:%02d %u ", hour, min, sec, millis() / 1000);
|
|
||||||
#else
|
#else
|
||||||
printf("%s ", logLevel);
|
printf("%s ", logLevel);
|
||||||
if (color) {
|
if (color) {
|
||||||
printf("\u001b[0m");
|
printf("\u001b[0m");
|
||||||
}
|
}
|
||||||
printf("| %02d:%02d:%02d %u ", hour, min, sec, millis() / 1000);
|
printf("| %02d:%02d:%02d %u ", hour, min, sec, millis() / 1000);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#ifdef ARCH_PORTDUINO
|
#ifdef ARCH_PORTDUINO
|
||||||
::printf("%s ", logLevel);
|
::printf("%s ", logLevel);
|
||||||
if (color) {
|
if (color) {
|
||||||
::printf("\u001b[0m");
|
::printf("\u001b[0m");
|
||||||
}
|
}
|
||||||
::printf("| ??:??:?? %u ", millis() / 1000);
|
::printf("| ??:??:?? %u ", millis() / 1000);
|
||||||
#else
|
#else
|
||||||
printf("%s ", logLevel);
|
printf("%s ", logLevel);
|
||||||
if (color) {
|
if (color) {
|
||||||
printf("\u001b[0m");
|
printf("\u001b[0m");
|
||||||
}
|
}
|
||||||
printf("| ??:??:?? %u ", millis() / 1000);
|
printf("| ??:??:?? %u ", millis() / 1000);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
auto thread = concurrency::OSThread::currentThread;
|
auto thread = concurrency::OSThread::currentThread;
|
||||||
if (thread) {
|
if (thread) {
|
||||||
print("[");
|
print("[");
|
||||||
// printf("%p ", thread);
|
// printf("%p ", thread);
|
||||||
// assert(thread->ThreadName.length());
|
// assert(thread->ThreadName.length());
|
||||||
print(thread->ThreadName);
|
print(thread->ThreadName);
|
||||||
print("] ");
|
print("] ");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
r += vprintf(logLevel, format, arg);
|
r += vprintf(logLevel, format, arg);
|
||||||
|
|
||||||
isContinuationMessage = !hasNewline;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RedirectablePrint::log_to_syslog(const char *logLevel, const char *format, va_list arg)
|
void RedirectablePrint::log_to_syslog(const char *logLevel, const char *format, va_list arg)
|
||||||
@@ -283,6 +277,14 @@ meshtastic_LogRecord_Level RedirectablePrint::getLogLevel(const char *logLevel)
|
|||||||
|
|
||||||
void RedirectablePrint::log(const char *logLevel, const char *format, ...)
|
void RedirectablePrint::log(const char *logLevel, const char *format, ...)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// append \n to format
|
||||||
|
size_t len = strlen(format);
|
||||||
|
char *newFormat = new char[len + 2];
|
||||||
|
strcpy(newFormat, format);
|
||||||
|
newFormat[len] = '\n';
|
||||||
|
newFormat[len + 1] = '\0';
|
||||||
|
|
||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO
|
||||||
// level trace is special, two possible ways to handle it.
|
// level trace is special, two possible ways to handle it.
|
||||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) {
|
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) {
|
||||||
@@ -295,17 +297,24 @@ void RedirectablePrint::log(const char *logLevel, const char *format, ...)
|
|||||||
}
|
}
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
}
|
}
|
||||||
if (settingsMap[logoutputlevel] < level_trace && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0)
|
if (settingsMap[logoutputlevel] < level_trace && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) {
|
||||||
|
delete[] newFormat;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (settingsMap[logoutputlevel] < level_debug && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0)
|
if (settingsMap[logoutputlevel] < level_debug && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0) {
|
||||||
|
delete[] newFormat;
|
||||||
return;
|
return;
|
||||||
else if (settingsMap[logoutputlevel] < level_info && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0)
|
} else if (settingsMap[logoutputlevel] < level_info && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_INFO) == 0) {
|
||||||
|
delete[] newFormat;
|
||||||
return;
|
return;
|
||||||
else if (settingsMap[logoutputlevel] < level_warn && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0)
|
} else if (settingsMap[logoutputlevel] < level_warn && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_WARN) == 0) {
|
||||||
|
delete[] newFormat;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (moduleConfig.serial.override_console_serial_port && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0) {
|
if (moduleConfig.serial.override_console_serial_port && strcmp(logLevel, MESHTASTIC_LOG_LEVEL_DEBUG) == 0) {
|
||||||
|
delete[] newFormat;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,9 +328,9 @@ void RedirectablePrint::log(const char *logLevel, const char *format, ...)
|
|||||||
va_list arg;
|
va_list arg;
|
||||||
va_start(arg, format);
|
va_start(arg, format);
|
||||||
|
|
||||||
log_to_serial(logLevel, format, arg);
|
log_to_serial(logLevel, newFormat, arg);
|
||||||
log_to_syslog(logLevel, format, arg);
|
log_to_syslog(logLevel, newFormat, arg);
|
||||||
log_to_ble(logLevel, format, arg);
|
log_to_ble(logLevel, newFormat, arg);
|
||||||
|
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
#ifdef HAS_FREE_RTOS
|
#ifdef HAS_FREE_RTOS
|
||||||
@@ -331,17 +340,18 @@ void RedirectablePrint::log(const char *logLevel, const char *format, ...)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete[] newFormat;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16_t len)
|
void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16_t len)
|
||||||
{
|
{
|
||||||
const char alphabet[17] = "0123456789abcdef";
|
const char alphabet[17] = "0123456789abcdef";
|
||||||
log(logLevel, " +------------------------------------------------+ +----------------+\n");
|
log(logLevel, " +------------------------------------------------+ +----------------+");
|
||||||
log(logLevel, " |.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f | | ASCII |\n");
|
log(logLevel, " |.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f | | ASCII |");
|
||||||
for (uint16_t i = 0; i < len; i += 16) {
|
for (uint16_t i = 0; i < len; i += 16) {
|
||||||
if (i % 128 == 0)
|
if (i % 128 == 0)
|
||||||
log(logLevel, " +------------------------------------------------+ +----------------+\n");
|
log(logLevel, " +------------------------------------------------+ +----------------+");
|
||||||
char s[] = "| | | |\n";
|
char s[] = "| | | |\n";
|
||||||
uint8_t ix = 1, iy = 52;
|
uint8_t ix = 1, iy = 52;
|
||||||
for (uint8_t j = 0; j < 16; j++) {
|
for (uint8_t j = 0; j < 16; j++) {
|
||||||
@@ -363,7 +373,7 @@ void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16
|
|||||||
log(logLevel, ".");
|
log(logLevel, ".");
|
||||||
log(logLevel, s);
|
log(logLevel, s);
|
||||||
}
|
}
|
||||||
log(logLevel, " +------------------------------------------------+ +----------------+\n");
|
log(logLevel, " +------------------------------------------------+ +----------------+");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string RedirectablePrint::mt_sprintf(const std::string fmt_str, ...)
|
std::string RedirectablePrint::mt_sprintf(const std::string fmt_str, ...)
|
||||||
|
|||||||
@@ -15,9 +15,6 @@ class RedirectablePrint : public Print
|
|||||||
{
|
{
|
||||||
Print *dest;
|
Print *dest;
|
||||||
|
|
||||||
/// Used to allow multiple logDebug messages to appear on a single log line
|
|
||||||
bool isContinuationMessage = false;
|
|
||||||
|
|
||||||
#ifdef HAS_FREE_RTOS
|
#ifdef HAS_FREE_RTOS
|
||||||
SemaphoreHandle_t inDebugPrint = nullptr;
|
SemaphoreHandle_t inDebugPrint = nullptr;
|
||||||
StaticSemaphore_t _MutexStorageSpace;
|
StaticSemaphore_t _MutexStorageSpace;
|
||||||
|
|||||||
@@ -59,14 +59,14 @@ bool SafeFile::close()
|
|||||||
|
|
||||||
// brief window of risk here ;-)
|
// brief window of risk here ;-)
|
||||||
if (fullAtomic && FSCom.exists(filename.c_str()) && !FSCom.remove(filename.c_str())) {
|
if (fullAtomic && FSCom.exists(filename.c_str()) && !FSCom.remove(filename.c_str())) {
|
||||||
LOG_ERROR("Can't remove old pref file\n");
|
LOG_ERROR("Can't remove old pref file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String filenameTmp = filename;
|
String filenameTmp = filename;
|
||||||
filenameTmp += ".tmp";
|
filenameTmp += ".tmp";
|
||||||
if (!renameFile(filenameTmp.c_str(), filename.c_str())) {
|
if (!renameFile(filenameTmp.c_str(), filename.c_str())) {
|
||||||
LOG_ERROR("Error: can't rename new pref file\n");
|
LOG_ERROR("Error: can't rename new pref file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ bool SafeFile::testReadback()
|
|||||||
filenameTmp += ".tmp";
|
filenameTmp += ".tmp";
|
||||||
auto f2 = FSCom.open(filenameTmp.c_str(), FILE_O_READ);
|
auto f2 = FSCom.open(filenameTmp.c_str(), FILE_O_READ);
|
||||||
if (!f2) {
|
if (!f2) {
|
||||||
LOG_ERROR("Can't open tmp file for readback\n");
|
LOG_ERROR("Can't open tmp file for readback");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ bool SafeFile::testReadback()
|
|||||||
f2.close();
|
f2.close();
|
||||||
|
|
||||||
if (test_hash != hash) {
|
if (test_hash != hash) {
|
||||||
LOG_ERROR("Readback failed hash mismatch\n");
|
LOG_ERROR("Readback failed hash mismatch");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,17 +13,17 @@ void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
|
|||||||
{
|
{
|
||||||
|
|
||||||
if (reportType == TX_LOG) {
|
if (reportType == TX_LOG) {
|
||||||
LOG_DEBUG("AirTime - Packet transmitted : %ums\n", airtime_ms);
|
LOG_DEBUG("Packet transmitted : %ums", airtime_ms);
|
||||||
this->airtimes.periodTX[0] = this->airtimes.periodTX[0] + airtime_ms;
|
this->airtimes.periodTX[0] = this->airtimes.periodTX[0] + airtime_ms;
|
||||||
air_period_tx[0] = air_period_tx[0] + airtime_ms;
|
air_period_tx[0] = air_period_tx[0] + airtime_ms;
|
||||||
|
|
||||||
this->utilizationTX[this->getPeriodUtilHour()] = this->utilizationTX[this->getPeriodUtilHour()] + airtime_ms;
|
this->utilizationTX[this->getPeriodUtilHour()] = this->utilizationTX[this->getPeriodUtilHour()] + airtime_ms;
|
||||||
} else if (reportType == RX_LOG) {
|
} else if (reportType == RX_LOG) {
|
||||||
LOG_DEBUG("AirTime - Packet received : %ums\n", airtime_ms);
|
LOG_DEBUG("Packet received : %ums", airtime_ms);
|
||||||
this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + airtime_ms;
|
this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + airtime_ms;
|
||||||
air_period_rx[0] = air_period_rx[0] + airtime_ms;
|
air_period_rx[0] = air_period_rx[0] + airtime_ms;
|
||||||
} else if (reportType == RX_ALL_LOG) {
|
} else if (reportType == RX_ALL_LOG) {
|
||||||
LOG_DEBUG("AirTime - Packet received (noise?) : %ums\n", airtime_ms);
|
LOG_DEBUG("Packet received (noise?) : %ums", airtime_ms);
|
||||||
this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + airtime_ms;
|
this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + airtime_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ void AirTime::airtimeRotatePeriod()
|
|||||||
{
|
{
|
||||||
|
|
||||||
if (this->airtimes.lastPeriodIndex != this->currentPeriodIndex()) {
|
if (this->airtimes.lastPeriodIndex != this->currentPeriodIndex()) {
|
||||||
LOG_DEBUG("Rotating airtimes to a new period = %u\n", this->currentPeriodIndex());
|
LOG_DEBUG("Rotating airtimes to a new period = %u", this->currentPeriodIndex());
|
||||||
|
|
||||||
for (int i = PERIODS_TO_LOG - 2; i >= 0; --i) {
|
for (int i = PERIODS_TO_LOG - 2; i >= 0; --i) {
|
||||||
this->airtimes.periodTX[i + 1] = this->airtimes.periodTX[i];
|
this->airtimes.periodTX[i + 1] = this->airtimes.periodTX[i];
|
||||||
@@ -105,7 +105,7 @@ float AirTime::channelUtilizationPercent()
|
|||||||
uint32_t sum = 0;
|
uint32_t sum = 0;
|
||||||
for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) {
|
for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) {
|
||||||
sum += this->channelUtilization[i];
|
sum += this->channelUtilization[i];
|
||||||
// LOG_DEBUG("ChanUtilArray %u %u\n", i, this->channelUtilization[i]);
|
// LOG_DEBUG("ChanUtilArray %u %u", i, this->channelUtilization[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (float(sum) / float(CHANNEL_UTILIZATION_PERIODS * 10 * 1000)) * 100;
|
return (float(sum) / float(CHANNEL_UTILIZATION_PERIODS * 10 * 1000)) * 100;
|
||||||
@@ -127,7 +127,7 @@ bool AirTime::isTxAllowedChannelUtil(bool polite)
|
|||||||
if (channelUtilizationPercent() < percentage) {
|
if (channelUtilizationPercent() < percentage) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN("Channel utilization is >%d percent. Skipping this opportunity to send.\n", percentage);
|
LOG_WARN("Channel utilization is >%d percent. Skipping this opportunity to send.", percentage);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,7 +138,7 @@ bool AirTime::isTxAllowedAirUtil()
|
|||||||
if (utilizationTXPercent() < myRegion->dutyCycle * polite_duty_cycle_percent / 100) {
|
if (utilizationTXPercent() < myRegion->dutyCycle * polite_duty_cycle_percent / 100) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN("Tx air utilization is >%f percent. Skipping this opportunity to send.\n",
|
LOG_WARN("Tx air utilization is >%f percent. Skipping this opportunity to send.",
|
||||||
myRegion->dutyCycle * polite_duty_cycle_percent / 100);
|
myRegion->dutyCycle * polite_duty_cycle_percent / 100);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -209,13 +209,13 @@ int32_t AirTime::runOnce()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
LOG_DEBUG("utilPeriodTX %d TX Airtime %3.2f%\n", utilPeriodTX, airTime->utilizationTXPercent());
|
LOG_DEBUG("utilPeriodTX %d TX Airtime %3.2f%", utilPeriodTX, airTime->utilizationTXPercent());
|
||||||
for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
|
for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
|
||||||
LOG_DEBUG(
|
LOG_DEBUG(
|
||||||
"%d,", this->utilizationTX[i]
|
"%d,", this->utilizationTX[i]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
LOG_DEBUG("\n");
|
LOG_DEBUG("");
|
||||||
*/
|
*/
|
||||||
return (1000 * 1);
|
return (1000 * 1);
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,7 @@ bool InterruptableDelay::delay(uint32_t msec)
|
|||||||
// sem take will return false if we timed out (i.e. were not interrupted)
|
// sem take will return false if we timed out (i.e. were not interrupted)
|
||||||
bool r = semaphore.take(msec);
|
bool r = semaphore.take(msec);
|
||||||
|
|
||||||
// LOG_DEBUG("interrupt=%d\n", r);
|
// LOG_DEBUG("interrupt=%d", r);
|
||||||
return !r;
|
return !r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,12 +32,12 @@ IRAM_ATTR bool NotifiedWorkerThread::notifyCommon(uint32_t v, bool overwrite)
|
|||||||
|
|
||||||
notification = v;
|
notification = v;
|
||||||
if (debugNotification) {
|
if (debugNotification) {
|
||||||
LOG_DEBUG("setting notification %d\n", v);
|
LOG_DEBUG("setting notification %d", v);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if (debugNotification) {
|
if (debugNotification) {
|
||||||
LOG_DEBUG("dropping notification %d\n", v);
|
LOG_DEBUG("dropping notification %d", v);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ bool NotifiedWorkerThread::notifyLater(uint32_t delay, uint32_t v, bool overwrit
|
|||||||
if (didIt) { // If we didn't already have something queued, override the delay to be larger
|
if (didIt) { // If we didn't already have something queued, override the delay to be larger
|
||||||
setIntervalFromNow(delay); // a new version of setInterval relative to the current time
|
setIntervalFromNow(delay); // a new version of setInterval relative to the current time
|
||||||
if (debugNotification) {
|
if (debugNotification) {
|
||||||
LOG_DEBUG("delaying notification %u\n", delay);
|
LOG_DEBUG("delaying notification %u", delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,15 +62,15 @@ bool OSThread::shouldRun(unsigned long time)
|
|||||||
bool r = Thread::shouldRun(time);
|
bool r = Thread::shouldRun(time);
|
||||||
|
|
||||||
if (showRun && r) {
|
if (showRun && r) {
|
||||||
LOG_DEBUG("Thread %s: run\n", ThreadName.c_str());
|
LOG_DEBUG("Thread %s: run", ThreadName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showWaiting && enabled && !r) {
|
if (showWaiting && enabled && !r) {
|
||||||
LOG_DEBUG("Thread %s: wait %lu\n", ThreadName.c_str(), interval);
|
LOG_DEBUG("Thread %s: wait %lu", ThreadName.c_str(), interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showDisabled && !enabled) {
|
if (showDisabled && !enabled) {
|
||||||
LOG_DEBUG("Thread %s: disabled\n", ThreadName.c_str());
|
LOG_DEBUG("Thread %s: disabled", ThreadName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
@@ -86,9 +86,9 @@ void OSThread::run()
|
|||||||
#ifdef DEBUG_HEAP
|
#ifdef DEBUG_HEAP
|
||||||
auto newHeap = memGet.getFreeHeap();
|
auto newHeap = memGet.getFreeHeap();
|
||||||
if (newHeap < heap)
|
if (newHeap < heap)
|
||||||
LOG_DEBUG("------ Thread %s leaked heap %d -> %d (%d) ------\n", ThreadName.c_str(), heap, newHeap, newHeap - heap);
|
LOG_DEBUG("------ Thread %s leaked heap %d -> %d (%d) ------", ThreadName.c_str(), heap, newHeap, newHeap - heap);
|
||||||
if (heap < newHeap)
|
if (heap < newHeap)
|
||||||
LOG_DEBUG("++++++ Thread %s freed heap %d -> %d (%d) ++++++\n", ThreadName.c_str(), heap, newHeap, newHeap - heap);
|
LOG_DEBUG("++++++ Thread %s freed heap %d -> %d (%d) ++++++", ThreadName.c_str(), heap, newHeap, newHeap - heap);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
runned();
|
runned();
|
||||||
|
|||||||
@@ -144,6 +144,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define MLX90632_ADDR 0x3A
|
#define MLX90632_ADDR 0x3A
|
||||||
#define DFROBOT_LARK_ADDR 0x42
|
#define DFROBOT_LARK_ADDR 0x42
|
||||||
#define NAU7802_ADDR 0x2A
|
#define NAU7802_ADDR 0x2A
|
||||||
|
#define MAX30102_ADDR 0x57
|
||||||
|
#define MLX90614_ADDR_DEF 0x5A
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// ACCELEROMETER
|
// ACCELEROMETER
|
||||||
@@ -185,6 +187,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
#define FT6336U_ADDR 0x48
|
#define FT6336U_ADDR 0x48
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// BIAS-T Generator
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
#define TPS65233_ADDR 0x60
|
||||||
|
|
||||||
// convert 24-bit color to 16-bit (56K)
|
// convert 24-bit color to 16-bit (56K)
|
||||||
#define COLOR565(r, g, b) (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3))
|
#define COLOR565(r, g, b) (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3))
|
||||||
|
|
||||||
|
|||||||
@@ -52,13 +52,16 @@ class ScanI2C
|
|||||||
TSL2591,
|
TSL2591,
|
||||||
OPT3001,
|
OPT3001,
|
||||||
MLX90632,
|
MLX90632,
|
||||||
|
MLX90614,
|
||||||
AHT10,
|
AHT10,
|
||||||
BMX160,
|
BMX160,
|
||||||
DFROBOT_LARK,
|
DFROBOT_LARK,
|
||||||
NAU7802,
|
NAU7802,
|
||||||
FT6336U,
|
FT6336U,
|
||||||
STK8BAXX,
|
STK8BAXX,
|
||||||
ICM20948
|
ICM20948,
|
||||||
|
MAX30102,
|
||||||
|
TPS65233
|
||||||
} DeviceType;
|
} DeviceType;
|
||||||
|
|
||||||
// typedef uint8_t DeviceAddress;
|
// typedef uint8_t DeviceAddress;
|
||||||
|
|||||||
@@ -71,15 +71,15 @@ ScanI2C::DeviceType ScanI2CTwoWire::probeOLED(ScanI2C::DeviceAddress addr) const
|
|||||||
r &= 0x0f;
|
r &= 0x0f;
|
||||||
|
|
||||||
if (r == 0x08 || r == 0x00) {
|
if (r == 0x08 || r == 0x00) {
|
||||||
LOG_INFO("sh1106 display found\n");
|
LOG_INFO("sh1106 display found");
|
||||||
o_probe = SCREEN_SH1106; // SH1106
|
o_probe = SCREEN_SH1106; // SH1106
|
||||||
} else if (r == 0x03 || r == 0x04 || r == 0x06 || r == 0x07) {
|
} else if (r == 0x03 || r == 0x04 || r == 0x06 || r == 0x07) {
|
||||||
LOG_INFO("ssd1306 display found\n");
|
LOG_INFO("ssd1306 display found");
|
||||||
o_probe = SCREEN_SSD1306; // SSD1306
|
o_probe = SCREEN_SSD1306; // SSD1306
|
||||||
}
|
}
|
||||||
c++;
|
c++;
|
||||||
} while ((r != r_prev) && (c < 4));
|
} while ((r != r_prev) && (c < 4));
|
||||||
LOG_DEBUG("0x%x subtype probed in %i tries \n", r, c);
|
LOG_DEBUG("0x%x subtype probed in %i tries ", r, c);
|
||||||
|
|
||||||
return o_probe;
|
return o_probe;
|
||||||
}
|
}
|
||||||
@@ -88,31 +88,31 @@ void ScanI2CTwoWire::printATECCInfo() const
|
|||||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||||
atecc.readConfigZone(false);
|
atecc.readConfigZone(false);
|
||||||
|
|
||||||
LOG_DEBUG("ATECC608B Serial Number: ");
|
std::string atecc_numbers = "ATECC608B Serial Number: ";
|
||||||
for (int i = 0; i < 9; i++) {
|
for (int i = 0; i < 9; i++) {
|
||||||
LOG_DEBUG("%02x", atecc.serialNumber[i]);
|
atecc_numbers += vformat("%02x", atecc.serialNumber[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG(", Rev Number: ");
|
atecc_numbers += ", Rev Number: ";
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
LOG_DEBUG("%02x", atecc.revisionNumber[i]);
|
atecc_numbers += vformat("%02x", atecc.revisionNumber[i]);
|
||||||
}
|
}
|
||||||
LOG_DEBUG("\n");
|
LOG_DEBUG(atecc_numbers.c_str());
|
||||||
|
|
||||||
LOG_DEBUG("ATECC608B Config %s", atecc.configLockStatus ? "Locked" : "Unlocked");
|
LOG_DEBUG("ATECC608B Config %s, Data %s, Slot 0 %s", atecc.configLockStatus ? "Locked" : "Unlocked",
|
||||||
LOG_DEBUG(", Data %s", atecc.dataOTPLockStatus ? "Locked" : "Unlocked");
|
atecc.dataOTPLockStatus ? "Locked" : "Unlocked", atecc.slot0LockStatus ? "Locked" : "Unlocked");
|
||||||
LOG_DEBUG(", Slot 0 %s\n", atecc.slot0LockStatus ? "Locked" : "Unlocked");
|
|
||||||
|
|
||||||
|
std::string atecc_publickey = "";
|
||||||
if (atecc.configLockStatus && atecc.dataOTPLockStatus && atecc.slot0LockStatus) {
|
if (atecc.configLockStatus && atecc.dataOTPLockStatus && atecc.slot0LockStatus) {
|
||||||
if (atecc.generatePublicKey() == false) {
|
if (atecc.generatePublicKey() == false) {
|
||||||
LOG_DEBUG("ATECC608B Error generating public key\n");
|
atecc_publickey += "ATECC608B Error generating public key";
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("ATECC608B Public Key: ");
|
atecc_publickey += "ATECC608B Public Key: ";
|
||||||
for (int i = 0; i < 64; i++) {
|
for (int i = 0; i < 64; i++) {
|
||||||
LOG_DEBUG("%02x", atecc.publicKey64Bytes[i]);
|
atecc_publickey += vformat("%02x", atecc.publicKey64Bytes[i]);
|
||||||
}
|
}
|
||||||
LOG_DEBUG("\n");
|
|
||||||
}
|
}
|
||||||
|
LOG_DEBUG(atecc_publickey.c_str());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -128,7 +128,7 @@ uint16_t ScanI2CTwoWire::getRegisterValue(const ScanI2CTwoWire::RegisterLocation
|
|||||||
i2cBus->endTransmission();
|
i2cBus->endTransmission();
|
||||||
delay(20);
|
delay(20);
|
||||||
i2cBus->requestFrom(registerLocation.i2cAddress.address, responseWidth);
|
i2cBus->requestFrom(registerLocation.i2cAddress.address, responseWidth);
|
||||||
LOG_DEBUG("Wire.available() = %d\n", i2cBus->available());
|
LOG_DEBUG("Wire.available() = %d", i2cBus->available());
|
||||||
if (i2cBus->available() == 2) {
|
if (i2cBus->available() == 2) {
|
||||||
// Read MSB, then LSB
|
// Read MSB, then LSB
|
||||||
value = (uint16_t)i2cBus->read() << 8;
|
value = (uint16_t)i2cBus->read() << 8;
|
||||||
@@ -149,7 +149,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
{
|
{
|
||||||
concurrency::LockGuard guard((concurrency::Lock *)&lock);
|
concurrency::LockGuard guard((concurrency::Lock *)&lock);
|
||||||
|
|
||||||
LOG_DEBUG("Scanning for I2C devices on port %d\n", port);
|
LOG_DEBUG("Scanning for I2C devices on port %d", port);
|
||||||
|
|
||||||
uint8_t err;
|
uint8_t err;
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
if (asize != 0) {
|
if (asize != 0) {
|
||||||
if (!in_array(address, asize, addr.address))
|
if (!in_array(address, asize, addr.address))
|
||||||
continue;
|
continue;
|
||||||
LOG_DEBUG("Scanning address 0x%x\n", addr.address);
|
LOG_DEBUG("Scanning address 0x%x", addr.address);
|
||||||
}
|
}
|
||||||
i2cBus->beginTransmission(addr.address);
|
i2cBus->beginTransmission(addr.address);
|
||||||
#ifdef ARCH_PORTDUINO
|
#ifdef ARCH_PORTDUINO
|
||||||
@@ -189,7 +189,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
#endif
|
#endif
|
||||||
type = NONE;
|
type = NONE;
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
LOG_DEBUG("I2C device found at address 0x%x\n", addr.address);
|
LOG_DEBUG("I2C device found at address 0x%x", addr.address);
|
||||||
|
|
||||||
switch (addr.address) {
|
switch (addr.address) {
|
||||||
case SSD1306_ADDRESS:
|
case SSD1306_ADDRESS:
|
||||||
@@ -205,9 +205,9 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
LOG_INFO("ATECC608B initialized\n");
|
LOG_INFO("ATECC608B initialized");
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN("ATECC608B initialization failed\n");
|
LOG_WARN("ATECC608B initialization failed");
|
||||||
}
|
}
|
||||||
printATECCInfo();
|
printATECCInfo();
|
||||||
break;
|
break;
|
||||||
@@ -217,7 +217,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
case RV3028_RTC:
|
case RV3028_RTC:
|
||||||
// foundDevices[addr] = RTC_RV3028;
|
// foundDevices[addr] = RTC_RV3028;
|
||||||
type = RTC_RV3028;
|
type = RTC_RV3028;
|
||||||
LOG_INFO("RV3028 RTC found\n");
|
LOG_INFO("RV3028 RTC found");
|
||||||
rtc.initI2C(*i2cBus);
|
rtc.initI2C(*i2cBus);
|
||||||
rtc.writeToRegister(0x35, 0x07); // no Clkout
|
rtc.writeToRegister(0x35, 0x07); // no Clkout
|
||||||
rtc.writeToRegister(0x37, 0xB4);
|
rtc.writeToRegister(0x37, 0xB4);
|
||||||
@@ -225,7 +225,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PCF8563_RTC
|
#ifdef PCF8563_RTC
|
||||||
SCAN_SIMPLE_CASE(PCF8563_RTC, RTC_PCF8563, "PCF8563 RTC found\n")
|
SCAN_SIMPLE_CASE(PCF8563_RTC, RTC_PCF8563, "PCF8563 RTC found")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case CARDKB_ADDR:
|
case CARDKB_ADDR:
|
||||||
@@ -233,49 +233,49 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x04), 1);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x04), 1);
|
||||||
if (registerValue == 0x02) {
|
if (registerValue == 0x02) {
|
||||||
// KEYPAD_VERSION
|
// KEYPAD_VERSION
|
||||||
LOG_INFO("RAK14004 found\n");
|
LOG_INFO("RAK14004 found");
|
||||||
type = RAK14004;
|
type = RAK14004;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("m5 cardKB found\n");
|
LOG_INFO("m5 cardKB found");
|
||||||
type = CARDKB;
|
type = CARDKB;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
SCAN_SIMPLE_CASE(TDECK_KB_ADDR, TDECKKB, "T-Deck keyboard found\n");
|
SCAN_SIMPLE_CASE(TDECK_KB_ADDR, TDECKKB, "T-Deck keyboard found");
|
||||||
SCAN_SIMPLE_CASE(BBQ10_KB_ADDR, BBQ10KB, "BB Q10 keyboard found\n");
|
SCAN_SIMPLE_CASE(BBQ10_KB_ADDR, BBQ10KB, "BB Q10 keyboard found");
|
||||||
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found\n");
|
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found");
|
||||||
#ifdef HAS_NCP5623
|
#ifdef HAS_NCP5623
|
||||||
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found\n");
|
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found");
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_PMU
|
#ifdef HAS_PMU
|
||||||
SCAN_SIMPLE_CASE(XPOWERS_AXP192_AXP2101_ADDRESS, PMU_AXP192_AXP2101, "axp192/axp2101 PMU found\n")
|
SCAN_SIMPLE_CASE(XPOWERS_AXP192_AXP2101_ADDRESS, PMU_AXP192_AXP2101, "axp192/axp2101 PMU found")
|
||||||
#endif
|
#endif
|
||||||
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
|
||||||
switch (registerValue) {
|
switch (registerValue) {
|
||||||
case 0x61:
|
case 0x61:
|
||||||
LOG_INFO("BME-680 sensor found at address 0x%x\n", (uint8_t)addr.address);
|
LOG_INFO("BME-680 sensor found at address 0x%x", (uint8_t)addr.address);
|
||||||
type = BME_680;
|
type = BME_680;
|
||||||
break;
|
break;
|
||||||
case 0x60:
|
case 0x60:
|
||||||
LOG_INFO("BME-280 sensor found at address 0x%x\n", (uint8_t)addr.address);
|
LOG_INFO("BME-280 sensor found at address 0x%x", (uint8_t)addr.address);
|
||||||
type = BME_280;
|
type = BME_280;
|
||||||
break;
|
break;
|
||||||
case 0x55:
|
case 0x55:
|
||||||
LOG_INFO("BMP-085 or BMP-180 sensor found at address 0x%x\n", (uint8_t)addr.address);
|
LOG_INFO("BMP-085 or BMP-180 sensor found at address 0x%x", (uint8_t)addr.address);
|
||||||
type = BMP_085;
|
type = BMP_085;
|
||||||
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) {
|
||||||
case 0x50: // BMP-388 should be 0x50
|
case 0x50: // BMP-388 should be 0x50
|
||||||
LOG_INFO("BMP-388 sensor found at address 0x%x\n", (uint8_t)addr.address);
|
LOG_INFO("BMP-388 sensor found at address 0x%x", (uint8_t)addr.address);
|
||||||
type = BMP_3XX;
|
type = BMP_3XX;
|
||||||
break;
|
break;
|
||||||
case 0x58: // BMP-280 should be 0x58
|
case 0x58: // BMP-280 should be 0x58
|
||||||
default:
|
default:
|
||||||
LOG_INFO("BMP-280 sensor found at address 0x%x\n", (uint8_t)addr.address);
|
LOG_INFO("BMP-280 sensor found at address 0x%x", (uint8_t)addr.address);
|
||||||
type = BMP_280;
|
type = BMP_280;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -284,7 +284,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
break;
|
break;
|
||||||
#ifndef HAS_NCP5623
|
#ifndef HAS_NCP5623
|
||||||
case AHT10_ADDR:
|
case AHT10_ADDR:
|
||||||
LOG_INFO("AHT10 sensor found at address 0x%x\n", (uint8_t)addr.address);
|
LOG_INFO("AHT10 sensor found at address 0x%x", (uint8_t)addr.address);
|
||||||
type = AHT10;
|
type = AHT10;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@@ -292,23 +292,23 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
case INA_ADDR_ALTERNATE:
|
case INA_ADDR_ALTERNATE:
|
||||||
case INA_ADDR_WAVESHARE_UPS:
|
case INA_ADDR_WAVESHARE_UPS:
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
|
||||||
LOG_DEBUG("Register MFG_UID: 0x%x\n", registerValue);
|
LOG_DEBUG("Register MFG_UID: 0x%x", registerValue);
|
||||||
if (registerValue == 0x5449) {
|
if (registerValue == 0x5449) {
|
||||||
LOG_INFO("INA260 sensor found at address 0x%x\n", (uint8_t)addr.address);
|
LOG_INFO("INA260 sensor found at address 0x%x", (uint8_t)addr.address);
|
||||||
type = INA260;
|
type = INA260;
|
||||||
} else { // Assume INA219 if INA260 ID is not found
|
} else { // Assume INA219 if INA260 ID is not found
|
||||||
LOG_INFO("INA219 sensor found at address 0x%x\n", (uint8_t)addr.address);
|
LOG_INFO("INA219 sensor found at address 0x%x", (uint8_t)addr.address);
|
||||||
type = INA219;
|
type = INA219;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INA3221_ADDR:
|
case INA3221_ADDR:
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
|
||||||
LOG_DEBUG("Register MFG_UID: 0x%x\n", registerValue);
|
LOG_DEBUG("Register MFG_UID: 0x%x", registerValue);
|
||||||
if (registerValue == 0x5449) {
|
if (registerValue == 0x5449) {
|
||||||
LOG_INFO("INA3221 sensor found at address 0x%x\n", (uint8_t)addr.address);
|
LOG_INFO("INA3221 sensor found at address 0x%x", (uint8_t)addr.address);
|
||||||
type = INA3221;
|
type = INA3221;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("DFRobot Lark weather station found at address 0x%x\n", (uint8_t)addr.address);
|
LOG_INFO("DFRobot Lark weather station found at address 0x%x", (uint8_t)addr.address);
|
||||||
type = DFROBOT_LARK;
|
type = DFROBOT_LARK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -320,7 +320,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 2);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 2);
|
||||||
if (registerValue == 0x8700) {
|
if (registerValue == 0x8700) {
|
||||||
type = STK8BAXX;
|
type = STK8BAXX;
|
||||||
LOG_INFO("STK8BAXX accelerometer found\n");
|
LOG_INFO("STK8BAXX accelerometer found");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,7 +328,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
|
||||||
if (registerValue == 0x0400) {
|
if (registerValue == 0x0400) {
|
||||||
type = MCP9808;
|
type = MCP9808;
|
||||||
LOG_INFO("MCP9808 sensor found\n");
|
LOG_INFO("MCP9808 sensor found");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +336,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 2);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 2);
|
||||||
if (registerValue == 0x3300 || registerValue == 0x3333) { // RAK4631 WisBlock has LIS3DH register at 0x3333
|
if (registerValue == 0x3300 || registerValue == 0x3333) { // RAK4631 WisBlock has LIS3DH register at 0x3333
|
||||||
type = LIS3DH;
|
type = LIS3DH;
|
||||||
LOG_INFO("LIS3DH accelerometer found\n");
|
LOG_INFO("LIS3DH accelerometer found");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -344,80 +344,95 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
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;
|
||||||
LOG_INFO("SHT4X sensor found\n");
|
LOG_INFO("SHT4X sensor found");
|
||||||
} else if (getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x7E), 2) == 0x5449) {
|
} else if (getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x7E), 2) == 0x5449) {
|
||||||
type = OPT3001;
|
type = OPT3001;
|
||||||
LOG_INFO("OPT3001 light sensor found\n");
|
LOG_INFO("OPT3001 light sensor found");
|
||||||
} else {
|
} else {
|
||||||
type = SHT31;
|
type = SHT31;
|
||||||
LOG_INFO("SHT31 sensor found\n");
|
LOG_INFO("SHT31 sensor found");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
SCAN_SIMPLE_CASE(SHTC3_ADDR, SHTC3, "SHTC3 sensor found\n")
|
SCAN_SIMPLE_CASE(SHTC3_ADDR, SHTC3, "SHTC3 sensor found")
|
||||||
SCAN_SIMPLE_CASE(RCWL9620_ADDR, RCWL9620, "RCWL9620 sensor found\n")
|
case RCWL9620_ADDR:
|
||||||
|
// get MAX30102 PARTID
|
||||||
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFF), 1);
|
||||||
|
if (registerValue == 0x15) {
|
||||||
|
type = MAX30102;
|
||||||
|
LOG_INFO("MAX30102 Health sensor found");
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
type = RCWL9620;
|
||||||
|
LOG_INFO("RCWL9620 sensor found");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case LPS22HB_ADDR_ALT:
|
case LPS22HB_ADDR_ALT:
|
||||||
SCAN_SIMPLE_CASE(LPS22HB_ADDR, LPS22HB, "LPS22HB sensor found\n")
|
SCAN_SIMPLE_CASE(LPS22HB_ADDR, LPS22HB, "LPS22HB sensor found")
|
||||||
|
|
||||||
SCAN_SIMPLE_CASE(QMC6310_ADDR, QMC6310, "QMC6310 Highrate 3-Axis magnetic sensor found\n")
|
SCAN_SIMPLE_CASE(QMC6310_ADDR, QMC6310, "QMC6310 Highrate 3-Axis magnetic sensor found")
|
||||||
|
|
||||||
case QMI8658_ADDR:
|
case QMI8658_ADDR:
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0A), 1); // get ID
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0A), 1); // get ID
|
||||||
if (registerValue == 0xC0) {
|
if (registerValue == 0xC0) {
|
||||||
type = BQ24295;
|
type = BQ24295;
|
||||||
LOG_INFO("BQ24295 PMU found\n");
|
LOG_INFO("BQ24295 PMU found");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 1); // get ID
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 1); // get ID
|
||||||
if (registerValue == 0x6A) {
|
if (registerValue == 0x6A) {
|
||||||
type = LSM6DS3;
|
type = LSM6DS3;
|
||||||
LOG_INFO("LSM6DS3 accelerometer found at address 0x%x\n", (uint8_t)addr.address);
|
LOG_INFO("LSM6DS3 accelerometer found at address 0x%x", (uint8_t)addr.address);
|
||||||
} else {
|
} else {
|
||||||
type = QMI8658;
|
type = QMI8658;
|
||||||
LOG_INFO("QMI8658 Highrate 6-Axis inertial measurement sensor found\n");
|
LOG_INFO("QMI8658 Highrate 6-Axis inertial measurement sensor found");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
SCAN_SIMPLE_CASE(QMC5883L_ADDR, QMC5883L, "QMC5883L Highrate 3-Axis magnetic sensor found\n")
|
SCAN_SIMPLE_CASE(QMC5883L_ADDR, QMC5883L, "QMC5883L Highrate 3-Axis magnetic sensor found")
|
||||||
SCAN_SIMPLE_CASE(HMC5883L_ADDR, HMC5883L, "HMC5883L 3-Axis digital compass found\n")
|
SCAN_SIMPLE_CASE(HMC5883L_ADDR, HMC5883L, "HMC5883L 3-Axis digital compass found")
|
||||||
SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found\n")
|
SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found")
|
||||||
SCAN_SIMPLE_CASE(BMA423_ADDR, BMA423, "BMA423 accelerometer found\n");
|
SCAN_SIMPLE_CASE(BMA423_ADDR, BMA423, "BMA423 accelerometer found");
|
||||||
SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3 accelerometer found at address 0x%x\n", (uint8_t)addr.address);
|
SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3 accelerometer found at address 0x%x", (uint8_t)addr.address);
|
||||||
SCAN_SIMPLE_CASE(TCA9535_ADDR, TCA9535, "TCA9535 I2C expander found\n");
|
SCAN_SIMPLE_CASE(TCA9535_ADDR, TCA9535, "TCA9535 I2C expander found");
|
||||||
SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555 I2C expander found\n");
|
SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555 I2C expander found");
|
||||||
SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700 light sensor found\n");
|
SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700 light sensor found");
|
||||||
SCAN_SIMPLE_CASE(TSL25911_ADDR, TSL2591, "TSL2591 light sensor found\n");
|
SCAN_SIMPLE_CASE(TSL25911_ADDR, TSL2591, "TSL2591 light sensor found");
|
||||||
SCAN_SIMPLE_CASE(OPT3001_ADDR, OPT3001, "OPT3001 light sensor found\n");
|
SCAN_SIMPLE_CASE(OPT3001_ADDR, OPT3001, "OPT3001 light sensor found");
|
||||||
SCAN_SIMPLE_CASE(MLX90632_ADDR, MLX90632, "MLX90632 IR temp sensor found\n");
|
SCAN_SIMPLE_CASE(MLX90632_ADDR, MLX90632, "MLX90632 IR temp sensor found");
|
||||||
SCAN_SIMPLE_CASE(NAU7802_ADDR, NAU7802, "NAU7802 based scale found\n");
|
SCAN_SIMPLE_CASE(NAU7802_ADDR, NAU7802, "NAU7802 based scale found");
|
||||||
SCAN_SIMPLE_CASE(FT6336U_ADDR, FT6336U, "FT6336U touchscreen found\n");
|
SCAN_SIMPLE_CASE(FT6336U_ADDR, FT6336U, "FT6336U touchscreen found");
|
||||||
SCAN_SIMPLE_CASE(MAX1704X_ADDR, MAX17048, "MAX17048 lipo fuel gauge found\n");
|
SCAN_SIMPLE_CASE(MAX1704X_ADDR, MAX17048, "MAX17048 lipo fuel gauge found");
|
||||||
|
#ifdef HAS_TPS65233
|
||||||
|
SCAN_SIMPLE_CASE(TPS65233_ADDR, TPS65233, "TPS65233 BIAS-T found");
|
||||||
|
#endif
|
||||||
|
SCAN_SIMPLE_CASE(MLX90614_ADDR_DEF, MLX90614, "MLX90614 IR temp sensor found");
|
||||||
|
|
||||||
case ICM20948_ADDR: // same as BMX160_ADDR
|
case ICM20948_ADDR: // same as BMX160_ADDR
|
||||||
case ICM20948_ADDR_ALT: // same as MPU6050_ADDR
|
case ICM20948_ADDR_ALT: // same as MPU6050_ADDR
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1);
|
||||||
if (registerValue == 0xEA) {
|
if (registerValue == 0xEA) {
|
||||||
type = ICM20948;
|
type = ICM20948;
|
||||||
LOG_INFO("ICM20948 9-dof motion processor found\n");
|
LOG_INFO("ICM20948 9-dof motion processor found");
|
||||||
break;
|
break;
|
||||||
} else if (addr.address == BMX160_ADDR) {
|
} else if (addr.address == BMX160_ADDR) {
|
||||||
type = BMX160;
|
type = BMX160;
|
||||||
LOG_INFO("BMX160 accelerometer found\n");
|
LOG_INFO("BMX160 accelerometer found");
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
type = MPU6050;
|
type = MPU6050;
|
||||||
LOG_INFO("MPU6050 accelerometer found\n");
|
LOG_INFO("MPU6050 accelerometer found");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address);
|
LOG_INFO("Device found at address 0x%x was not able to be enumerated", addr.address);
|
||||||
}
|
}
|
||||||
} else if (err == 4) {
|
} else if (err == 4) {
|
||||||
LOG_ERROR("Unknown error at address 0x%x\n", addr.address);
|
LOG_ERROR("Unknown error at address 0x%x", addr.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a type was found for the enumerated device - save, if so
|
// Check if a type was found for the enumerated device - save, if so
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
uint32_t axpDebugRead()
|
uint32_t axpDebugRead()
|
||||||
{
|
{
|
||||||
axp.debugCharging();
|
axp.debugCharging();
|
||||||
LOG_DEBUG("vbus current %f\n", axp.getVbusCurrent());
|
LOG_DEBUG("vbus current %f", axp.getVbusCurrent());
|
||||||
LOG_DEBUG("charge current %f\n", axp.getBattChargeCurrent());
|
LOG_DEBUG("charge current %f", axp.getBattChargeCurrent());
|
||||||
LOG_DEBUG("bat voltage %f\n", axp.getBattVoltage());
|
LOG_DEBUG("bat voltage %f", axp.getBattVoltage());
|
||||||
LOG_DEBUG("batt pct %d\n", axp.getBattPercentage());
|
LOG_DEBUG("batt pct %d", axp.getBattPercentage());
|
||||||
LOG_DEBUG("is battery connected %d\n", axp.isBatteryConnect());
|
LOG_DEBUG("is battery connected %d", axp.isBatteryConnect());
|
||||||
LOG_DEBUG("is USB connected %d\n", axp.isVBUSPlug());
|
LOG_DEBUG("is USB connected %d", axp.isVBUSPlug());
|
||||||
LOG_DEBUG("is charging %d\n", axp.isChargeing());
|
LOG_DEBUG("is charging %d", axp.isChargeing());
|
||||||
|
|
||||||
return 30 * 1000;
|
return 30 * 1000;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,9 +59,9 @@ void scanEInkDevice(void)
|
|||||||
d_writeCommand(0x20);
|
d_writeCommand(0x20);
|
||||||
eink_found = (d_waitWhileBusy(150) > 0) ? true : false;
|
eink_found = (d_waitWhileBusy(150) > 0) ? true : false;
|
||||||
if (eink_found)
|
if (eink_found)
|
||||||
LOG_DEBUG("EInk display found\n");
|
LOG_DEBUG("EInk display found");
|
||||||
else
|
else
|
||||||
LOG_DEBUG("EInk display not found\n");
|
LOG_DEBUG("EInk display not found");
|
||||||
SPI1.end();
|
SPI1.end();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
306
src/gps/GPS.cpp
@@ -154,7 +154,7 @@ uint8_t GPS::makeCASPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_siz
|
|||||||
CASChecksum(UBXscratch, (payload_size + 10));
|
CASChecksum(UBXscratch, (payload_size + 10));
|
||||||
|
|
||||||
#if defined(GPS_DEBUG) && defined(DEBUG_PORT)
|
#if defined(GPS_DEBUG) && defined(DEBUG_PORT)
|
||||||
LOG_DEBUG("Constructed CAS packet: \n");
|
LOG_DEBUG("Constructed CAS packet: ");
|
||||||
DEBUG_PORT.hexDump(MESHTASTIC_LOG_LEVEL_DEBUG, UBXscratch, payload_size + 10);
|
DEBUG_PORT.hexDump(MESHTASTIC_LOG_LEVEL_DEBUG, UBXscratch, payload_size + 10);
|
||||||
#endif
|
#endif
|
||||||
return (payload_size + 10);
|
return (payload_size + 10);
|
||||||
@@ -166,33 +166,33 @@ GPS_RESPONSE GPS::getACK(const char *message, uint32_t waitMillis)
|
|||||||
uint8_t b;
|
uint8_t b;
|
||||||
int bytesRead = 0;
|
int bytesRead = 0;
|
||||||
uint32_t startTimeout = millis() + waitMillis;
|
uint32_t startTimeout = millis() + waitMillis;
|
||||||
|
#ifdef GPS_DEBUG
|
||||||
|
std::string debugmsg = "";
|
||||||
|
#endif
|
||||||
while (millis() < startTimeout) {
|
while (millis() < startTimeout) {
|
||||||
if (_serial_gps->available()) {
|
if (_serial_gps->available()) {
|
||||||
b = _serial_gps->read();
|
b = _serial_gps->read();
|
||||||
|
|
||||||
#ifdef GPS_DEBUG
|
#ifdef GPS_DEBUG
|
||||||
LOG_DEBUG("%c", (b >= 32 && b <= 126) ? b : '.');
|
debugmsg += vformat("%c", (b >= 32 && b <= 126) ? b : '.');
|
||||||
#endif
|
#endif
|
||||||
buffer[bytesRead] = b;
|
buffer[bytesRead] = b;
|
||||||
bytesRead++;
|
bytesRead++;
|
||||||
if ((bytesRead == 767) || (b == '\r')) {
|
if ((bytesRead == 767) || (b == '\r')) {
|
||||||
if (strnstr((char *)buffer, message, bytesRead) != nullptr) {
|
if (strnstr((char *)buffer, message, bytesRead) != nullptr) {
|
||||||
#ifdef GPS_DEBUG
|
#ifdef GPS_DEBUG
|
||||||
LOG_DEBUG("\r\nFound: %s\r\n", message); // Log the found message
|
LOG_DEBUG("Found: %s", message); // Log the found message
|
||||||
#endif
|
#endif
|
||||||
return GNSS_RESPONSE_OK;
|
return GNSS_RESPONSE_OK;
|
||||||
} else {
|
} else {
|
||||||
bytesRead = 0;
|
bytesRead = 0;
|
||||||
#ifdef GPS_DEBUG
|
#ifdef GPS_DEBUG
|
||||||
LOG_DEBUG("\r\n");
|
LOG_DEBUG(debugmsg.c_str());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef GPS_DEBUG
|
|
||||||
LOG_DEBUG("\n");
|
|
||||||
#endif
|
|
||||||
return GNSS_RESPONSE_NONE;
|
return GNSS_RESPONSE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,7 +235,7 @@ GPS_RESPONSE GPS::getACKCas(uint8_t class_id, uint8_t msg_id, uint32_t waitMilli
|
|||||||
// Check for an ACK-ACK for the specified class and message id
|
// Check for an ACK-ACK for the specified class and message id
|
||||||
if ((msg_cls == 0x05) && (msg_msg_id == 0x01) && payload_cls == class_id && payload_msg == msg_id) {
|
if ((msg_cls == 0x05) && (msg_msg_id == 0x01) && payload_cls == class_id && payload_msg == msg_id) {
|
||||||
#ifdef GPS_DEBUG
|
#ifdef GPS_DEBUG
|
||||||
LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", class_id, msg_id, millis() - startTime);
|
LOG_INFO("Got ACK for class %02X message %02X in %d millis.", class_id, msg_id, millis() - startTime);
|
||||||
#endif
|
#endif
|
||||||
return GNSS_RESPONSE_OK;
|
return GNSS_RESPONSE_OK;
|
||||||
}
|
}
|
||||||
@@ -243,7 +243,7 @@ GPS_RESPONSE GPS::getACKCas(uint8_t class_id, uint8_t msg_id, uint32_t waitMilli
|
|||||||
// Check for an ACK-NACK for the specified class and message id
|
// Check for an ACK-NACK for the specified class and message id
|
||||||
if ((msg_cls == 0x05) && (msg_msg_id == 0x00) && payload_cls == class_id && payload_msg == msg_id) {
|
if ((msg_cls == 0x05) && (msg_msg_id == 0x00) && payload_cls == class_id && payload_msg == msg_id) {
|
||||||
#ifdef GPS_DEBUG
|
#ifdef GPS_DEBUG
|
||||||
LOG_WARN("Got NACK for class %02X message %02X in %d millis.\n", class_id, msg_id, millis() - startTime);
|
LOG_WARN("Got NACK for class %02X message %02X in %d millis.", class_id, msg_id, millis() - startTime);
|
||||||
#endif
|
#endif
|
||||||
return GNSS_RESPONSE_NAK;
|
return GNSS_RESPONSE_NAK;
|
||||||
}
|
}
|
||||||
@@ -281,8 +281,8 @@ GPS_RESPONSE GPS::getACK(uint8_t class_id, uint8_t msg_id, uint32_t waitMillis)
|
|||||||
while (Throttle::isWithinTimespanMs(startTime, waitMillis)) {
|
while (Throttle::isWithinTimespanMs(startTime, waitMillis)) {
|
||||||
if (ack > 9) {
|
if (ack > 9) {
|
||||||
#ifdef GPS_DEBUG
|
#ifdef GPS_DEBUG
|
||||||
LOG_DEBUG("\n");
|
LOG_DEBUG("");
|
||||||
LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", class_id, msg_id, millis() - startTime);
|
LOG_INFO("Got ACK for class %02X message %02X in %d millis.", class_id, msg_id, millis() - startTime);
|
||||||
#endif
|
#endif
|
||||||
return GNSS_RESPONSE_OK; // ACK received
|
return GNSS_RESPONSE_OK; // ACK received
|
||||||
}
|
}
|
||||||
@@ -304,9 +304,9 @@ GPS_RESPONSE GPS::getACK(uint8_t class_id, uint8_t msg_id, uint32_t waitMillis)
|
|||||||
} else {
|
} else {
|
||||||
if (ack == 3 && b == 0x00) { // UBX-ACK-NAK message
|
if (ack == 3 && b == 0x00) { // UBX-ACK-NAK message
|
||||||
#ifdef GPS_DEBUG
|
#ifdef GPS_DEBUG
|
||||||
LOG_DEBUG("\n");
|
LOG_DEBUG("");
|
||||||
#endif
|
#endif
|
||||||
LOG_WARN("Got NAK for class %02X message %02X\n", class_id, msg_id);
|
LOG_WARN("Got NAK for class %02X message %02X", class_id, msg_id);
|
||||||
return GNSS_RESPONSE_NAK; // NAK received
|
return GNSS_RESPONSE_NAK; // NAK received
|
||||||
}
|
}
|
||||||
ack = 0; // Reset the acknowledgement counter
|
ack = 0; // Reset the acknowledgement counter
|
||||||
@@ -314,8 +314,8 @@ GPS_RESPONSE GPS::getACK(uint8_t class_id, uint8_t msg_id, uint32_t waitMillis)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef GPS_DEBUG
|
#ifdef GPS_DEBUG
|
||||||
LOG_DEBUG("\n");
|
LOG_DEBUG("");
|
||||||
LOG_WARN("No response for class %02X message %02X\n", class_id, msg_id);
|
LOG_WARN("No response for class %02X message %02X", class_id, msg_id);
|
||||||
#endif
|
#endif
|
||||||
return GNSS_RESPONSE_NONE; // No response received within timeout
|
return GNSS_RESPONSE_NONE; // No response received within timeout
|
||||||
}
|
}
|
||||||
@@ -388,7 +388,7 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
|
|||||||
} else {
|
} else {
|
||||||
// return payload length
|
// return payload length
|
||||||
#ifdef GPS_DEBUG
|
#ifdef GPS_DEBUG
|
||||||
LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", requestedClass, requestedID,
|
LOG_INFO("Got ACK for class %02X message %02X in %d millis.", requestedClass, requestedID,
|
||||||
millis() - startTime);
|
millis() - startTime);
|
||||||
#endif
|
#endif
|
||||||
return needRead;
|
return needRead;
|
||||||
@@ -400,7 +400,7 @@ int GPS::getACK(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// LOG_WARN("No response for class %02X message %02X\n", requestedClass, requestedID);
|
// LOG_WARN("No response for class %02X message %02X", requestedClass, requestedID);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,13 +416,13 @@ bool GPS::setup()
|
|||||||
speedSelect = std::find(serialSpeeds, std::end(serialSpeeds), GPS_BAUDRATE) - serialSpeeds;
|
speedSelect = std::find(serialSpeeds, std::end(serialSpeeds), GPS_BAUDRATE) - serialSpeeds;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("Probing for GPS at %d \n", serialSpeeds[speedSelect]);
|
LOG_DEBUG("Probing for GPS at %d", serialSpeeds[speedSelect]);
|
||||||
gnssModel = probe(serialSpeeds[speedSelect]);
|
gnssModel = probe(serialSpeeds[speedSelect]);
|
||||||
if (gnssModel == GNSS_MODEL_UNKNOWN) {
|
if (gnssModel == GNSS_MODEL_UNKNOWN) {
|
||||||
if (++speedSelect == sizeof(serialSpeeds) / sizeof(int)) {
|
if (++speedSelect == sizeof(serialSpeeds) / sizeof(int)) {
|
||||||
speedSelect = 0;
|
speedSelect = 0;
|
||||||
if (--probeTries == 0) {
|
if (--probeTries == 0) {
|
||||||
LOG_WARN("Giving up on GPS probe and setting to 9600.\n");
|
LOG_WARN("Giving up on GPS probe and setting to 9600.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -491,15 +491,15 @@ bool GPS::setup()
|
|||||||
msglen = makeCASPacket(0x06, 0x01, sizeof(cas_cfg_msg_packet), cas_cfg_msg_packet);
|
msglen = makeCASPacket(0x06, 0x01, sizeof(cas_cfg_msg_packet), cas_cfg_msg_packet);
|
||||||
_serial_gps->write(UBXscratch, msglen);
|
_serial_gps->write(UBXscratch, msglen);
|
||||||
if (getACKCas(0x06, 0x01, 250) != GNSS_RESPONSE_OK) {
|
if (getACKCas(0x06, 0x01, 250) != GNSS_RESPONSE_OK) {
|
||||||
LOG_WARN("ATGM336H - Could not enable NMEA MSG: %d\n", fields[i]);
|
LOG_WARN("ATGM336H - Could not enable NMEA MSG: %d", fields[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (gnssModel == GNSS_MODEL_UC6580) {
|
} else if (gnssModel == GNSS_MODEL_UC6580) {
|
||||||
// The Unicore UC6580 can use a lot of sat systems, enable it to
|
// The Unicore UC6580 can use a lot of sat systems, enable it to
|
||||||
// use GPS L1 & L5 + BDS B1I & B2a + GLONASS L1 + GALILEO E1 & E5a + SBAS
|
// use GPS L1 & L5 + BDS B1I & B2a + GLONASS L1 + GALILEO E1 & E5a + SBAS + QZSS
|
||||||
// This will reset the receiver, so wait a bit afterwards
|
// This will reset the receiver, so wait a bit afterwards
|
||||||
// The paranoid will wait for the OK*04 confirmation response after each command.
|
// The paranoid will wait for the OK*04 confirmation response after each command.
|
||||||
_serial_gps->write("$CFGSYS,h25155\r\n");
|
_serial_gps->write("$CFGSYS,h35155\r\n");
|
||||||
delay(750);
|
delay(750);
|
||||||
// Must be done after the CFGSYS command
|
// Must be done after the CFGSYS command
|
||||||
// Turn off GSV messages, we don't really care about which and where the sats are, maybe someday.
|
// Turn off GSV messages, we don't really care about which and where the sats are, maybe someday.
|
||||||
@@ -530,34 +530,34 @@ bool GPS::setup()
|
|||||||
_serial_gps->write("$PAIR513*3D\r\n"); // save configuration
|
_serial_gps->write("$PAIR513*3D\r\n"); // save configuration
|
||||||
} else if (gnssModel == GNSS_MODEL_UBLOX6) {
|
} else if (gnssModel == GNSS_MODEL_UBLOX6) {
|
||||||
clearBuffer();
|
clearBuffer();
|
||||||
SEND_UBX_PACKET(0x06, 0x02, _message_DISABLE_TXT_INFO, "Unable to disable text info messages.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x02, _message_DISABLE_TXT_INFO, "disable text info messages", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x39, _message_JAM_6_7, "Unable to enable interference resistance.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x39, _message_JAM_6_7, "enable interference resistance", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x23, _message_NAVX5, "Unable to configure NAVX5 settings.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x23, _message_NAVX5, "configure NAVX5 settings", 500);
|
||||||
|
|
||||||
// Turn off unwanted NMEA messages, set update rate
|
// Turn off unwanted NMEA messages, set update rate
|
||||||
SEND_UBX_PACKET(0x06, 0x08, _message_1HZ, "Unable to set GPS update rate.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x08, _message_1HZ, "set GPS update rate", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x01, _message_GLL, "Unable to disable NMEA GLL.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x01, _message_GLL, "disable NMEA GLL", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x01, _message_GSA, "Unable to Enable NMEA GSA.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x01, _message_GSA, "enable NMEA GSA", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x01, _message_GSV, "Unable to disable NMEA GSV.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x01, _message_GSV, "disable NMEA GSV", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x01, _message_VTG, "Unable to disable NMEA VTG.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x01, _message_VTG, "disable NMEA VTG", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x01, _message_RMC, "Unable to enable NMEA RMC.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x01, _message_RMC, "enable NMEA RMC", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x01, _message_GGA, "Unable to enable NMEA GGA.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x01, _message_GGA, "enable NMEA GGA", 500);
|
||||||
|
|
||||||
clearBuffer();
|
clearBuffer();
|
||||||
SEND_UBX_PACKET(0x06, 0x11, _message_CFG_RXM_ECO, "Unable to enable powersaving ECO mode for Neo-6.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x11, _message_CFG_RXM_ECO, "enable powersaving ECO mode for Neo-6", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x3B, _message_CFG_PM2, "Unable to enable powersaving details for GPS.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x3B, _message_CFG_PM2, "enable powersaving details for GPS", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x01, _message_AID, "Unable to disable UBX-AID.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x01, _message_AID, "disable UBX-AID", 500);
|
||||||
|
|
||||||
msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE), _message_SAVE);
|
msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE), _message_SAVE);
|
||||||
_serial_gps->write(UBXscratch, msglen);
|
_serial_gps->write(UBXscratch, msglen);
|
||||||
if (getACK(0x06, 0x09, 2000) != GNSS_RESPONSE_OK) {
|
if (getACK(0x06, 0x09, 2000) != GNSS_RESPONSE_OK) {
|
||||||
LOG_WARN("Unable to save GNSS module configuration.\n");
|
LOG_WARN("Unable to save GNSS module configuration.");
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("GNSS module configuration saved!\n");
|
LOG_INFO("GNSS module configuration saved!");
|
||||||
}
|
}
|
||||||
} else if (IS_ONE_OF(gnssModel, GNSS_MODEL_UBLOX7, GNSS_MODEL_UBLOX8, GNSS_MODEL_UBLOX9)) {
|
} else if (IS_ONE_OF(gnssModel, GNSS_MODEL_UBLOX7, GNSS_MODEL_UBLOX8, GNSS_MODEL_UBLOX9)) {
|
||||||
if (gnssModel == GNSS_MODEL_UBLOX7) {
|
if (gnssModel == GNSS_MODEL_UBLOX7) {
|
||||||
LOG_DEBUG("Setting GPS+SBAS\n");
|
LOG_DEBUG("Setting GPS+SBAS");
|
||||||
msglen = makeUBXPacket(0x06, 0x3e, sizeof(_message_GNSS_7), _message_GNSS_7);
|
msglen = makeUBXPacket(0x06, 0x3e, sizeof(_message_GNSS_7), _message_GNSS_7);
|
||||||
_serial_gps->write(UBXscratch, msglen);
|
_serial_gps->write(UBXscratch, msglen);
|
||||||
} else { // 8,9
|
} else { // 8,9
|
||||||
@@ -567,12 +567,12 @@ bool GPS::setup()
|
|||||||
|
|
||||||
if (getACK(0x06, 0x3e, 800) == GNSS_RESPONSE_NAK) {
|
if (getACK(0x06, 0x3e, 800) == GNSS_RESPONSE_NAK) {
|
||||||
// It's not critical if the module doesn't acknowledge this configuration.
|
// It's not critical if the module doesn't acknowledge this configuration.
|
||||||
LOG_INFO("Unable to reconfigure GNSS - defaults maintained. Is this module GPS-only?\n");
|
LOG_INFO("reconfigure GNSS - defaults maintained. Is this module GPS-only?");
|
||||||
} else {
|
} else {
|
||||||
if (gnssModel == GNSS_MODEL_UBLOX7) {
|
if (gnssModel == GNSS_MODEL_UBLOX7) {
|
||||||
LOG_INFO("GNSS configured for GPS+SBAS.\n");
|
LOG_INFO("GNSS configured for GPS+SBAS.");
|
||||||
} else { // 8,9
|
} else { // 8,9
|
||||||
LOG_INFO("GNSS configured for GPS+SBAS+GLONASS+Galileo.\n");
|
LOG_INFO("GNSS configured for GPS+SBAS+GLONASS+Galileo.");
|
||||||
}
|
}
|
||||||
// Documentation say, we need wait atleast 0.5s after reconfiguration of GNSS module, before sending next
|
// Documentation say, we need wait atleast 0.5s after reconfiguration of GNSS module, before sending next
|
||||||
// commands for the M8 it tends to be more... 1 sec should be enough ;>)
|
// commands for the M8 it tends to be more... 1 sec should be enough ;>)
|
||||||
@@ -581,86 +581,84 @@ bool GPS::setup()
|
|||||||
|
|
||||||
// Disable Text Info messages //6,7,8,9
|
// Disable Text Info messages //6,7,8,9
|
||||||
clearBuffer();
|
clearBuffer();
|
||||||
SEND_UBX_PACKET(0x06, 0x02, _message_DISABLE_TXT_INFO, "Unable to disable text info messages.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x02, _message_DISABLE_TXT_INFO, "disable text info messages", 500);
|
||||||
|
|
||||||
if (gnssModel == GNSS_MODEL_UBLOX8) { // 8
|
if (gnssModel == GNSS_MODEL_UBLOX8) { // 8
|
||||||
clearBuffer();
|
clearBuffer();
|
||||||
SEND_UBX_PACKET(0x06, 0x39, _message_JAM_8, "Unable to enable interference resistance.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x39, _message_JAM_8, "enable interference resistance", 500);
|
||||||
|
|
||||||
clearBuffer();
|
clearBuffer();
|
||||||
SEND_UBX_PACKET(0x06, 0x23, _message_NAVX5_8, "Unable to configure NAVX5_8 settings.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x23, _message_NAVX5_8, "configure NAVX5_8 settings", 500);
|
||||||
} else { // 6,7,9
|
} else { // 6,7,9
|
||||||
SEND_UBX_PACKET(0x06, 0x39, _message_JAM_6_7, "Unable to enable interference resistance.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x39, _message_JAM_6_7, "enable interference resistance", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x23, _message_NAVX5, "Unable to configure NAVX5 settings.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x23, _message_NAVX5, "configure NAVX5 settings", 500);
|
||||||
}
|
}
|
||||||
// Turn off unwanted NMEA messages, set update rate
|
// Turn off unwanted NMEA messages, set update rate
|
||||||
SEND_UBX_PACKET(0x06, 0x08, _message_1HZ, "Unable to set GPS update rate.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x08, _message_1HZ, "set GPS update rate", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x01, _message_GLL, "Unable to disable NMEA GLL.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x01, _message_GLL, "disable NMEA GLL", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x01, _message_GSA, "Unable to Enable NMEA GSA.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x01, _message_GSA, "enable NMEA GSA", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x01, _message_GSV, "Unable to disable NMEA GSV.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x01, _message_GSV, "disable NMEA GSV", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x01, _message_VTG, "Unable to disable NMEA VTG.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x01, _message_VTG, "disable NMEA VTG", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x01, _message_RMC, "Unable to enable NMEA RMC.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x01, _message_RMC, "enable NMEA RMC", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x01, _message_GGA, "Unable to enable NMEA GGA.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x01, _message_GGA, "enable NMEA GGA", 500);
|
||||||
|
|
||||||
if (uBloxProtocolVersion >= 18) {
|
if (uBloxProtocolVersion >= 18) {
|
||||||
clearBuffer();
|
clearBuffer();
|
||||||
SEND_UBX_PACKET(0x06, 0x86, _message_PMS, "Unable to enable powersaving for GPS.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x86, _message_PMS, "enable powersaving for GPS", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x3B, _message_CFG_PM2, "Unable to enable powersaving details for GPS.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x3B, _message_CFG_PM2, "enable powersaving details for GPS", 500);
|
||||||
|
|
||||||
// For M8 we want to enable NMEA vserion 4.10 so we can see the additional sats.
|
// For M8 we want to enable NMEA vserion 4.10 so we can see the additional sats.
|
||||||
if (gnssModel == GNSS_MODEL_UBLOX8) {
|
if (gnssModel == GNSS_MODEL_UBLOX8) {
|
||||||
clearBuffer();
|
clearBuffer();
|
||||||
SEND_UBX_PACKET(0x06, 0x17, _message_NMEA, "Unable to enable NMEA 4.10.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x17, _message_NMEA, "enable NMEA 4.10", 500);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SEND_UBX_PACKET(0x06, 0x11, _message_CFG_RXM_PSM, "Unable to enable powersaving mode for GPS.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x11, _message_CFG_RXM_PSM, "enable powersaving mode for GPS", 500);
|
||||||
SEND_UBX_PACKET(0x06, 0x3B, _message_CFG_PM2, "Unable to enable powersaving details for GPS.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x3B, _message_CFG_PM2, "enable powersaving details for GPS", 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE), _message_SAVE);
|
msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE), _message_SAVE);
|
||||||
_serial_gps->write(UBXscratch, msglen);
|
_serial_gps->write(UBXscratch, msglen);
|
||||||
if (getACK(0x06, 0x09, 2000) != GNSS_RESPONSE_OK) {
|
if (getACK(0x06, 0x09, 2000) != GNSS_RESPONSE_OK) {
|
||||||
LOG_WARN("Unable to save GNSS module configuration.\n");
|
LOG_WARN("Unable to save GNSS module configuration.");
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("GNSS module configuration saved!\n");
|
LOG_INFO("GNSS module configuration saved!");
|
||||||
}
|
}
|
||||||
} else if (gnssModel == GNSS_MODEL_UBLOX10) {
|
} else if (gnssModel == GNSS_MODEL_UBLOX10) {
|
||||||
delay(1000);
|
delay(1000);
|
||||||
clearBuffer();
|
clearBuffer();
|
||||||
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_NMEA_RAM, "Unable to disable NMEA messages in M10 RAM.\n", 300);
|
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_NMEA_RAM, "disable NMEA messages in M10 RAM", 300);
|
||||||
delay(750);
|
delay(750);
|
||||||
clearBuffer();
|
clearBuffer();
|
||||||
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_NMEA_BBR, "Unable to disable NMEA messages in M10 BBR.\n", 300);
|
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_NMEA_BBR, "disable NMEA messages in M10 BBR", 300);
|
||||||
delay(750);
|
delay(750);
|
||||||
clearBuffer();
|
clearBuffer();
|
||||||
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_TXT_INFO_RAM,
|
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_TXT_INFO_RAM, "disable Info messages for M10 GPS RAM", 300);
|
||||||
"Unable to disable Info messages for M10 GPS RAM.\n", 300);
|
|
||||||
delay(750);
|
delay(750);
|
||||||
// Next disable Info txt messages in BBR layer
|
// Next disable Info txt messages in BBR layer
|
||||||
clearBuffer();
|
clearBuffer();
|
||||||
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_TXT_INFO_BBR,
|
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_TXT_INFO_BBR, "disable Info messages for M10 GPS BBR", 300);
|
||||||
"Unable to disable Info messages for M10 GPS BBR.\n", 300);
|
|
||||||
delay(750);
|
delay(750);
|
||||||
// Do M10 configuration for Power Management.
|
// Do M10 configuration for Power Management.
|
||||||
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_PM_RAM, "Unable to enable powersaving for M10 GPS RAM.\n", 300);
|
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_PM_RAM, "enable powersaving for M10 GPS RAM", 300);
|
||||||
delay(750);
|
delay(750);
|
||||||
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_PM_BBR, "Unable to enable powersaving for M10 GPS BBR.\n", 300);
|
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_PM_BBR, "enable powersaving for M10 GPS BBR", 300);
|
||||||
delay(750);
|
delay(750);
|
||||||
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ITFM_RAM, "Unable to enable Jamming detection M10 GPS RAM.\n", 300);
|
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ITFM_RAM, "enable Jamming detection M10 GPS RAM", 300);
|
||||||
delay(750);
|
delay(750);
|
||||||
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ITFM_BBR, "Unable to enable Jamming detection M10 GPS BBR.\n", 300);
|
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ITFM_BBR, "enable Jamming detection M10 GPS BBR", 300);
|
||||||
delay(750);
|
delay(750);
|
||||||
// Here is where the init commands should go to do further M10 initialization.
|
// Here is where the init commands should go to do further M10 initialization.
|
||||||
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_SBAS_RAM, "Unable to disable SBAS M10 GPS RAM.\n", 300);
|
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_SBAS_RAM, "disable SBAS M10 GPS RAM", 300);
|
||||||
delay(750); // will cause a receiver restart so wait a bit
|
delay(750); // will cause a receiver restart so wait a bit
|
||||||
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_SBAS_BBR, "Unable to disable SBAS M10 GPS BBR.\n", 300);
|
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_DISABLE_SBAS_BBR, "disable SBAS M10 GPS BBR", 300);
|
||||||
delay(750); // will cause a receiver restart so wait a bit
|
delay(750); // will cause a receiver restart so wait a bit
|
||||||
|
|
||||||
// Done with initialization, Now enable wanted NMEA messages in BBR layer so they will survive a periodic sleep.
|
// Done with initialization, Now enable wanted NMEA messages in BBR layer so they will survive a periodic sleep.
|
||||||
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ENABLE_NMEA_BBR, "Unable to enable messages for M10 GPS BBR.\n", 300);
|
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ENABLE_NMEA_BBR, "enable messages for M10 GPS BBR", 300);
|
||||||
delay(750);
|
delay(750);
|
||||||
// Next enable wanted NMEA messages in RAM layer
|
// Next enable wanted NMEA messages in RAM layer
|
||||||
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ENABLE_NMEA_RAM, "Unable to enable messages for M10 GPS RAM.\n", 500);
|
SEND_UBX_PACKET(0x06, 0x8A, _message_VALSET_ENABLE_NMEA_RAM, "enable messages for M10 GPS RAM", 500);
|
||||||
delay(750);
|
delay(750);
|
||||||
|
|
||||||
// As the M10 has no flash, the best we can do to preserve the config is to set it in RAM and BBR.
|
// As the M10 has no flash, the best we can do to preserve the config is to set it in RAM and BBR.
|
||||||
@@ -669,9 +667,9 @@ bool GPS::setup()
|
|||||||
msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE_10), _message_SAVE_10);
|
msglen = makeUBXPacket(0x06, 0x09, sizeof(_message_SAVE_10), _message_SAVE_10);
|
||||||
_serial_gps->write(UBXscratch, msglen);
|
_serial_gps->write(UBXscratch, msglen);
|
||||||
if (getACK(0x06, 0x09, 2000) != GNSS_RESPONSE_OK) {
|
if (getACK(0x06, 0x09, 2000) != GNSS_RESPONSE_OK) {
|
||||||
LOG_WARN("Unable to save GNSS module configuration.\n");
|
LOG_WARN("Unable to save GNSS module configuration.");
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("GNSS module configuration saved!\n");
|
LOG_INFO("GNSS module configuration saved!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
didSerialInit = true;
|
didSerialInit = true;
|
||||||
@@ -693,7 +691,7 @@ void GPS::setPowerState(GPSPowerState newState, uint32_t sleepTime)
|
|||||||
// Update the stored GPSPowerstate, and create local copies
|
// Update the stored GPSPowerstate, and create local copies
|
||||||
GPSPowerState oldState = powerState;
|
GPSPowerState oldState = powerState;
|
||||||
powerState = newState;
|
powerState = newState;
|
||||||
LOG_INFO("GPS power state moving from %s to %s\n", getGPSPowerStateString(oldState), getGPSPowerStateString(newState));
|
LOG_INFO("GPS power state moving from %s to %s", getGPSPowerStateString(oldState), getGPSPowerStateString(newState));
|
||||||
|
|
||||||
#ifdef HELTEC_MESH_NODE_T114
|
#ifdef HELTEC_MESH_NODE_T114
|
||||||
if ((oldState == GPS_OFF || oldState == GPS_HARDSLEEP) && (newState != GPS_OFF && newState != GPS_HARDSLEEP)) {
|
if ((oldState == GPS_OFF || oldState == GPS_HARDSLEEP) && (newState != GPS_OFF && newState != GPS_HARDSLEEP)) {
|
||||||
@@ -763,7 +761,7 @@ void GPS::writePinEN(bool on)
|
|||||||
// Write and log
|
// Write and log
|
||||||
enablePin->set(on);
|
enablePin->set(on);
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
LOG_DEBUG("Pin EN %s\n", val == HIGH ? "HIGH" : "LOW");
|
LOG_DEBUG("Pin EN %s", val == HIGH ? "HIGH" : "LOW");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -785,7 +783,7 @@ void GPS::writePinStandby(bool standby)
|
|||||||
pinMode(PIN_GPS_STANDBY, OUTPUT);
|
pinMode(PIN_GPS_STANDBY, OUTPUT);
|
||||||
digitalWrite(PIN_GPS_STANDBY, val);
|
digitalWrite(PIN_GPS_STANDBY, val);
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
LOG_DEBUG("Pin STANDBY %s\n", val == HIGH ? "HIGH" : "LOW");
|
LOG_DEBUG("Pin STANDBY %s", val == HIGH ? "HIGH" : "LOW");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -819,7 +817,7 @@ void GPS::setPowerPMU(bool on)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
LOG_DEBUG("PMU %s\n", on ? "on" : "off");
|
LOG_DEBUG("PMU %s", on ? "on" : "off");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -836,7 +834,7 @@ void GPS::setPowerUBLOX(bool on, uint32_t sleepMs)
|
|||||||
gps->_serial_gps->write(0xFF);
|
gps->_serial_gps->write(0xFF);
|
||||||
clearBuffer(); // This often returns old data, so drop it
|
clearBuffer(); // This often returns old data, so drop it
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
LOG_DEBUG("UBLOX: wake\n");
|
LOG_DEBUG("UBLOX: wake");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -851,7 +849,7 @@ void GPS::setPowerUBLOX(bool on, uint32_t sleepMs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Determine hardware version
|
// Determine hardware version
|
||||||
if (gnssModel == GNSS_MODEL_UBLOX10) {
|
if (gnssModel != GNSS_MODEL_UBLOX10) {
|
||||||
// Encode the sleep time in millis into the packet
|
// Encode the sleep time in millis into the packet
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
gps->_message_PMREQ[0 + i] = sleepMs >> (i * 8);
|
gps->_message_PMREQ[0 + i] = sleepMs >> (i * 8);
|
||||||
@@ -871,7 +869,7 @@ void GPS::setPowerUBLOX(bool on, uint32_t sleepMs)
|
|||||||
gps->_serial_gps->write(gps->UBXscratch, msglen);
|
gps->_serial_gps->write(gps->UBXscratch, msglen);
|
||||||
|
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
LOG_DEBUG("UBLOX: sleep for %dmS\n", sleepMs);
|
LOG_DEBUG("UBLOX: sleep for %dmS", sleepMs);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -900,7 +898,7 @@ void GPS::down()
|
|||||||
uint32_t sleepTime = scheduling.msUntilNextSearch();
|
uint32_t sleepTime = scheduling.msUntilNextSearch();
|
||||||
uint32_t updateInterval = Default::getConfiguredOrDefaultMs(config.position.gps_update_interval);
|
uint32_t updateInterval = Default::getConfiguredOrDefaultMs(config.position.gps_update_interval);
|
||||||
|
|
||||||
LOG_DEBUG("%us until next search\n", sleepTime / 1000);
|
LOG_DEBUG("%us until next search", sleepTime / 1000);
|
||||||
|
|
||||||
// If update interval less than 10 seconds, no attempt to sleep
|
// If update interval less than 10 seconds, no attempt to sleep
|
||||||
if (updateInterval <= 10 * 1000UL || sleepTime == 0)
|
if (updateInterval <= 10 * 1000UL || sleepTime == 0)
|
||||||
@@ -923,7 +921,7 @@ void GPS::down()
|
|||||||
// https://www.desmos.com/calculator/6gvjghoumr
|
// https://www.desmos.com/calculator/6gvjghoumr
|
||||||
// This is not particularly accurate, but probably an impromevement over a single, fixed threshold
|
// This is not particularly accurate, but probably an impromevement over a single, fixed threshold
|
||||||
uint32_t hardsleepThreshold = (2750 * pow(predictedSearchDuration / 1000, 1.22));
|
uint32_t hardsleepThreshold = (2750 * pow(predictedSearchDuration / 1000, 1.22));
|
||||||
LOG_DEBUG("gps_update_interval >= %us needed to justify hardsleep\n", hardsleepThreshold / 1000);
|
LOG_DEBUG("gps_update_interval >= %us needed to justify hardsleep", hardsleepThreshold / 1000);
|
||||||
|
|
||||||
// If update interval too short: softsleep (if supported by hardware)
|
// If update interval too short: softsleep (if supported by hardware)
|
||||||
if (updateInterval < hardsleepThreshold) {
|
if (updateInterval < hardsleepThreshold) {
|
||||||
@@ -942,7 +940,7 @@ void GPS::publishUpdate()
|
|||||||
shouldPublish = false;
|
shouldPublish = false;
|
||||||
|
|
||||||
// In debug logs, identify position by @timestamp:stage (stage 2 = publish)
|
// In debug logs, identify position by @timestamp:stage (stage 2 = publish)
|
||||||
LOG_DEBUG("publishing pos@%x:2, hasVal=%d, Sats=%d, GPSlock=%d\n", p.timestamp, hasValidLocation, p.sats_in_view,
|
LOG_DEBUG("publishing pos@%x:2, hasVal=%d, Sats=%d, GPSlock=%d", p.timestamp, hasValidLocation, p.sats_in_view,
|
||||||
hasLock());
|
hasLock());
|
||||||
|
|
||||||
// Notify any status instances that are observing us
|
// Notify any status instances that are observing us
|
||||||
@@ -958,7 +956,7 @@ int32_t GPS::runOnce()
|
|||||||
{
|
{
|
||||||
if (!GPSInitFinished) {
|
if (!GPSInitFinished) {
|
||||||
if (!_serial_gps || config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT) {
|
if (!_serial_gps || config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT) {
|
||||||
LOG_INFO("GPS set to not-present. Skipping probe.\n");
|
LOG_INFO("GPS set to not-present. Skipping probe.");
|
||||||
return disable();
|
return disable();
|
||||||
}
|
}
|
||||||
if (!setup())
|
if (!setup())
|
||||||
@@ -970,7 +968,7 @@ int32_t GPS::runOnce()
|
|||||||
}
|
}
|
||||||
// ONCE we will factory reset the GPS for bug #327
|
// ONCE we will factory reset the GPS for bug #327
|
||||||
if (!devicestate.did_gps_reset) {
|
if (!devicestate.did_gps_reset) {
|
||||||
LOG_WARN("GPS FactoryReset requested\n");
|
LOG_WARN("GPS FactoryReset requested");
|
||||||
if (gps->factoryReset()) { // If we don't succeed try again next time
|
if (gps->factoryReset()) { // If we don't succeed try again next time
|
||||||
devicestate.did_gps_reset = true;
|
devicestate.did_gps_reset = true;
|
||||||
nodeDB->saveToDisk(SEGMENT_DEVICESTATE);
|
nodeDB->saveToDisk(SEGMENT_DEVICESTATE);
|
||||||
@@ -993,7 +991,7 @@ int32_t GPS::runOnce()
|
|||||||
GNSS_MODEL_UBLOX10)) {
|
GNSS_MODEL_UBLOX10)) {
|
||||||
// reset the GPS on next bootup
|
// reset the GPS on next bootup
|
||||||
if (devicestate.did_gps_reset && scheduling.elapsedSearchMs() > 60 * 1000UL && !hasFlow()) {
|
if (devicestate.did_gps_reset && scheduling.elapsedSearchMs() > 60 * 1000UL && !hasFlow()) {
|
||||||
LOG_DEBUG("GPS is not communicating, trying factory reset on next bootup.\n");
|
LOG_DEBUG("GPS is not communicating, trying factory reset on next bootup.");
|
||||||
devicestate.did_gps_reset = false;
|
devicestate.did_gps_reset = false;
|
||||||
nodeDB->saveToDisk(SEGMENT_DEVICESTATE);
|
nodeDB->saveToDisk(SEGMENT_DEVICESTATE);
|
||||||
return disable(); // Stop the GPS thread as it can do nothing useful until next reboot.
|
return disable(); // Stop the GPS thread as it can do nothing useful until next reboot.
|
||||||
@@ -1003,7 +1001,7 @@ int32_t GPS::runOnce()
|
|||||||
// At least one GPS has a bad habit of losing its mind from time to time
|
// At least one GPS has a bad habit of losing its mind from time to time
|
||||||
if (rebootsSeen > 2) {
|
if (rebootsSeen > 2) {
|
||||||
rebootsSeen = 0;
|
rebootsSeen = 0;
|
||||||
LOG_DEBUG("Would normally factoryReset()\n");
|
LOG_DEBUG("Would normally factoryReset()");
|
||||||
// gps->factoryReset();
|
// gps->factoryReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1020,23 +1018,23 @@ int32_t GPS::runOnce()
|
|||||||
|
|
||||||
bool gotLoc = lookForLocation();
|
bool gotLoc = lookForLocation();
|
||||||
if (gotLoc && !hasValidLocation) { // declare that we have location ASAP
|
if (gotLoc && !hasValidLocation) { // declare that we have location ASAP
|
||||||
LOG_DEBUG("hasValidLocation RISING EDGE\n");
|
LOG_DEBUG("hasValidLocation RISING EDGE");
|
||||||
hasValidLocation = true;
|
hasValidLocation = true;
|
||||||
shouldPublish = true;
|
shouldPublish = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tooLong = scheduling.searchedTooLong();
|
bool tooLong = scheduling.searchedTooLong();
|
||||||
if (tooLong)
|
if (tooLong)
|
||||||
LOG_WARN("Couldn't publish a valid location: didn't get a GPS lock in time.\n");
|
LOG_WARN("Couldn't publish a valid location: didn't get a GPS lock in time.");
|
||||||
|
|
||||||
// Once we get a location we no longer desperately want an update
|
// Once we get a location we no longer desperately want an update
|
||||||
// LOG_DEBUG("gotLoc %d, tooLong %d, gotTime %d\n", gotLoc, tooLong, gotTime);
|
// LOG_DEBUG("gotLoc %d, tooLong %d, gotTime %d", gotLoc, tooLong, gotTime);
|
||||||
if ((gotLoc && gotTime) || tooLong) {
|
if ((gotLoc && gotTime) || tooLong) {
|
||||||
|
|
||||||
if (tooLong) {
|
if (tooLong) {
|
||||||
// we didn't get a location during this ack window, therefore declare loss of lock
|
// we didn't get a location during this ack window, therefore declare loss of lock
|
||||||
if (hasValidLocation) {
|
if (hasValidLocation) {
|
||||||
LOG_DEBUG("hasValidLocation FALLING EDGE\n");
|
LOG_DEBUG("hasValidLocation FALLING EDGE");
|
||||||
}
|
}
|
||||||
p = meshtastic_Position_init_default;
|
p = meshtastic_Position_init_default;
|
||||||
hasValidLocation = false;
|
hasValidLocation = false;
|
||||||
@@ -1068,17 +1066,20 @@ void GPS::clearBuffer()
|
|||||||
/// 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
|
||||||
int GPS::prepareDeepSleep(void *unused)
|
int GPS::prepareDeepSleep(void *unused)
|
||||||
{
|
{
|
||||||
LOG_INFO("GPS deep sleep!\n");
|
LOG_INFO("GPS deep sleep!");
|
||||||
disable();
|
disable();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *PROBE_MESSAGE = "Trying %s (%s)...";
|
||||||
|
const char *DETECTED_MESSAGE = "%s detected, using %s Module";
|
||||||
|
|
||||||
#define PROBE_SIMPLE(CHIP, TOWRITE, RESPONSE, DRIVER, TIMEOUT, ...) \
|
#define PROBE_SIMPLE(CHIP, TOWRITE, RESPONSE, DRIVER, TIMEOUT, ...) \
|
||||||
LOG_DEBUG("Trying " TOWRITE " (" CHIP ") ...\n"); \
|
LOG_DEBUG(PROBE_MESSAGE, TOWRITE, CHIP); \
|
||||||
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(CHIP " detected, using " #DRIVER " Module\n"); \
|
LOG_INFO(DETECTED_MESSAGE, CHIP, #DRIVER); \
|
||||||
return DRIVER; \
|
return DRIVER; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1093,7 +1094,7 @@ GnssModel_t GPS::probe(int serialSpeed)
|
|||||||
_serial_gps->begin(serialSpeed);
|
_serial_gps->begin(serialSpeed);
|
||||||
#else
|
#else
|
||||||
if (_serial_gps->baudRate() != serialSpeed) {
|
if (_serial_gps->baudRate() != serialSpeed) {
|
||||||
LOG_DEBUG("Setting Baud to %i\n", serialSpeed);
|
LOG_DEBUG("Setting Baud to %i", serialSpeed);
|
||||||
_serial_gps->updateBaudRate(serialSpeed);
|
_serial_gps->updateBaudRate(serialSpeed);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1105,6 +1106,11 @@ GnssModel_t GPS::probe(int serialSpeed)
|
|||||||
// Close all NMEA sentences, valid for L76K, ATGM336H (and likely other AT6558 devices)
|
// Close all NMEA sentences, valid for L76K, ATGM336H (and likely other AT6558 devices)
|
||||||
_serial_gps->write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n");
|
_serial_gps->write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n");
|
||||||
delay(20);
|
delay(20);
|
||||||
|
// Close NMEA sequences on Ublox
|
||||||
|
_serial_gps->write("$PUBX,40,GLL,0,0,0,0,0,0*5C\r\n");
|
||||||
|
_serial_gps->write("$PUBX,40,GSV,0,0,0,0,0,0*59\r\n");
|
||||||
|
_serial_gps->write("$PUBX,40,VTG,0,0,0,0,0,0*5E\r\n");
|
||||||
|
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);
|
PROBE_SIMPLE("UC6580", "$PDTINFO", "UC6580", GNSS_MODEL_UC6580, 500);
|
||||||
@@ -1137,35 +1143,10 @@ GnssModel_t GPS::probe(int serialSpeed)
|
|||||||
// Check that the returned response class and message ID are correct
|
// Check that the returned response class and message ID are correct
|
||||||
GPS_RESPONSE response = getACK(0x06, 0x08, 750);
|
GPS_RESPONSE response = getACK(0x06, 0x08, 750);
|
||||||
if (response == GNSS_RESPONSE_NONE) {
|
if (response == GNSS_RESPONSE_NONE) {
|
||||||
LOG_WARN("Failed to find UBlox & MTK GNSS Module using baudrate %d\n", serialSpeed);
|
LOG_WARN("Failed to find GNSS Module (baudrate %d)", serialSpeed);
|
||||||
return GNSS_MODEL_UNKNOWN;
|
return GNSS_MODEL_UNKNOWN;
|
||||||
} else if (response == GNSS_RESPONSE_FRAME_ERRORS) {
|
} else if (response == GNSS_RESPONSE_FRAME_ERRORS) {
|
||||||
LOG_INFO("UBlox Frame Errors using baudrate %d\n", serialSpeed);
|
LOG_INFO("UBlox Frame Errors (baudrate %d)", serialSpeed);
|
||||||
} else if (response == GNSS_RESPONSE_OK) {
|
|
||||||
LOG_INFO("Found a UBlox Module using baudrate %d\n", serialSpeed);
|
|
||||||
}
|
|
||||||
|
|
||||||
// tips: NMEA Only should not be set here, otherwise initializing Ublox gnss module again after
|
|
||||||
// setting will not output command messages in UART1, resulting in unrecognized module information
|
|
||||||
if (serialSpeed != 9600) {
|
|
||||||
// Set the UART port to 9600
|
|
||||||
uint8_t _message_prt[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00,
|
|
||||||
0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
||||||
UBXChecksum(_message_prt, sizeof(_message_prt));
|
|
||||||
_serial_gps->write(_message_prt, sizeof(_message_prt));
|
|
||||||
delay(500);
|
|
||||||
serialSpeed = 9600;
|
|
||||||
#if defined(ARCH_NRF52) || defined(ARCH_PORTDUINO) || defined(ARCH_STM32WL)
|
|
||||||
_serial_gps->end();
|
|
||||||
_serial_gps->begin(serialSpeed);
|
|
||||||
#elif defined(ARCH_RP2040)
|
|
||||||
_serial_gps->end();
|
|
||||||
_serial_gps->setFIFOSize(256);
|
|
||||||
_serial_gps->begin(serialSpeed);
|
|
||||||
#else
|
|
||||||
_serial_gps->updateBaudRate(serialSpeed);
|
|
||||||
#endif
|
|
||||||
delay(200);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
@@ -1182,7 +1163,7 @@ GnssModel_t GPS::probe(int serialSpeed)
|
|||||||
|
|
||||||
uint16_t len = getACK(buffer, sizeof(buffer), 0x0A, 0x04, 1200);
|
uint16_t len = getACK(buffer, sizeof(buffer), 0x0A, 0x04, 1200);
|
||||||
if (len) {
|
if (len) {
|
||||||
// LOG_DEBUG("monver reply size = %d\n", len);
|
// LOG_DEBUG("monver reply size = %d", len);
|
||||||
uint16_t position = 0;
|
uint16_t position = 0;
|
||||||
for (int i = 0; i < 30; i++) {
|
for (int i = 0; i < 30; i++) {
|
||||||
info.swVersion[i] = buffer[position];
|
info.swVersion[i] = buffer[position];
|
||||||
@@ -1203,12 +1184,12 @@ GnssModel_t GPS::probe(int serialSpeed)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("Module Info : \n");
|
LOG_DEBUG("Module Info : ");
|
||||||
LOG_DEBUG("Soft version: %s\n", info.swVersion);
|
LOG_DEBUG("Soft version: %s", info.swVersion);
|
||||||
LOG_DEBUG("Hard version: %s\n", info.hwVersion);
|
LOG_DEBUG("Hard version: %s", info.hwVersion);
|
||||||
LOG_DEBUG("Extensions:%d\n", info.extensionNo);
|
LOG_DEBUG("Extensions:%d", info.extensionNo);
|
||||||
for (int i = 0; i < info.extensionNo; i++) {
|
for (int i = 0; i < info.extensionNo; i++) {
|
||||||
LOG_DEBUG(" %s\n", info.extension[i]);
|
LOG_DEBUG(" %s", info.extension[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
@@ -1217,38 +1198,37 @@ GnssModel_t GPS::probe(int serialSpeed)
|
|||||||
for (int i = 0; i < info.extensionNo; ++i) {
|
for (int i = 0; i < info.extensionNo; ++i) {
|
||||||
if (!strncmp(info.extension[i], "MOD=", 4)) {
|
if (!strncmp(info.extension[i], "MOD=", 4)) {
|
||||||
strncpy((char *)buffer, &(info.extension[i][4]), sizeof(buffer));
|
strncpy((char *)buffer, &(info.extension[i][4]), sizeof(buffer));
|
||||||
// LOG_DEBUG("GetModel:%s\n", (char *)buffer);
|
|
||||||
if (strlen((char *)buffer)) {
|
|
||||||
LOG_INFO("%s detected, using GNSS_MODEL_UBLOX\n", (char *)buffer);
|
|
||||||
} else {
|
|
||||||
LOG_INFO("Generic Ublox detected, using GNSS_MODEL_UBLOX\n");
|
|
||||||
}
|
|
||||||
} else if (!strncmp(info.extension[i], "PROTVER", 7)) {
|
} else if (!strncmp(info.extension[i], "PROTVER", 7)) {
|
||||||
char *ptr = nullptr;
|
char *ptr = nullptr;
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
strncpy((char *)buffer, &(info.extension[i][8]), sizeof(buffer));
|
strncpy((char *)buffer, &(info.extension[i][8]), sizeof(buffer));
|
||||||
LOG_DEBUG("Protocol Version:%s\n", (char *)buffer);
|
LOG_DEBUG("Protocol Version:%s", (char *)buffer);
|
||||||
if (strlen((char *)buffer)) {
|
if (strlen((char *)buffer)) {
|
||||||
uBloxProtocolVersion = strtoul((char *)buffer, &ptr, 10);
|
uBloxProtocolVersion = strtoul((char *)buffer, &ptr, 10);
|
||||||
LOG_DEBUG("ProtVer=%d\n", uBloxProtocolVersion);
|
LOG_DEBUG("ProtVer=%d", uBloxProtocolVersion);
|
||||||
} else {
|
} else {
|
||||||
uBloxProtocolVersion = 0;
|
uBloxProtocolVersion = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (strncmp(info.hwVersion, "00040007", 8) == 0) {
|
if (strncmp(info.hwVersion, "00040007", 8) == 0) {
|
||||||
|
LOG_INFO(DETECTED_MESSAGE, "U-blox 6", "6");
|
||||||
return GNSS_MODEL_UBLOX6;
|
return GNSS_MODEL_UBLOX6;
|
||||||
} else if (strncmp(info.hwVersion, "00070000", 8) == 0) {
|
} else if (strncmp(info.hwVersion, "00070000", 8) == 0) {
|
||||||
|
LOG_INFO(DETECTED_MESSAGE, "U-blox 7", "7");
|
||||||
return GNSS_MODEL_UBLOX7;
|
return GNSS_MODEL_UBLOX7;
|
||||||
} else if (strncmp(info.hwVersion, "00080000", 8) == 0) {
|
} else if (strncmp(info.hwVersion, "00080000", 8) == 0) {
|
||||||
|
LOG_INFO(DETECTED_MESSAGE, "U-blox 8", "8");
|
||||||
return GNSS_MODEL_UBLOX8;
|
return GNSS_MODEL_UBLOX8;
|
||||||
} else if (strncmp(info.hwVersion, "00190000", 8) == 0) {
|
} else if (strncmp(info.hwVersion, "00190000", 8) == 0) {
|
||||||
|
LOG_INFO(DETECTED_MESSAGE, "U-blox 9", "9");
|
||||||
return GNSS_MODEL_UBLOX9;
|
return GNSS_MODEL_UBLOX9;
|
||||||
} else if (strncmp(info.hwVersion, "000A0000", 8) == 0) {
|
} else if (strncmp(info.hwVersion, "000A0000", 8) == 0) {
|
||||||
|
LOG_INFO(DETECTED_MESSAGE, "U-blox 10", "10");
|
||||||
return GNSS_MODEL_UBLOX10;
|
return GNSS_MODEL_UBLOX10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LOG_WARN("Failed to find GNSS Module (baudrate %d)", serialSpeed);
|
||||||
return GNSS_MODEL_UNKNOWN;
|
return GNSS_MODEL_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1309,7 +1289,7 @@ GPS *GPS::createGps()
|
|||||||
// see NMEAGPS.h
|
// see NMEAGPS.h
|
||||||
gsafixtype.begin(reader, NMEA_MSG_GXGSA, 2);
|
gsafixtype.begin(reader, NMEA_MSG_GXGSA, 2);
|
||||||
gsapdop.begin(reader, NMEA_MSG_GXGSA, 15);
|
gsapdop.begin(reader, NMEA_MSG_GXGSA, 15);
|
||||||
LOG_DEBUG("Using " NMEA_MSG_GXGSA " for 3DFIX and PDOP\n");
|
LOG_DEBUG("Using " NMEA_MSG_GXGSA " for 3DFIX and PDOP");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Make sure the GPS is awake before performing any init.
|
// Make sure the GPS is awake before performing any init.
|
||||||
@@ -1330,8 +1310,8 @@ GPS *GPS::createGps()
|
|||||||
|
|
||||||
// ESP32 has a special set of parameters vs other arduino ports
|
// ESP32 has a special set of parameters vs other arduino ports
|
||||||
#if defined(ARCH_ESP32)
|
#if defined(ARCH_ESP32)
|
||||||
LOG_DEBUG("Using GPIO%d for GPS RX\n", new_gps->rx_gpio);
|
LOG_DEBUG("Using GPIO%d for GPS RX", new_gps->rx_gpio);
|
||||||
LOG_DEBUG("Using GPIO%d for GPS TX\n", new_gps->tx_gpio);
|
LOG_DEBUG("Using GPIO%d for GPS TX", new_gps->tx_gpio);
|
||||||
_serial_gps->begin(GPS_BAUDRATE, SERIAL_8N1, new_gps->rx_gpio, new_gps->tx_gpio);
|
_serial_gps->begin(GPS_BAUDRATE, SERIAL_8N1, new_gps->rx_gpio, new_gps->tx_gpio);
|
||||||
#elif defined(ARCH_RP2040)
|
#elif defined(ARCH_RP2040)
|
||||||
_serial_gps->setFIFOSize(256);
|
_serial_gps->setFIFOSize(256);
|
||||||
@@ -1367,21 +1347,21 @@ bool GPS::factoryReset()
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1C, 0xA2};
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1C, 0xA2};
|
||||||
_serial_gps->write(_message_reset1, sizeof(_message_reset1));
|
_serial_gps->write(_message_reset1, sizeof(_message_reset1));
|
||||||
if (getACK(0x05, 0x01, 10000)) {
|
if (getACK(0x05, 0x01, 10000)) {
|
||||||
LOG_INFO("Get ack success!\n");
|
LOG_INFO(ACK_SUCCESS_MESSAGE);
|
||||||
}
|
}
|
||||||
delay(100);
|
delay(100);
|
||||||
byte _message_reset2[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
|
byte _message_reset2[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1B, 0xA1};
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1B, 0xA1};
|
||||||
_serial_gps->write(_message_reset2, sizeof(_message_reset2));
|
_serial_gps->write(_message_reset2, sizeof(_message_reset2));
|
||||||
if (getACK(0x05, 0x01, 10000)) {
|
if (getACK(0x05, 0x01, 10000)) {
|
||||||
LOG_INFO("Get ack success!\n");
|
LOG_INFO(ACK_SUCCESS_MESSAGE);
|
||||||
}
|
}
|
||||||
delay(100);
|
delay(100);
|
||||||
byte _message_reset3[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
byte _message_reset3[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0x1D, 0xB3};
|
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0x1D, 0xB3};
|
||||||
_serial_gps->write(_message_reset3, sizeof(_message_reset3));
|
_serial_gps->write(_message_reset3, sizeof(_message_reset3));
|
||||||
if (getACK(0x05, 0x01, 10000)) {
|
if (getACK(0x05, 0x01, 10000)) {
|
||||||
LOG_INFO("Get ack success!\n");
|
LOG_INFO(ACK_SUCCESS_MESSAGE);
|
||||||
}
|
}
|
||||||
// Reset device ram to COLDSTART state
|
// Reset device ram to COLDSTART state
|
||||||
// byte _message_CFG_RST_COLDSTART[] = {0xB5, 0x62, 0x06, 0x04, 0x04, 0x00, 0xFF, 0xB9, 0x00, 0x00, 0xC6, 0x8B};
|
// byte _message_CFG_RST_COLDSTART[] = {0xB5, 0x62, 0x06, 0x04, 0x04, 0x00, 0xFF, 0xB9, 0x00, 0x00, 0xC6, 0x8B};
|
||||||
@@ -1389,11 +1369,11 @@ bool GPS::factoryReset()
|
|||||||
// delay(1000);
|
// delay(1000);
|
||||||
} else if (gnssModel == GNSS_MODEL_MTK) {
|
} else if (gnssModel == GNSS_MODEL_MTK) {
|
||||||
// send the CAS10 to perform a factory restart of the device (and other device that support PCAS statements)
|
// send the CAS10 to perform a factory restart of the device (and other device that support PCAS statements)
|
||||||
LOG_INFO("GNSS Factory Reset via PCAS10,3\n");
|
LOG_INFO("GNSS Factory Reset via PCAS10,3");
|
||||||
_serial_gps->write("$PCAS10,3*1F\r\n");
|
_serial_gps->write("$PCAS10,3*1F\r\n");
|
||||||
delay(100);
|
delay(100);
|
||||||
} else if (gnssModel == GNSS_MODEL_ATGM336H) {
|
} else if (gnssModel == GNSS_MODEL_ATGM336H) {
|
||||||
LOG_INFO("Factory Reset via CAS-CFG-RST\n");
|
LOG_INFO("Factory Reset via CAS-CFG-RST");
|
||||||
uint8_t msglen = makeCASPacket(0x06, 0x02, sizeof(_message_CAS_CFG_RST_FACTORY), _message_CAS_CFG_RST_FACTORY);
|
uint8_t msglen = makeCASPacket(0x06, 0x02, sizeof(_message_CAS_CFG_RST_FACTORY), _message_CAS_CFG_RST_FACTORY);
|
||||||
_serial_gps->write(UBXscratch, msglen);
|
_serial_gps->write(UBXscratch, msglen);
|
||||||
delay(100);
|
delay(100);
|
||||||
@@ -1454,7 +1434,7 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
|
|||||||
t.tm_year = d.year() - 1900;
|
t.tm_year = d.year() - 1900;
|
||||||
t.tm_isdst = false;
|
t.tm_isdst = false;
|
||||||
if (t.tm_mon > -1) {
|
if (t.tm_mon > -1) {
|
||||||
LOG_DEBUG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d age %d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min,
|
LOG_DEBUG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d age %d", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min,
|
||||||
t.tm_sec, ti.age());
|
t.tm_sec, ti.age());
|
||||||
perhapsSetRTC(RTCQualityGPS, t);
|
perhapsSetRTC(RTCQualityGPS, t);
|
||||||
return true;
|
return true;
|
||||||
@@ -1498,7 +1478,7 @@ bool GPS::lookForLocation()
|
|||||||
|
|
||||||
#ifndef TINYGPS_OPTION_NO_STATISTICS
|
#ifndef TINYGPS_OPTION_NO_STATISTICS
|
||||||
if (reader.failedChecksum() > lastChecksumFailCount) {
|
if (reader.failedChecksum() > lastChecksumFailCount) {
|
||||||
LOG_WARN("%u new GPS checksum failures, for a total of %u.\n", reader.failedChecksum() - lastChecksumFailCount,
|
LOG_WARN("%u new GPS checksum failures, for a total of %u.", reader.failedChecksum() - lastChecksumFailCount,
|
||||||
reader.failedChecksum());
|
reader.failedChecksum());
|
||||||
lastChecksumFailCount = reader.failedChecksum();
|
lastChecksumFailCount = reader.failedChecksum();
|
||||||
}
|
}
|
||||||
@@ -1506,7 +1486,7 @@ bool GPS::lookForLocation()
|
|||||||
|
|
||||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||||
fixType = atoi(gsafixtype.value()); // will set to zero if no data
|
fixType = atoi(gsafixtype.value()); // will set to zero if no data
|
||||||
// LOG_DEBUG("FIX QUAL=%d, TYPE=%d\n", fixQual, fixType);
|
// LOG_DEBUG("FIX QUAL=%d, TYPE=%d", fixQual, fixType);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// check if GPS has an acceptable lock
|
// check if GPS has an acceptable lock
|
||||||
@@ -1514,7 +1494,7 @@ bool GPS::lookForLocation()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
LOG_DEBUG("AGE: LOC=%d FIX=%d DATE=%d TIME=%d\n", reader.location.age(),
|
LOG_DEBUG("AGE: LOC=%d FIX=%d DATE=%d TIME=%d", reader.location.age(),
|
||||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||||
gsafixtype.age(),
|
gsafixtype.age(),
|
||||||
#else
|
#else
|
||||||
@@ -1535,7 +1515,7 @@ bool GPS::lookForLocation()
|
|||||||
(gsafixtype.age() < GPS_SOL_EXPIRY_MS) &&
|
(gsafixtype.age() < GPS_SOL_EXPIRY_MS) &&
|
||||||
#endif
|
#endif
|
||||||
(reader.time.age() < GPS_SOL_EXPIRY_MS) && (reader.date.age() < GPS_SOL_EXPIRY_MS))) {
|
(reader.time.age() < GPS_SOL_EXPIRY_MS) && (reader.date.age() < GPS_SOL_EXPIRY_MS))) {
|
||||||
LOG_WARN("SOME data is TOO OLD: LOC %u, TIME %u, DATE %u\n", reader.location.age(), reader.time.age(), reader.date.age());
|
LOG_WARN("SOME data is TOO OLD: LOC %u, TIME %u, DATE %u", reader.location.age(), reader.time.age(), reader.date.age());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1545,13 +1525,13 @@ bool GPS::lookForLocation()
|
|||||||
// Bail out EARLY to avoid overwriting previous good data (like #857)
|
// Bail out EARLY to avoid overwriting previous good data (like #857)
|
||||||
if (toDegInt(loc.lat) > 900000000) {
|
if (toDegInt(loc.lat) > 900000000) {
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
LOG_DEBUG("Bail out EARLY on LAT %i\n", toDegInt(loc.lat));
|
LOG_DEBUG("Bail out EARLY on LAT %i", toDegInt(loc.lat));
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (toDegInt(loc.lng) > 1800000000) {
|
if (toDegInt(loc.lng) > 1800000000) {
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
LOG_DEBUG("Bail out EARLY on LNG %i\n", toDegInt(loc.lng));
|
LOG_DEBUG("Bail out EARLY on LNG %i", toDegInt(loc.lng));
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1562,7 +1542,7 @@ bool GPS::lookForLocation()
|
|||||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||||
p.HDOP = reader.hdop.value();
|
p.HDOP = reader.hdop.value();
|
||||||
p.PDOP = TinyGPSPlus::parseDecimal(gsapdop.value());
|
p.PDOP = TinyGPSPlus::parseDecimal(gsapdop.value());
|
||||||
// LOG_DEBUG("PDOP=%d, HDOP=%d\n", p.PDOP, p.HDOP);
|
// LOG_DEBUG("PDOP=%d, HDOP=%d", p.PDOP, p.HDOP);
|
||||||
#else
|
#else
|
||||||
// FIXME! naive PDOP emulation (assumes VDOP==HDOP)
|
// FIXME! naive PDOP emulation (assumes VDOP==HDOP)
|
||||||
// correct formula is PDOP = SQRT(HDOP^2 + VDOP^2)
|
// correct formula is PDOP = SQRT(HDOP^2 + VDOP^2)
|
||||||
@@ -1572,7 +1552,7 @@ bool GPS::lookForLocation()
|
|||||||
|
|
||||||
// Discard incomplete or erroneous readings
|
// Discard incomplete or erroneous readings
|
||||||
if (reader.hdop.value() == 0) {
|
if (reader.hdop.value() == 0) {
|
||||||
LOG_WARN("BOGUS hdop.value() REJECTED: %d\n", reader.hdop.value());
|
LOG_WARN("BOGUS hdop.value() REJECTED: %d", reader.hdop.value());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1609,7 +1589,7 @@ bool GPS::lookForLocation()
|
|||||||
p.ground_track =
|
p.ground_track =
|
||||||
reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5
|
reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN("BOGUS course.value() REJECTED: %d\n", reader.course.value());
|
LOG_WARN("BOGUS course.value() REJECTED: %d", reader.course.value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1649,12 +1629,12 @@ bool GPS::whileActive()
|
|||||||
}
|
}
|
||||||
#ifdef SERIAL_BUFFER_SIZE
|
#ifdef SERIAL_BUFFER_SIZE
|
||||||
if (_serial_gps->available() >= SERIAL_BUFFER_SIZE - 1) {
|
if (_serial_gps->available() >= SERIAL_BUFFER_SIZE - 1) {
|
||||||
LOG_WARN("GPS Buffer full with %u bytes waiting. Flushing to avoid corruption.\n", _serial_gps->available());
|
LOG_WARN("GPS Buffer full with %u bytes waiting. Flushing to avoid corruption.", _serial_gps->available());
|
||||||
clearBuffer();
|
clearBuffer();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// if (_serial_gps->available() > 0)
|
// if (_serial_gps->available() > 0)
|
||||||
// LOG_DEBUG("GPS Bytes Waiting: %u\n", _serial_gps->available());
|
// LOG_DEBUG("GPS Bytes Waiting: %u", _serial_gps->available());
|
||||||
// First consume any chars that have piled up at the receiver
|
// First consume any chars that have piled up at the receiver
|
||||||
while (_serial_gps->available() > 0) {
|
while (_serial_gps->available() > 0) {
|
||||||
int c = _serial_gps->read();
|
int c = _serial_gps->read();
|
||||||
@@ -1699,17 +1679,17 @@ void GPS::toggleGpsMode()
|
|||||||
{
|
{
|
||||||
if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
|
if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
|
||||||
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_DISABLED;
|
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_DISABLED;
|
||||||
LOG_INFO("User toggled GpsMode. Now DISABLED.\n");
|
LOG_INFO("User toggled GpsMode. Now DISABLED.");
|
||||||
#ifdef GNSS_AIROHA
|
#ifdef GNSS_AIROHA
|
||||||
if (powerState == GPS_ACTIVE) {
|
if (powerState == GPS_ACTIVE) {
|
||||||
LOG_DEBUG("User power Off GPS\n");
|
LOG_DEBUG("User power Off GPS");
|
||||||
digitalWrite(PIN_GPS_EN, LOW);
|
digitalWrite(PIN_GPS_EN, LOW);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
disable();
|
disable();
|
||||||
} else if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_DISABLED) {
|
} else if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_DISABLED) {
|
||||||
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED;
|
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED;
|
||||||
LOG_INFO("User toggled GpsMode. Now ENABLED\n");
|
LOG_INFO("User toggled GpsMode. Now ENABLED");
|
||||||
enable();
|
enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,6 +156,8 @@ class GPS : private concurrency::OSThread
|
|||||||
static const uint8_t _message_CAS_CFG_NAVX_CONF[];
|
static const uint8_t _message_CAS_CFG_NAVX_CONF[];
|
||||||
static const uint8_t _message_CAS_CFG_RATE_1HZ[];
|
static const uint8_t _message_CAS_CFG_RATE_1HZ[];
|
||||||
|
|
||||||
|
const char *ACK_SUCCESS_MESSAGE = "Get ack success!";
|
||||||
|
|
||||||
meshtastic_Position p = meshtastic_Position_init_default;
|
meshtastic_Position p = meshtastic_Position_init_default;
|
||||||
|
|
||||||
/** This is normally bound to config.position.gps_en_gpio but some rare boards (like heltec tracker) need more advanced
|
/** This is normally bound to config.position.gps_en_gpio but some rare boards (like heltec tracker) need more advanced
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ void GPSUpdateScheduling::informSearching()
|
|||||||
void GPSUpdateScheduling::informGotLock()
|
void GPSUpdateScheduling::informGotLock()
|
||||||
{
|
{
|
||||||
searchEndedMs = millis();
|
searchEndedMs = millis();
|
||||||
LOG_DEBUG("Took %us to get lock\n", (searchEndedMs - searchStartedMs) / 1000);
|
LOG_DEBUG("Took %us to get lock", (searchEndedMs - searchStartedMs) / 1000);
|
||||||
updateLockTimePrediction();
|
updateLockTimePrediction();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ void GPSUpdateScheduling::updateLockTimePrediction()
|
|||||||
|
|
||||||
searchCount++; // Only tracked so we can diregard initial lock-times
|
searchCount++; // Only tracked so we can diregard initial lock-times
|
||||||
|
|
||||||
LOG_DEBUG("Predicting %us to get next lock\n", predictedMsToGetLock / 1000);
|
LOG_DEBUG("Predicting %us to get next lock", predictedMsToGetLock / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// How long do we expect to spend searching for a lock?
|
// How long do we expect to spend searching for a lock?
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ void readFromRTC()
|
|||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
|
uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
|
||||||
LOG_DEBUG("Read RTC time from RV3028 getTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t.tm_year + 1900, t.tm_mon + 1,
|
LOG_DEBUG("Read RTC time from RV3028 getTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)", t.tm_year + 1900, t.tm_mon + 1,
|
||||||
t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch);
|
t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch);
|
||||||
timeStartMsec = now;
|
timeStartMsec = now;
|
||||||
zeroOffsetSecs = tv.tv_sec;
|
zeroOffsetSecs = tv.tv_sec;
|
||||||
@@ -77,8 +77,8 @@ void readFromRTC()
|
|||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
|
uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
|
||||||
LOG_DEBUG("Read RTC time from PCF8563 getDateTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t.tm_year + 1900,
|
LOG_DEBUG("Read RTC time from PCF8563 getDateTime as %02d-%02d-%02d %02d:%02d:%02d (%ld)", t.tm_year + 1900, t.tm_mon + 1,
|
||||||
t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch);
|
t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, printableEpoch);
|
||||||
timeStartMsec = now;
|
timeStartMsec = now;
|
||||||
zeroOffsetSecs = tv.tv_sec;
|
zeroOffsetSecs = tv.tv_sec;
|
||||||
if (currentQuality == RTCQualityNone) {
|
if (currentQuality == RTCQualityNone) {
|
||||||
@@ -89,7 +89,7 @@ void readFromRTC()
|
|||||||
if (!gettimeofday(&tv, NULL)) {
|
if (!gettimeofday(&tv, NULL)) {
|
||||||
uint32_t now = millis();
|
uint32_t now = millis();
|
||||||
uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
|
uint32_t printableEpoch = tv.tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
|
||||||
LOG_DEBUG("Read RTC time as %ld\n", printableEpoch);
|
LOG_DEBUG("Read RTC time as %ld", printableEpoch);
|
||||||
timeStartMsec = now;
|
timeStartMsec = now;
|
||||||
zeroOffsetSecs = tv.tv_sec;
|
zeroOffsetSecs = tv.tv_sec;
|
||||||
}
|
}
|
||||||
@@ -112,7 +112,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate)
|
|||||||
uint32_t printableEpoch = tv->tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
|
uint32_t printableEpoch = tv->tv_sec; // Print lib only supports 32 bit but time_t can be 64 bit on some platforms
|
||||||
#ifdef BUILD_EPOCH
|
#ifdef BUILD_EPOCH
|
||||||
if (tv->tv_sec < BUILD_EPOCH) {
|
if (tv->tv_sec < BUILD_EPOCH) {
|
||||||
LOG_WARN("Ignoring time (%ld) before build epoch (%ld)!\n", printableEpoch, BUILD_EPOCH);
|
LOG_WARN("Ignoring time (%ld) before build epoch (%ld)!", printableEpoch, BUILD_EPOCH);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -120,21 +120,21 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate)
|
|||||||
bool shouldSet;
|
bool shouldSet;
|
||||||
if (forceUpdate) {
|
if (forceUpdate) {
|
||||||
shouldSet = true;
|
shouldSet = true;
|
||||||
LOG_DEBUG("Overriding current RTC quality (%s) with incoming time of RTC quality of %s\n", RtcName(currentQuality),
|
LOG_DEBUG("Overriding current RTC quality (%s) with incoming time of RTC quality of %s", RtcName(currentQuality),
|
||||||
RtcName(q));
|
RtcName(q));
|
||||||
} else if (q > currentQuality) {
|
} else if (q > currentQuality) {
|
||||||
shouldSet = true;
|
shouldSet = true;
|
||||||
LOG_DEBUG("Upgrading time to quality %s\n", RtcName(q));
|
LOG_DEBUG("Upgrading time to quality %s", RtcName(q));
|
||||||
} else if (q == RTCQualityGPS) {
|
} else if (q == RTCQualityGPS) {
|
||||||
shouldSet = true;
|
shouldSet = true;
|
||||||
LOG_DEBUG("Reapplying GPS time: %ld secs\n", printableEpoch);
|
LOG_DEBUG("Reapplying GPS time: %ld secs", printableEpoch);
|
||||||
} else if (q == RTCQualityNTP && !Throttle::isWithinTimespanMs(lastSetMsec, (12 * 60 * 60 * 1000UL))) {
|
} else if (q == RTCQualityNTP && !Throttle::isWithinTimespanMs(lastSetMsec, (12 * 60 * 60 * 1000UL))) {
|
||||||
// Every 12 hrs we will slam in a new NTP or Phone GPS / NTP time, to correct for local RTC clock drift
|
// Every 12 hrs we will slam in a new NTP or Phone GPS / NTP time, to correct for local RTC clock drift
|
||||||
shouldSet = true;
|
shouldSet = true;
|
||||||
LOG_DEBUG("Reapplying external time to correct clock drift %ld secs\n", printableEpoch);
|
LOG_DEBUG("Reapplying external time to correct clock drift %ld secs", printableEpoch);
|
||||||
} else {
|
} else {
|
||||||
shouldSet = false;
|
shouldSet = false;
|
||||||
LOG_DEBUG("Current RTC quality: %s. Ignoring time of RTC quality of %s\n", RtcName(currentQuality), RtcName(q));
|
LOG_DEBUG("Current RTC quality: %s. Ignoring time of RTC quality of %s", RtcName(currentQuality), RtcName(q));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldSet) {
|
if (shouldSet) {
|
||||||
@@ -158,7 +158,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate)
|
|||||||
#endif
|
#endif
|
||||||
tm *t = gmtime(&tv->tv_sec);
|
tm *t = gmtime(&tv->tv_sec);
|
||||||
rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
||||||
LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
|
LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d (%ld)", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
|
||||||
t->tm_hour, t->tm_min, t->tm_sec, printableEpoch);
|
t->tm_hour, t->tm_min, t->tm_sec, printableEpoch);
|
||||||
}
|
}
|
||||||
#elif defined(PCF8563_RTC)
|
#elif defined(PCF8563_RTC)
|
||||||
@@ -172,8 +172,8 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv, bool forceUpdate)
|
|||||||
#endif
|
#endif
|
||||||
tm *t = gmtime(&tv->tv_sec);
|
tm *t = gmtime(&tv->tv_sec);
|
||||||
rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
||||||
LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d (%ld)\n", t->tm_year + 1900, t->tm_mon + 1,
|
LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d (%ld)", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
|
||||||
t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, printableEpoch);
|
t->tm_hour, t->tm_min, t->tm_sec, printableEpoch);
|
||||||
}
|
}
|
||||||
#elif defined(ARCH_ESP32)
|
#elif defined(ARCH_ESP32)
|
||||||
settimeofday(tv, NULL);
|
settimeofday(tv, NULL);
|
||||||
@@ -228,9 +228,9 @@ bool perhapsSetRTC(RTCQuality q, struct tm &t)
|
|||||||
tv.tv_sec = res;
|
tv.tv_sec = res;
|
||||||
tv.tv_usec = 0; // time.centisecond() * (10 / 1000);
|
tv.tv_usec = 0; // time.centisecond() * (10 / 1000);
|
||||||
|
|
||||||
// LOG_DEBUG("Got time from GPS month=%d, year=%d, unixtime=%ld\n", t.tm_mon, t.tm_year, tv.tv_sec);
|
// LOG_DEBUG("Got time from GPS month=%d, year=%d, unixtime=%ld", t.tm_mon, t.tm_year, tv.tv_sec);
|
||||||
if (t.tm_year < 0 || t.tm_year >= 300) {
|
if (t.tm_year < 0 || t.tm_year >= 300) {
|
||||||
// LOG_DEBUG("Ignoring invalid GPS month=%d, year=%d, unixtime=%ld\n", t.tm_mon, t.tm_year, tv.tv_sec);
|
// LOG_DEBUG("Ignoring invalid GPS month=%d, year=%d, unixtime=%ld", t.tm_mon, t.tm_year, tv.tv_sec);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return perhapsSetRTC(q, &tv);
|
return perhapsSetRTC(q, &tv);
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
|
const char *failMessage = "Unable to %s";
|
||||||
|
|
||||||
#define SEND_UBX_PACKET(TYPE, ID, DATA, ERRMSG, TIMEOUT) \
|
#define SEND_UBX_PACKET(TYPE, ID, DATA, ERRMSG, TIMEOUT) \
|
||||||
msglen = makeUBXPacket(TYPE, ID, sizeof(DATA), DATA); \
|
msglen = makeUBXPacket(TYPE, ID, sizeof(DATA), DATA); \
|
||||||
_serial_gps->write(UBXscratch, msglen); \
|
_serial_gps->write(UBXscratch, msglen); \
|
||||||
if (getACK(TYPE, ID, TIMEOUT) != GNSS_RESPONSE_OK) { \
|
if (getACK(TYPE, ID, TIMEOUT) != GNSS_RESPONSE_OK) { \
|
||||||
LOG_WARN(#ERRMSG); \
|
LOG_WARN(failMessage, #ERRMSG); \
|
||||||
}
|
}
|
||||||
|
|
||||||
// Power Management
|
// Power Management
|
||||||
|
|||||||
@@ -79,13 +79,13 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Trigger the refresh in GxEPD2
|
// Trigger the refresh in GxEPD2
|
||||||
LOG_DEBUG("Updating E-Paper... ");
|
LOG_DEBUG("Updating E-Paper");
|
||||||
adafruitDisplay->nextPage();
|
adafruitDisplay->nextPage();
|
||||||
|
|
||||||
// End the update process
|
// End the update process
|
||||||
endUpdate();
|
endUpdate();
|
||||||
|
|
||||||
LOG_DEBUG("done\n");
|
LOG_DEBUG("done");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ void EInkDisplay::setDetected(uint8_t detected)
|
|||||||
// Connect to the display - variant specific
|
// Connect to the display - variant specific
|
||||||
bool EInkDisplay::connect()
|
bool EInkDisplay::connect()
|
||||||
{
|
{
|
||||||
LOG_INFO("Doing EInk init\n");
|
LOG_INFO("Doing EInk init");
|
||||||
|
|
||||||
#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
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ void EInkDynamicDisplay::endOrDetach()
|
|||||||
awaitRefresh();
|
awaitRefresh();
|
||||||
else {
|
else {
|
||||||
// Async begins
|
// Async begins
|
||||||
LOG_DEBUG("Async full-refresh begins (dropping frames)\n");
|
LOG_DEBUG("Async full-refresh begins (dropping frames)");
|
||||||
notifyLater(intervalPollAsyncRefresh, DUE_POLL_ASYNCREFRESH, true); // Hand-off to NotifiedWorkerThread
|
notifyLater(intervalPollAsyncRefresh, DUE_POLL_ASYNCREFRESH, true); // Hand-off to NotifiedWorkerThread
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,7 +133,7 @@ void EInkDynamicDisplay::endOrDetach()
|
|||||||
if (previousRefresh == FULL || previousRefresh == FAST) { // If refresh wasn't skipped (on unspecified..)
|
if (previousRefresh == FULL || previousRefresh == FAST) { // If refresh wasn't skipped (on unspecified..)
|
||||||
LOG_WARN(
|
LOG_WARN(
|
||||||
"GxEPD2 version has not been modified to support async refresh; using fallback behavior. Please update lib_deps in "
|
"GxEPD2 version has not been modified to support async refresh; using fallback behavior. Please update lib_deps in "
|
||||||
"variant's platformio.ini file\n");
|
"variant's platformio.ini file");
|
||||||
EInkDisplay::endUpdate();
|
EInkDisplay::endUpdate();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -170,7 +170,7 @@ bool EInkDynamicDisplay::determineMode()
|
|||||||
checkFastRequested();
|
checkFastRequested();
|
||||||
|
|
||||||
if (refresh == UNSPECIFIED)
|
if (refresh == UNSPECIFIED)
|
||||||
LOG_WARN("There was a flaw in the determineMode() logic.\n");
|
LOG_WARN("There was a flaw in the determineMode() logic.");
|
||||||
|
|
||||||
// -- Decision has been reached --
|
// -- Decision has been reached --
|
||||||
applyRefreshMode();
|
applyRefreshMode();
|
||||||
@@ -254,7 +254,7 @@ void EInkDynamicDisplay::checkRateLimiting()
|
|||||||
if (Throttle::isWithinTimespanMs(previousRunMs, EINK_LIMIT_RATE_RESPONSIVE_SEC * 1000)) {
|
if (Throttle::isWithinTimespanMs(previousRunMs, EINK_LIMIT_RATE_RESPONSIVE_SEC * 1000)) {
|
||||||
refresh = SKIPPED;
|
refresh = SKIPPED;
|
||||||
reason = EXCEEDED_RATELIMIT_FAST;
|
reason = EXCEEDED_RATELIMIT_FAST;
|
||||||
LOG_DEBUG("refresh=SKIPPED, reason=EXCEEDED_RATELIMIT_FAST, frameFlags=0x%x\n", frameFlags);
|
LOG_DEBUG("refresh=SKIPPED, reason=EXCEEDED_RATELIMIT_FAST, frameFlags=0x%x", frameFlags);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,7 +271,7 @@ void EInkDynamicDisplay::checkCosmetic()
|
|||||||
if (frameFlags & COSMETIC) {
|
if (frameFlags & COSMETIC) {
|
||||||
refresh = FULL;
|
refresh = FULL;
|
||||||
reason = FLAGGED_COSMETIC;
|
reason = FLAGGED_COSMETIC;
|
||||||
LOG_DEBUG("refresh=FULL, reason=FLAGGED_COSMETIC, frameFlags=0x%x\n", frameFlags);
|
LOG_DEBUG("refresh=FULL, reason=FLAGGED_COSMETIC, frameFlags=0x%x", frameFlags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,7 +286,7 @@ void EInkDynamicDisplay::checkDemandingFast()
|
|||||||
if (frameFlags & DEMAND_FAST) {
|
if (frameFlags & DEMAND_FAST) {
|
||||||
refresh = FAST;
|
refresh = FAST;
|
||||||
reason = FLAGGED_DEMAND_FAST;
|
reason = FLAGGED_DEMAND_FAST;
|
||||||
LOG_DEBUG("refresh=FAST, reason=FLAGGED_DEMAND_FAST, frameFlags=0x%x\n", frameFlags);
|
LOG_DEBUG("refresh=FAST, reason=FLAGGED_DEMAND_FAST, frameFlags=0x%x", frameFlags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,7 +306,7 @@ void EInkDynamicDisplay::checkFrameMatchesPrevious()
|
|||||||
if (frameFlags == BACKGROUND && fastRefreshCount > 0) {
|
if (frameFlags == BACKGROUND && fastRefreshCount > 0) {
|
||||||
refresh = FULL;
|
refresh = FULL;
|
||||||
reason = REDRAW_WITH_FULL;
|
reason = REDRAW_WITH_FULL;
|
||||||
LOG_DEBUG("refresh=FULL, reason=REDRAW_WITH_FULL, frameFlags=0x%x\n", frameFlags);
|
LOG_DEBUG("refresh=FULL, reason=REDRAW_WITH_FULL, frameFlags=0x%x", frameFlags);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -314,7 +314,7 @@ void EInkDynamicDisplay::checkFrameMatchesPrevious()
|
|||||||
// Not redrawn, not COSMETIC, not DEMAND_FAST
|
// Not redrawn, not COSMETIC, not DEMAND_FAST
|
||||||
refresh = SKIPPED;
|
refresh = SKIPPED;
|
||||||
reason = FRAME_MATCHED_PREVIOUS;
|
reason = FRAME_MATCHED_PREVIOUS;
|
||||||
LOG_DEBUG("refresh=SKIPPED, reason=FRAME_MATCHED_PREVIOUS, frameFlags=0x%x\n", frameFlags);
|
LOG_DEBUG("refresh=SKIPPED, reason=FRAME_MATCHED_PREVIOUS, frameFlags=0x%x", frameFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Have too many fast-refreshes occured consecutively, since last full refresh?
|
// Have too many fast-refreshes occured consecutively, since last full refresh?
|
||||||
@@ -328,7 +328,7 @@ void EInkDynamicDisplay::checkConsecutiveFastRefreshes()
|
|||||||
if (fastRefreshCount >= EINK_LIMIT_FASTREFRESH) {
|
if (fastRefreshCount >= EINK_LIMIT_FASTREFRESH) {
|
||||||
refresh = FULL;
|
refresh = FULL;
|
||||||
reason = EXCEEDED_LIMIT_FASTREFRESH;
|
reason = EXCEEDED_LIMIT_FASTREFRESH;
|
||||||
LOG_DEBUG("refresh=FULL, reason=EXCEEDED_LIMIT_FASTREFRESH, frameFlags=0x%x\n", frameFlags);
|
LOG_DEBUG("refresh=FULL, reason=EXCEEDED_LIMIT_FASTREFRESH, frameFlags=0x%x", frameFlags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,13 +343,13 @@ void EInkDynamicDisplay::checkFastRequested()
|
|||||||
// If we want BACKGROUND to use fast. (FULL only when a limit is hit)
|
// If we want BACKGROUND to use fast. (FULL only when a limit is hit)
|
||||||
refresh = FAST;
|
refresh = FAST;
|
||||||
reason = BACKGROUND_USES_FAST;
|
reason = BACKGROUND_USES_FAST;
|
||||||
LOG_DEBUG("refresh=FAST, reason=BACKGROUND_USES_FAST, fastRefreshCount=%lu, frameFlags=0x%x\n", fastRefreshCount,
|
LOG_DEBUG("refresh=FAST, reason=BACKGROUND_USES_FAST, fastRefreshCount=%lu, frameFlags=0x%x", fastRefreshCount,
|
||||||
frameFlags);
|
frameFlags);
|
||||||
#else
|
#else
|
||||||
// If we do want to use FULL for BACKGROUND updates
|
// If we do want to use FULL for BACKGROUND updates
|
||||||
refresh = FULL;
|
refresh = FULL;
|
||||||
reason = FLAGGED_BACKGROUND;
|
reason = FLAGGED_BACKGROUND;
|
||||||
LOG_DEBUG("refresh=FULL, reason=FLAGGED_BACKGROUND\n");
|
LOG_DEBUG("refresh=FULL, reason=FLAGGED_BACKGROUND");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,7 +357,7 @@ void EInkDynamicDisplay::checkFastRequested()
|
|||||||
if (frameFlags & RESPONSIVE) {
|
if (frameFlags & RESPONSIVE) {
|
||||||
refresh = FAST;
|
refresh = FAST;
|
||||||
reason = NO_OBJECTIONS;
|
reason = NO_OBJECTIONS;
|
||||||
LOG_DEBUG("refresh=FAST, reason=NO_OBJECTIONS, fastRefreshCount=%lu, frameFlags=0x%x\n", fastRefreshCount, frameFlags);
|
LOG_DEBUG("refresh=FAST, reason=NO_OBJECTIONS, fastRefreshCount=%lu, frameFlags=0x%x", fastRefreshCount, frameFlags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,7 +438,7 @@ void EInkDynamicDisplay::checkExcessiveGhosting()
|
|||||||
if (ghostPixelCount > EINK_LIMIT_GHOSTING_PX) {
|
if (ghostPixelCount > EINK_LIMIT_GHOSTING_PX) {
|
||||||
refresh = FULL;
|
refresh = FULL;
|
||||||
reason = EXCEEDED_GHOSTINGLIMIT;
|
reason = EXCEEDED_GHOSTINGLIMIT;
|
||||||
LOG_DEBUG("refresh=FULL, reason=EXCEEDED_GHOSTINGLIMIT, frameFlags=0x%x\n", frameFlags);
|
LOG_DEBUG("refresh=FULL, reason=EXCEEDED_GHOSTINGLIMIT, frameFlags=0x%x", frameFlags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -469,7 +469,7 @@ void EInkDynamicDisplay::joinAsyncRefresh()
|
|||||||
if (!asyncRefreshRunning)
|
if (!asyncRefreshRunning)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LOG_DEBUG("Joining an async refresh in progress\n");
|
LOG_DEBUG("Joining an async refresh in progress");
|
||||||
|
|
||||||
// Continually poll the BUSY pin
|
// Continually poll the BUSY pin
|
||||||
while (adafruitDisplay->epd2.isBusy())
|
while (adafruitDisplay->epd2.isBusy())
|
||||||
@@ -479,7 +479,7 @@ void EInkDynamicDisplay::joinAsyncRefresh()
|
|||||||
adafruitDisplay->endAsyncFull(); // Run the end of nextPage() code
|
adafruitDisplay->endAsyncFull(); // Run the end of nextPage() code
|
||||||
EInkDisplay::endUpdate(); // Run base-class code to finish off update (NOT our derived class override)
|
EInkDisplay::endUpdate(); // Run base-class code to finish off update (NOT our derived class override)
|
||||||
asyncRefreshRunning = false; // Unset the flag
|
asyncRefreshRunning = false; // Unset the flag
|
||||||
LOG_DEBUG("Refresh complete\n");
|
LOG_DEBUG("Refresh complete");
|
||||||
|
|
||||||
// Note: this code only works because of a modification to meshtastic/GxEPD2.
|
// Note: this code only works because of a modification to meshtastic/GxEPD2.
|
||||||
// It is only equipped to intercept calls to nextPage()
|
// It is only equipped to intercept calls to nextPage()
|
||||||
@@ -503,7 +503,7 @@ void EInkDynamicDisplay::pollAsyncRefresh()
|
|||||||
adafruitDisplay->endAsyncFull(); // Run the end of nextPage() code
|
adafruitDisplay->endAsyncFull(); // Run the end of nextPage() code
|
||||||
EInkDisplay::endUpdate(); // Run base-class code to finish off update (NOT our derived class override)
|
EInkDisplay::endUpdate(); // Run base-class code to finish off update (NOT our derived class override)
|
||||||
asyncRefreshRunning = false; // Unset the flag
|
asyncRefreshRunning = false; // Unset the flag
|
||||||
LOG_DEBUG("Async full-refresh complete\n");
|
LOG_DEBUG("Async full-refresh complete");
|
||||||
|
|
||||||
// Note: this code only works because of a modification to meshtastic/GxEPD2.
|
// Note: this code only works because of a modification to meshtastic/GxEPD2.
|
||||||
// It is only equipped to intercept calls to nextPage()
|
// It is only equipped to intercept calls to nextPage()
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ static bool haveGlyphs(const char *str)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("haveGlyphs=%d\n", have);
|
LOG_DEBUG("haveGlyphs=%d", have);
|
||||||
return have;
|
return have;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,8 +163,8 @@ static void drawIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDispl
|
|||||||
|
|
||||||
display->setFont(FONT_MEDIUM);
|
display->setFont(FONT_MEDIUM);
|
||||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||||
#ifdef SPLASH_TITLE_USERPREFS
|
#ifdef USERPREFS_SPLASH_TITLE
|
||||||
const char *title = SPLASH_TITLE_USERPREFS;
|
const char *title = USERPREFS_SPLASH_TITLE;
|
||||||
#else
|
#else
|
||||||
const char *title = "meshtastic.org";
|
const char *title = "meshtastic.org";
|
||||||
#endif
|
#endif
|
||||||
@@ -186,56 +186,6 @@ static void drawIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDispl
|
|||||||
display->setTextAlignment(TEXT_ALIGN_LEFT); // Restore left align, just to be kind to any other unsuspecting code
|
display->setTextAlignment(TEXT_ALIGN_LEFT); // Restore left align, just to be kind to any other unsuspecting code
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drawOEMIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
|
||||||
{
|
|
||||||
// draw an xbm image.
|
|
||||||
// Please note that everything that should be transitioned
|
|
||||||
// needs to be drawn relative to x and y
|
|
||||||
|
|
||||||
// draw centered icon left to right and centered above the one line of app text
|
|
||||||
display->drawXbm(x + (SCREEN_WIDTH - oemStore.oem_icon_width) / 2,
|
|
||||||
y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - oemStore.oem_icon_height) / 2 + 2, oemStore.oem_icon_width,
|
|
||||||
oemStore.oem_icon_height, (const uint8_t *)oemStore.oem_icon_bits.bytes);
|
|
||||||
|
|
||||||
switch (oemStore.oem_font) {
|
|
||||||
case 0:
|
|
||||||
display->setFont(FONT_SMALL);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
display->setFont(FONT_LARGE);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
display->setFont(FONT_MEDIUM);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
|
||||||
const char *title = oemStore.oem_text;
|
|
||||||
display->drawString(x + getStringCenteredX(title), y + SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM, title);
|
|
||||||
display->setFont(FONT_SMALL);
|
|
||||||
|
|
||||||
// Draw region in upper left
|
|
||||||
if (upperMsg)
|
|
||||||
display->drawString(x + 0, y + 0, upperMsg);
|
|
||||||
|
|
||||||
// Draw version and shortname in upper right
|
|
||||||
char buf[25];
|
|
||||||
snprintf(buf, sizeof(buf), "%s\n%s", xstr(APP_VERSION_SHORT), haveGlyphs(owner.short_name) ? owner.short_name : "");
|
|
||||||
|
|
||||||
display->setTextAlignment(TEXT_ALIGN_RIGHT);
|
|
||||||
display->drawString(x + SCREEN_WIDTH, y + 0, buf);
|
|
||||||
screen->forceDisplay();
|
|
||||||
|
|
||||||
display->setTextAlignment(TEXT_ALIGN_LEFT); // Restore left align, just to be kind to any other unsuspecting code
|
|
||||||
}
|
|
||||||
|
|
||||||
static void drawOEMBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
|
||||||
{
|
|
||||||
// Draw region in upper left
|
|
||||||
const char *region = myRegion ? myRegion->name : NULL;
|
|
||||||
drawOEMIconScreen(region, display, state, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Screen::drawFrameText(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y, const char *message)
|
void Screen::drawFrameText(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y, const char *message)
|
||||||
{
|
{
|
||||||
uint16_t x_offset = display->width() / 2;
|
uint16_t x_offset = display->width() / 2;
|
||||||
@@ -292,7 +242,7 @@ static void drawWelcomeScreen(OLEDDisplay *display, OLEDDisplayUiState *state, i
|
|||||||
// draw overlay in bottom right corner of screen to show when notifications are muted or modifier key is active
|
// draw overlay in bottom right corner of screen to show when notifications are muted or modifier key is active
|
||||||
static void drawFunctionOverlay(OLEDDisplay *display, OLEDDisplayUiState *state)
|
static void drawFunctionOverlay(OLEDDisplay *display, OLEDDisplayUiState *state)
|
||||||
{
|
{
|
||||||
// LOG_DEBUG("Drawing function overlay\n");
|
// LOG_DEBUG("Drawing function overlay");
|
||||||
if (functionSymbals.begin() != functionSymbals.end()) {
|
if (functionSymbals.begin() != functionSymbals.end()) {
|
||||||
char buf[64];
|
char buf[64];
|
||||||
display->setFont(FONT_SMALL);
|
display->setFont(FONT_SMALL);
|
||||||
@@ -310,7 +260,7 @@ static void drawDeepSleepScreen(OLEDDisplay *display, OLEDDisplayUiState *state,
|
|||||||
EINK_ADD_FRAMEFLAG(display, COSMETIC);
|
EINK_ADD_FRAMEFLAG(display, COSMETIC);
|
||||||
EINK_ADD_FRAMEFLAG(display, BLOCKING);
|
EINK_ADD_FRAMEFLAG(display, BLOCKING);
|
||||||
|
|
||||||
LOG_DEBUG("Drawing deep sleep screen\n");
|
LOG_DEBUG("Drawing deep sleep screen");
|
||||||
|
|
||||||
// Display displayStr on the screen
|
// Display displayStr on the screen
|
||||||
drawIconScreen("Sleeping", display, state, x, y);
|
drawIconScreen("Sleeping", display, state, x, y);
|
||||||
@@ -319,7 +269,7 @@ static void drawDeepSleepScreen(OLEDDisplay *display, OLEDDisplayUiState *state,
|
|||||||
/// Used on eink displays when screen updates are paused
|
/// Used on eink displays when screen updates are paused
|
||||||
static void drawScreensaverOverlay(OLEDDisplay *display, OLEDDisplayUiState *state)
|
static void drawScreensaverOverlay(OLEDDisplay *display, OLEDDisplayUiState *state)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Drawing screensaver overlay\n");
|
LOG_DEBUG("Drawing screensaver overlay");
|
||||||
|
|
||||||
EINK_ADD_FRAMEFLAG(display, COSMETIC); // Take the opportunity for a full-refresh
|
EINK_ADD_FRAMEFLAG(display, COSMETIC); // Take the opportunity for a full-refresh
|
||||||
|
|
||||||
@@ -385,9 +335,9 @@ static void drawModuleFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int
|
|||||||
} else {
|
} else {
|
||||||
// otherwise, just display the module frame that's aligned with the current frame
|
// otherwise, just display the module frame that's aligned with the current frame
|
||||||
module_frame = state->currentFrame;
|
module_frame = state->currentFrame;
|
||||||
// LOG_DEBUG("Screen is not in transition. Frame: %d\n\n", module_frame);
|
// LOG_DEBUG("Screen is not in transition. Frame: %d", module_frame);
|
||||||
}
|
}
|
||||||
// LOG_DEBUG("Drawing Module Frame %d\n\n", module_frame);
|
// LOG_DEBUG("Drawing Module Frame %d", module_frame);
|
||||||
MeshModule &pi = *moduleFrames.at(module_frame);
|
MeshModule &pi = *moduleFrames.at(module_frame);
|
||||||
pi.drawFrame(display, state, x, y);
|
pi.drawFrame(display, state, x, y);
|
||||||
}
|
}
|
||||||
@@ -497,7 +447,7 @@ void Screen::drawDigitalClockFrame(OLEDDisplay *display, OLEDDisplayUiState *sta
|
|||||||
display->drawString(x + 20, y + 2, batteryPercent);
|
display->drawString(x + 20, y + 2, batteryPercent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nimbleBluetooth->isConnected()) {
|
if (nimbleBluetooth && nimbleBluetooth->isConnected()) {
|
||||||
drawBluetoothConnectedIcon(display, display->getWidth() - 18, y + 2);
|
drawBluetoothConnectedIcon(display, display->getWidth() - 18, y + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -729,7 +679,7 @@ void Screen::drawAnalogClockFrame(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
display->drawString(x + 20, y + 2, batteryPercent);
|
display->drawString(x + 20, y + 2, batteryPercent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nimbleBluetooth->isConnected()) {
|
if (nimbleBluetooth && nimbleBluetooth->isConnected()) {
|
||||||
drawBluetoothConnectedIcon(display, display->getWidth() - 18, y + 2);
|
drawBluetoothConnectedIcon(display, display->getWidth() - 18, y + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -962,7 +912,7 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
|
|||||||
|
|
||||||
const meshtastic_MeshPacket &mp = devicestate.rx_text_message;
|
const meshtastic_MeshPacket &mp = devicestate.rx_text_message;
|
||||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(getFrom(&mp));
|
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(getFrom(&mp));
|
||||||
// LOG_DEBUG("drawing text message from 0x%x: %s\n", mp.from,
|
// LOG_DEBUG("drawing text message from 0x%x: %s", mp.from,
|
||||||
// mp.decoded.variant.data.decoded.bytes);
|
// mp.decoded.variant.data.decoded.bytes);
|
||||||
|
|
||||||
// Demo for drawStringMaxWidth:
|
// Demo for drawStringMaxWidth:
|
||||||
@@ -1097,8 +1047,8 @@ static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const NodeStat
|
|||||||
{
|
{
|
||||||
char usersString[20];
|
char usersString[20];
|
||||||
snprintf(usersString, sizeof(usersString), "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
|
snprintf(usersString, sizeof(usersString), "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
|
||||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \
|
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
||||||
defined(USE_ST7789) || defined(HX8357_CS)) && \
|
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS)) && \
|
||||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||||
display->drawFastImage(x, y + 3, 8, 8, imgUser);
|
display->drawFastImage(x, y + 3, 8, 8, imgUser);
|
||||||
#else
|
#else
|
||||||
@@ -1500,7 +1450,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
|||||||
if (!hasNodeHeading) {
|
if (!hasNodeHeading) {
|
||||||
// direction to node is unknown so display question mark
|
// direction to node is unknown so display question mark
|
||||||
// Debug info for gps lock errors
|
// Debug info for gps lock errors
|
||||||
// LOG_DEBUG("ourNode %d, ourPos %d, theirPos %d\n", !!ourNode, ourNode && hasValidPosition(ourNode),
|
// LOG_DEBUG("ourNode %d, ourPos %d, theirPos %d", !!ourNode, ourNode && hasValidPosition(ourNode),
|
||||||
// hasValidPosition(node));
|
// hasValidPosition(node));
|
||||||
display->drawString(compassX - FONT_HEIGHT_SMALL / 4, compassY - FONT_HEIGHT_SMALL / 2, "?");
|
display->drawString(compassX - FONT_HEIGHT_SMALL / 4, compassY - FONT_HEIGHT_SMALL / 2, "?");
|
||||||
}
|
}
|
||||||
@@ -1534,8 +1484,8 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O
|
|||||||
#elif defined(USE_SSD1306)
|
#elif defined(USE_SSD1306)
|
||||||
dispdev = new SSD1306Wire(address.address, -1, -1, geometry,
|
dispdev = new SSD1306Wire(address.address, -1, -1, geometry,
|
||||||
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
||||||
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7789_CS) || defined(RAK14014) || \
|
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7789_CS) || \
|
||||||
defined(HX8357_CS)
|
defined(RAK14014) || defined(HX8357_CS)
|
||||||
dispdev = new TFTDisplay(address.address, -1, -1, geometry,
|
dispdev = new TFTDisplay(address.address, -1, -1, geometry,
|
||||||
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
||||||
#elif defined(USE_EINK) && !defined(USE_EINK_DYNAMICDISPLAY)
|
#elif defined(USE_EINK) && !defined(USE_EINK_DYNAMICDISPLAY)
|
||||||
@@ -1549,7 +1499,7 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O
|
|||||||
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
||||||
#elif ARCH_PORTDUINO
|
#elif ARCH_PORTDUINO
|
||||||
if (settingsMap[displayPanel] != no_screen) {
|
if (settingsMap[displayPanel] != no_screen) {
|
||||||
LOG_DEBUG("Making TFTDisplay!\n");
|
LOG_DEBUG("Making TFTDisplay!");
|
||||||
dispdev = new TFTDisplay(address.address, -1, -1, geometry,
|
dispdev = new TFTDisplay(address.address, -1, -1, geometry,
|
||||||
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
||||||
} else {
|
} else {
|
||||||
@@ -1596,7 +1546,7 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver)
|
|||||||
|
|
||||||
if (on != screenOn) {
|
if (on != screenOn) {
|
||||||
if (on) {
|
if (on) {
|
||||||
LOG_INFO("Turning on screen\n");
|
LOG_INFO("Turning on screen");
|
||||||
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);
|
||||||
@@ -1631,7 +1581,7 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver)
|
|||||||
// eInkScreensaver parameter is usually NULL (default argument), default frame used instead
|
// eInkScreensaver parameter is usually NULL (default argument), default frame used instead
|
||||||
setScreensaverFrames(einkScreensaver);
|
setScreensaverFrames(einkScreensaver);
|
||||||
#endif
|
#endif
|
||||||
LOG_INFO("Turning off screen\n");
|
LOG_INFO("Turning off screen");
|
||||||
dispdev->displayOff();
|
dispdev->displayOff();
|
||||||
#ifdef USE_ST7789
|
#ifdef USE_ST7789
|
||||||
SPI1.end();
|
SPI1.end();
|
||||||
@@ -1699,9 +1649,6 @@ void Screen::setup()
|
|||||||
// Set the utf8 conversion function
|
// Set the utf8 conversion function
|
||||||
dispdev->setFontTableLookupFunction(customFontTableLookup);
|
dispdev->setFontTableLookupFunction(customFontTableLookup);
|
||||||
|
|
||||||
if (strlen(oemStore.oem_text) > 0)
|
|
||||||
logo_timeout *= 2;
|
|
||||||
|
|
||||||
// Add frames.
|
// Add frames.
|
||||||
EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST);
|
EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST);
|
||||||
alertFrames[0] = [this](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
|
alertFrames[0] = [this](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
|
||||||
@@ -1732,8 +1679,8 @@ void Screen::setup()
|
|||||||
// Standard behaviour is to FLIP the screen (needed on T-Beam). If this config item is set, unflip it, and thereby logically
|
// Standard behaviour is to FLIP the screen (needed on T-Beam). If this config item is set, unflip it, and thereby logically
|
||||||
// flip it. If you have a headache now, you're welcome.
|
// flip it. If you have a headache now, you're welcome.
|
||||||
if (!config.display.flip_screen) {
|
if (!config.display.flip_screen) {
|
||||||
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7789_CS) || \
|
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || \
|
||||||
defined(RAK14014) || defined(HX8357_CS)
|
defined(ST7789_CS) || defined(RAK14014) || defined(HX8357_CS)
|
||||||
static_cast<TFTDisplay *>(dispdev)->flipScreenVertically();
|
static_cast<TFTDisplay *>(dispdev)->flipScreenVertically();
|
||||||
#elif defined(USE_ST7789)
|
#elif defined(USE_ST7789)
|
||||||
static_cast<ST7789Spi *>(dispdev)->flipScreenVertically();
|
static_cast<ST7789Spi *>(dispdev)->flipScreenVertically();
|
||||||
@@ -1842,28 +1789,11 @@ int32_t Screen::runOnce()
|
|||||||
// serialSinceMsec adjusts for additional serial wait time during nRF52 bootup
|
// serialSinceMsec adjusts for additional serial wait time during nRF52 bootup
|
||||||
static bool showingBootScreen = true;
|
static bool showingBootScreen = true;
|
||||||
if (showingBootScreen && (millis() > (logo_timeout + serialSinceMsec))) {
|
if (showingBootScreen && (millis() > (logo_timeout + serialSinceMsec))) {
|
||||||
LOG_INFO("Done with boot screen...\n");
|
LOG_INFO("Done with boot screen...");
|
||||||
stopBootScreen();
|
stopBootScreen();
|
||||||
showingBootScreen = false;
|
showingBootScreen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have an OEM Boot screen, toggle after logo_timeout seconds
|
|
||||||
if (strlen(oemStore.oem_text) > 0) {
|
|
||||||
static bool showingOEMBootScreen = true;
|
|
||||||
if (showingOEMBootScreen && (millis() > ((logo_timeout / 2) + serialSinceMsec))) {
|
|
||||||
LOG_INFO("Switch to OEM screen...\n");
|
|
||||||
// Change frames.
|
|
||||||
static FrameCallback bootOEMFrames[] = {drawOEMBootScreen};
|
|
||||||
static const int bootOEMFrameCount = sizeof(bootOEMFrames) / sizeof(bootOEMFrames[0]);
|
|
||||||
ui->setFrames(bootOEMFrames, bootOEMFrameCount);
|
|
||||||
ui->update();
|
|
||||||
#ifndef USE_EINK
|
|
||||||
ui->update();
|
|
||||||
#endif
|
|
||||||
showingOEMBootScreen = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef DISABLE_WELCOME_UNSET
|
#ifndef DISABLE_WELCOME_UNSET
|
||||||
if (showingNormalScreen && config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET) {
|
if (showingNormalScreen && config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET) {
|
||||||
setWelcomeFrames();
|
setWelcomeFrames();
|
||||||
@@ -1917,7 +1847,7 @@ int32_t Screen::runOnce()
|
|||||||
free(cmd.print_text);
|
free(cmd.print_text);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR("Invalid screen cmd\n");
|
LOG_ERROR("Invalid screen cmd");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1955,12 +1885,12 @@ int32_t Screen::runOnce()
|
|||||||
EINK_ADD_FRAMEFLAG(dispdev, COSMETIC);
|
EINK_ADD_FRAMEFLAG(dispdev, COSMETIC);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LOG_DEBUG("LastScreenTransition exceeded %ums transitioning to next frame\n", (millis() - lastScreenTransition));
|
LOG_DEBUG("LastScreenTransition exceeded %ums transitioning to next frame", (millis() - lastScreenTransition));
|
||||||
handleOnPress();
|
handleOnPress();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LOG_DEBUG("want fps %d, fixed=%d\n", targetFramerate,
|
// LOG_DEBUG("want fps %d, fixed=%d", targetFramerate,
|
||||||
// ui->getUiState()->frameState); If we are scrolling we need to be called
|
// ui->getUiState()->frameState); If we are scrolling we need to be called
|
||||||
// soon, otherwise just 1 fps (to save CPU) We also ask to be called twice
|
// soon, otherwise just 1 fps (to save CPU) We also ask to be called twice
|
||||||
// as fast as we really need so that any rounding errors still result with
|
// as fast as we really need so that any rounding errors still result with
|
||||||
@@ -1991,7 +1921,7 @@ void Screen::drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiStat
|
|||||||
void Screen::setSSLFrames()
|
void Screen::setSSLFrames()
|
||||||
{
|
{
|
||||||
if (address_found.address) {
|
if (address_found.address) {
|
||||||
// LOG_DEBUG("showing SSL frames\n");
|
// LOG_DEBUG("showing SSL frames");
|
||||||
static FrameCallback sslFrames[] = {drawSSLScreen};
|
static FrameCallback sslFrames[] = {drawSSLScreen};
|
||||||
ui->setFrames(sslFrames, 1);
|
ui->setFrames(sslFrames, 1);
|
||||||
ui->update();
|
ui->update();
|
||||||
@@ -2003,7 +1933,7 @@ void Screen::setSSLFrames()
|
|||||||
void Screen::setWelcomeFrames()
|
void Screen::setWelcomeFrames()
|
||||||
{
|
{
|
||||||
if (address_found.address) {
|
if (address_found.address) {
|
||||||
// LOG_DEBUG("showing Welcome frames\n");
|
// LOG_DEBUG("showing Welcome frames");
|
||||||
static FrameCallback frames[] = {drawWelcomeScreen};
|
static FrameCallback frames[] = {drawWelcomeScreen};
|
||||||
setFrameImmediateDraw(frames);
|
setFrameImmediateDraw(frames);
|
||||||
}
|
}
|
||||||
@@ -2069,7 +1999,7 @@ void Screen::setFrames(FrameFocus focus)
|
|||||||
uint8_t originalPosition = ui->getUiState()->currentFrame;
|
uint8_t originalPosition = ui->getUiState()->currentFrame;
|
||||||
FramesetInfo fsi; // Location of specific frames, for applying focus parameter
|
FramesetInfo fsi; // Location of specific frames, for applying focus parameter
|
||||||
|
|
||||||
LOG_DEBUG("showing standard frames\n");
|
LOG_DEBUG("showing standard frames");
|
||||||
showingNormalScreen = true;
|
showingNormalScreen = true;
|
||||||
|
|
||||||
#ifdef USE_EINK
|
#ifdef USE_EINK
|
||||||
@@ -2082,10 +2012,10 @@ void Screen::setFrames(FrameFocus focus)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
moduleFrames = MeshModule::GetMeshModulesWithUIFrames();
|
moduleFrames = MeshModule::GetMeshModulesWithUIFrames();
|
||||||
LOG_DEBUG("Showing %d module frames\n", moduleFrames.size());
|
LOG_DEBUG("Showing %d module frames", moduleFrames.size());
|
||||||
#ifdef DEBUG_PORT
|
#ifdef DEBUG_PORT
|
||||||
int totalFrameCount = MAX_NUM_NODES + NUM_EXTRA_FRAMES + moduleFrames.size();
|
int totalFrameCount = MAX_NUM_NODES + NUM_EXTRA_FRAMES + moduleFrames.size();
|
||||||
LOG_DEBUG("Total frame count: %d\n", totalFrameCount);
|
LOG_DEBUG("Total frame count: %d", totalFrameCount);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// We don't show the node info of our node (if we have it yet - we should)
|
// We don't show the node info of our node (if we have it yet - we should)
|
||||||
@@ -2119,7 +2049,7 @@ void Screen::setFrames(FrameFocus focus)
|
|||||||
numframes++;
|
numframes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("Added modules. numframes: %d\n", numframes);
|
LOG_DEBUG("Added modules. numframes: %d", numframes);
|
||||||
|
|
||||||
// If we have a critical fault, show it first
|
// If we have a critical fault, show it first
|
||||||
fsi.positions.fault = numframes;
|
fsi.positions.fault = numframes;
|
||||||
@@ -2164,7 +2094,7 @@ void Screen::setFrames(FrameFocus focus)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
fsi.frameCount = numframes; // Total framecount is used to apply FOCUS_PRESERVE
|
fsi.frameCount = numframes; // Total framecount is used to apply FOCUS_PRESERVE
|
||||||
LOG_DEBUG("Finished building frames. numframes: %d\n", numframes);
|
LOG_DEBUG("Finished building frames. numframes: %d", numframes);
|
||||||
|
|
||||||
ui->setFrames(normalFrames, numframes);
|
ui->setFrames(normalFrames, numframes);
|
||||||
ui->enableAllIndicators();
|
ui->enableAllIndicators();
|
||||||
@@ -2245,13 +2175,13 @@ void Screen::dismissCurrentFrame()
|
|||||||
bool dismissed = false;
|
bool dismissed = false;
|
||||||
|
|
||||||
if (currentFrame == framesetInfo.positions.textMessage && devicestate.has_rx_text_message) {
|
if (currentFrame == framesetInfo.positions.textMessage && devicestate.has_rx_text_message) {
|
||||||
LOG_INFO("Dismissing Text Message\n");
|
LOG_INFO("Dismissing Text Message");
|
||||||
devicestate.has_rx_text_message = false;
|
devicestate.has_rx_text_message = false;
|
||||||
dismissed = true;
|
dismissed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (currentFrame == framesetInfo.positions.waypoint && devicestate.has_rx_waypoint) {
|
else if (currentFrame == framesetInfo.positions.waypoint && devicestate.has_rx_waypoint) {
|
||||||
LOG_DEBUG("Dismissing Waypoint\n");
|
LOG_DEBUG("Dismissing Waypoint");
|
||||||
devicestate.has_rx_waypoint = false;
|
devicestate.has_rx_waypoint = false;
|
||||||
dismissed = true;
|
dismissed = true;
|
||||||
}
|
}
|
||||||
@@ -2263,7 +2193,7 @@ void Screen::dismissCurrentFrame()
|
|||||||
|
|
||||||
void Screen::handleStartFirmwareUpdateScreen()
|
void Screen::handleStartFirmwareUpdateScreen()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("showing firmware screen\n");
|
LOG_DEBUG("showing firmware screen");
|
||||||
showingNormalScreen = false;
|
showingNormalScreen = false;
|
||||||
EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST); // E-Ink: Explicitly use fast-refresh for next frame
|
EINK_ADD_FRAMEFLAG(dispdev, DEMAND_FAST); // E-Ink: Explicitly use fast-refresh for next frame
|
||||||
|
|
||||||
@@ -2355,7 +2285,7 @@ void Screen::handlePrint(const char *text)
|
|||||||
{
|
{
|
||||||
// the string passed into us probably has a newline, but that would confuse the logging system
|
// the string passed into us probably has a newline, but that would confuse the logging system
|
||||||
// so strip it
|
// so strip it
|
||||||
LOG_DEBUG("Screen: %.*s\n", strlen(text) - 1, text);
|
LOG_DEBUG("Screen: %.*s", strlen(text) - 1, text);
|
||||||
if (!useDisplay || !showingNormalScreen)
|
if (!useDisplay || !showingNormalScreen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -2472,8 +2402,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
|||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
if (!Throttle::isWithinTimespanMs(storeForwardModule->lastHeartbeat,
|
if (!Throttle::isWithinTimespanMs(storeForwardModule->lastHeartbeat,
|
||||||
(storeForwardModule->heartbeatInterval * 1200))) { // no heartbeat, overlap a bit
|
(storeForwardModule->heartbeatInterval * 1200))) { // no heartbeat, overlap a bit
|
||||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \
|
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
||||||
defined(USE_ST7789) || defined(HX8357_CS)) && \
|
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || ARCH_PORTDUINO) && \
|
||||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
||||||
imgQuestionL1);
|
imgQuestionL1);
|
||||||
@@ -2484,8 +2414,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
|||||||
imgQuestion);
|
imgQuestion);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \
|
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
||||||
defined(USE_ST7789) || defined(HX8357_CS)) && \
|
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS)) && \
|
||||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||||
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 16, 8,
|
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 16, 8,
|
||||||
imgSFL1);
|
imgSFL1);
|
||||||
@@ -2499,8 +2429,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
|||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
// TODO: Raspberry Pi supports more than just the one screen size
|
// TODO: Raspberry Pi supports more than just the one screen size
|
||||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \
|
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
||||||
defined(USE_ST7789) || defined(HX8357_CS) || ARCH_PORTDUINO) && \
|
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || ARCH_PORTDUINO) && \
|
||||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
||||||
imgInfoL1);
|
imgInfoL1);
|
||||||
@@ -2708,7 +2638,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
|
|
||||||
int Screen::handleStatusUpdate(const meshtastic::Status *arg)
|
int Screen::handleStatusUpdate(const meshtastic::Status *arg)
|
||||||
{
|
{
|
||||||
// LOG_DEBUG("Screen got status update %d\n", arg->getStatusType());
|
// LOG_DEBUG("Screen got status update %d", arg->getStatusType());
|
||||||
switch (arg->getStatusType()) {
|
switch (arg->getStatusType()) {
|
||||||
case STATUS_TYPE_NODE:
|
case STATUS_TYPE_NODE:
|
||||||
if (showingNormalScreen && nodeStatus->getLastNumTotal() != nodeStatus->getNumTotal()) {
|
if (showingNormalScreen && nodeStatus->getLastNumTotal() != nodeStatus->getNumTotal()) {
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
#include "graphics/fonts/OLEDDisplayFontsUA.h"
|
#include "graphics/fonts/OLEDDisplayFontsUA.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \
|
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
||||||
defined(USE_ST7789) || defined(HX8357_CS)) && \
|
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS)) && \
|
||||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||||
// The screen is bigger so use bigger fonts
|
// The screen is bigger so use bigger fonts
|
||||||
#define FONT_SMALL ArialMT_Plain_16 // Height: 19
|
#define FONT_SMALL ArialMT_Plain_16 // Height: 19
|
||||||
@@ -41,4 +41,4 @@
|
|||||||
|
|
||||||
#define FONT_HEIGHT_SMALL _fontHeight(FONT_SMALL)
|
#define FONT_HEIGHT_SMALL _fontHeight(FONT_SMALL)
|
||||||
#define FONT_HEIGHT_MEDIUM _fontHeight(FONT_MEDIUM)
|
#define FONT_HEIGHT_MEDIUM _fontHeight(FONT_MEDIUM)
|
||||||
#define FONT_HEIGHT_LARGE _fontHeight(FONT_LARGE)
|
#define FONT_HEIGHT_LARGE _fontHeight(FONT_LARGE)
|
||||||
|
|||||||
@@ -244,9 +244,9 @@ class LGFX : public lgfx::LGFX_Device
|
|||||||
|
|
||||||
static LGFX *tft = nullptr;
|
static LGFX *tft = nullptr;
|
||||||
|
|
||||||
#elif defined(ILI9341_DRIVER)
|
#elif defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER)
|
||||||
|
|
||||||
#include <LovyanGFX.hpp> // Graphics and font library for ILI9341 driver chip
|
#include <LovyanGFX.hpp> // Graphics and font library for ILI9341/ILI9342 driver chip
|
||||||
|
|
||||||
#if defined(ILI9341_BACKLIGHT_EN) && !defined(TFT_BL)
|
#if defined(ILI9341_BACKLIGHT_EN) && !defined(TFT_BL)
|
||||||
#define TFT_BL ILI9341_BACKLIGHT_EN
|
#define TFT_BL ILI9341_BACKLIGHT_EN
|
||||||
@@ -254,7 +254,11 @@ static LGFX *tft = nullptr;
|
|||||||
|
|
||||||
class LGFX : public lgfx::LGFX_Device
|
class LGFX : public lgfx::LGFX_Device
|
||||||
{
|
{
|
||||||
|
#if defined(ILI9341_DRIVER)
|
||||||
lgfx::Panel_ILI9341 _panel_instance;
|
lgfx::Panel_ILI9341 _panel_instance;
|
||||||
|
#elif defined(ILI9342_DRIVER)
|
||||||
|
lgfx::Panel_ILI9342 _panel_instance;
|
||||||
|
#endif
|
||||||
lgfx::Bus_SPI _bus_instance;
|
lgfx::Bus_SPI _bus_instance;
|
||||||
lgfx::Light_PWM _light_instance;
|
lgfx::Light_PWM _light_instance;
|
||||||
|
|
||||||
@@ -265,7 +269,11 @@ class LGFX : public lgfx::LGFX_Device
|
|||||||
auto cfg = _bus_instance.config();
|
auto cfg = _bus_instance.config();
|
||||||
|
|
||||||
// configure SPI
|
// configure SPI
|
||||||
|
#if defined(ILI9341_DRIVER)
|
||||||
cfg.spi_host = ILI9341_SPI_HOST; // ESP32-S2,S3,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
|
cfg.spi_host = ILI9341_SPI_HOST; // ESP32-S2,S3,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
|
||||||
|
#elif defined(ILI9342_DRIVER)
|
||||||
|
cfg.spi_host = ILI9342_SPI_HOST; // ESP32-S2,S3,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
|
||||||
|
#endif
|
||||||
cfg.spi_mode = 0;
|
cfg.spi_mode = 0;
|
||||||
cfg.freq_write = SPI_FREQUENCY; // SPI clock for transmission (up to 80MHz, rounded to the value obtained by dividing
|
cfg.freq_write = SPI_FREQUENCY; // SPI clock for transmission (up to 80MHz, rounded to the value obtained by dividing
|
||||||
// 80MHz by an integer)
|
// 80MHz by an integer)
|
||||||
@@ -336,7 +344,7 @@ class LGFX : public lgfx::LGFX_Device
|
|||||||
static LGFX *tft = nullptr;
|
static LGFX *tft = nullptr;
|
||||||
|
|
||||||
#elif defined(ST7735_CS)
|
#elif defined(ST7735_CS)
|
||||||
#include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip
|
#include <TFT_eSPI.h> // Graphics and font library for ILI9342 driver chip
|
||||||
|
|
||||||
static TFT_eSPI *tft = nullptr; // Invoke library, pins defined in User_Setup.h
|
static TFT_eSPI *tft = nullptr; // Invoke library, pins defined in User_Setup.h
|
||||||
#elif ARCH_PORTDUINO && HAS_SCREEN != 0
|
#elif ARCH_PORTDUINO && HAS_SCREEN != 0
|
||||||
@@ -360,6 +368,8 @@ class LGFX : public lgfx::LGFX_Device
|
|||||||
_panel_instance = new lgfx::Panel_ST7735S;
|
_panel_instance = new lgfx::Panel_ST7735S;
|
||||||
else if (settingsMap[displayPanel] == ili9341)
|
else if (settingsMap[displayPanel] == ili9341)
|
||||||
_panel_instance = new lgfx::Panel_ILI9341;
|
_panel_instance = new lgfx::Panel_ILI9341;
|
||||||
|
else if (settingsMap[displayPanel] == ili9342)
|
||||||
|
_panel_instance = new lgfx::Panel_ILI9342;
|
||||||
auto buscfg = _bus_instance.config();
|
auto buscfg = _bus_instance.config();
|
||||||
buscfg.spi_mode = 0;
|
buscfg.spi_mode = 0;
|
||||||
buscfg.spi_host = settingsMap[displayspidev];
|
buscfg.spi_host = settingsMap[displayspidev];
|
||||||
@@ -370,7 +380,7 @@ class LGFX : public lgfx::LGFX_Device
|
|||||||
_panel_instance->setBus(&_bus_instance); // set the bus on the panel.
|
_panel_instance->setBus(&_bus_instance); // set the bus on the panel.
|
||||||
|
|
||||||
auto cfg = _panel_instance->config(); // Gets a structure for display panel settings.
|
auto cfg = _panel_instance->config(); // Gets a structure for display panel settings.
|
||||||
LOG_DEBUG("Height: %d, Width: %d \n", settingsMap[displayHeight], settingsMap[displayWidth]);
|
LOG_DEBUG("Height: %d, Width: %d ", settingsMap[displayHeight], settingsMap[displayWidth]);
|
||||||
cfg.pin_cs = settingsMap[displayCS]; // Pin number where CS is connected (-1 = disable)
|
cfg.pin_cs = settingsMap[displayCS]; // Pin number where CS is connected (-1 = disable)
|
||||||
cfg.pin_rst = settingsMap[displayReset];
|
cfg.pin_rst = settingsMap[displayReset];
|
||||||
cfg.panel_width = settingsMap[displayWidth]; // actual displayable width
|
cfg.panel_width = settingsMap[displayWidth]; // actual displayable width
|
||||||
@@ -618,8 +628,8 @@ static LGFX *tft = nullptr;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER) || defined(RAK14014) || \
|
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || \
|
||||||
defined(HX8357_CS) || (ARCH_PORTDUINO && HAS_SCREEN != 0)
|
defined(RAK14014) || defined(HX8357_CS) || (ARCH_PORTDUINO && HAS_SCREEN != 0)
|
||||||
#include "SPILock.h"
|
#include "SPILock.h"
|
||||||
#include "TFTDisplay.h"
|
#include "TFTDisplay.h"
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
@@ -633,7 +643,7 @@ GpioPin *TFTDisplay::backlightEnable = NULL;
|
|||||||
|
|
||||||
TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY geometry, HW_I2C i2cBus)
|
TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY geometry, HW_I2C i2cBus)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("TFTDisplay!\n");
|
LOG_DEBUG("TFTDisplay!");
|
||||||
|
|
||||||
#ifdef TFT_BL
|
#ifdef TFT_BL
|
||||||
GpioPin *p = new GpioHwPin(TFT_BL);
|
GpioPin *p = new GpioHwPin(TFT_BL);
|
||||||
@@ -702,7 +712,7 @@ void TFTDisplay::sendCommand(uint8_t com)
|
|||||||
// handle display on/off directly
|
// handle display on/off directly
|
||||||
switch (com) {
|
switch (com) {
|
||||||
case DISPLAYON: {
|
case DISPLAYON: {
|
||||||
// LOG_DEBUG("Display on\n");
|
// LOG_DEBUG("Display on");
|
||||||
backlightEnable->set(true);
|
backlightEnable->set(true);
|
||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO
|
||||||
display(true);
|
display(true);
|
||||||
@@ -726,7 +736,7 @@ void TFTDisplay::sendCommand(uint8_t com)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DISPLAYOFF: {
|
case DISPLAYOFF: {
|
||||||
// LOG_DEBUG("Display off\n");
|
// LOG_DEBUG("Display off");
|
||||||
backlightEnable->set(false);
|
backlightEnable->set(false);
|
||||||
#if ARCH_PORTDUINO
|
#if ARCH_PORTDUINO
|
||||||
tft->clear();
|
tft->clear();
|
||||||
@@ -762,14 +772,14 @@ void TFTDisplay::setDisplayBrightness(uint8_t _brightness)
|
|||||||
// todo
|
// todo
|
||||||
#else
|
#else
|
||||||
tft->setBrightness(_brightness);
|
tft->setBrightness(_brightness);
|
||||||
LOG_DEBUG("Brightness is set to value: %i \n", _brightness);
|
LOG_DEBUG("Brightness is set to value: %i ", _brightness);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void TFTDisplay::flipScreenVertically()
|
void TFTDisplay::flipScreenVertically()
|
||||||
{
|
{
|
||||||
#if defined(T_WATCH_S3)
|
#if defined(T_WATCH_S3)
|
||||||
LOG_DEBUG("Flip TFT vertically\n"); // T-Watch S3 right-handed orientation
|
LOG_DEBUG("Flip TFT vertically"); // T-Watch S3 right-handed orientation
|
||||||
tft->setRotation(0);
|
tft->setRotation(0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -813,7 +823,7 @@ void TFTDisplay::setDetected(uint8_t detected)
|
|||||||
bool TFTDisplay::connect()
|
bool TFTDisplay::connect()
|
||||||
{
|
{
|
||||||
concurrency::LockGuard g(spiLock);
|
concurrency::LockGuard g(spiLock);
|
||||||
LOG_INFO("Doing TFT init\n");
|
LOG_INFO("Doing TFT init");
|
||||||
#ifdef RAK14014
|
#ifdef RAK14014
|
||||||
tft = new TFT_eSPI;
|
tft = new TFT_eSPI;
|
||||||
#else
|
#else
|
||||||
@@ -821,7 +831,7 @@ bool TFTDisplay::connect()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
backlightEnable->set(true);
|
backlightEnable->set(true);
|
||||||
LOG_INFO("Power to TFT Backlight\n");
|
LOG_INFO("Power to TFT Backlight");
|
||||||
|
|
||||||
#ifdef UNPHONE
|
#ifdef UNPHONE
|
||||||
unphone.backlight(true); // using unPhone library
|
unphone.backlight(true); // using unPhone library
|
||||||
@@ -850,4 +860,4 @@ bool TFTDisplay::connect()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ const uint8_t bluetoothConnectedIcon[36] PROGMEM = {0xfe, 0x01, 0xff, 0x03, 0x03
|
|||||||
0xfe, 0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0x3f, 0xe0, 0x1f};
|
0xfe, 0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0x3f, 0xe0, 0x1f};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || \
|
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
||||||
defined(USE_ST7789) || defined(HX8357_CS) || ARCH_PORTDUINO) && \
|
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || ARCH_PORTDUINO) && \
|
||||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||||
const uint8_t imgQuestionL1[] PROGMEM = {0xff, 0x01, 0x01, 0x32, 0x7b, 0x49, 0x49, 0x6f, 0x26, 0x01, 0x01, 0xff};
|
const uint8_t imgQuestionL1[] PROGMEM = {0xff, 0x01, 0x01, 0x32, 0x7b, 0x49, 0x49, 0x6f, 0x26, 0x01, 0x01, 0xff};
|
||||||
const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};
|
const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#ifndef HAS_USERPREFS_SPLASH
|
#ifndef USERPREFS_HAS_SPLASH
|
||||||
#define icon_width 50
|
#define icon_width 50
|
||||||
#define icon_height 28
|
#define icon_height 28
|
||||||
static uint8_t icon_bits[] = {
|
static uint8_t icon_bits[] = {
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ void ExpressLRSFiveWay::sendAdhocPing()
|
|||||||
// Contained as one method for easier remapping of buttons by user
|
// Contained as one method for easier remapping of buttons by user
|
||||||
void ExpressLRSFiveWay::shutdown()
|
void ExpressLRSFiveWay::shutdown()
|
||||||
{
|
{
|
||||||
LOG_INFO("Shutdown from long press\n");
|
LOG_INFO("Shutdown from long press");
|
||||||
powerFSM.trigger(EVENT_PRESS);
|
powerFSM.trigger(EVENT_PRESS);
|
||||||
screen->startAlert("Shutting down...");
|
screen->startAlert("Shutting down...");
|
||||||
// Don't set alerting = true. We don't want to auto-dismiss this alert.
|
// Don't set alerting = true. We don't want to auto-dismiss this alert.
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#define INPUT_BROKER_MSG_RIGHT 0xb7
|
#define INPUT_BROKER_MSG_RIGHT 0xb7
|
||||||
#define INPUT_BROKER_MSG_FN_SYMBOL_ON 0xf1
|
#define INPUT_BROKER_MSG_FN_SYMBOL_ON 0xf1
|
||||||
#define INPUT_BROKER_MSG_FN_SYMBOL_OFF 0xf2
|
#define INPUT_BROKER_MSG_FN_SYMBOL_OFF 0xf2
|
||||||
|
#define INPUT_BROKER_MSG_BLUETOOTH_TOGGLE 0xAA
|
||||||
|
|
||||||
typedef struct _InputEvent {
|
typedef struct _InputEvent {
|
||||||
const char *source;
|
const char *source;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ void RotaryEncoderInterruptBase::init(
|
|||||||
|
|
||||||
this->rotaryLevelA = digitalRead(this->_pinA);
|
this->rotaryLevelA = digitalRead(this->_pinA);
|
||||||
this->rotaryLevelB = digitalRead(this->_pinB);
|
this->rotaryLevelB = digitalRead(this->_pinB);
|
||||||
LOG_INFO("Rotary initialized (%d, %d, %d)\n", this->_pinA, this->_pinB, pinPress);
|
LOG_INFO("Rotary initialized (%d, %d, %d)", this->_pinA, this->_pinB, pinPress);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t RotaryEncoderInterruptBase::runOnce()
|
int32_t RotaryEncoderInterruptBase::runOnce()
|
||||||
@@ -38,13 +38,13 @@ int32_t RotaryEncoderInterruptBase::runOnce()
|
|||||||
e.source = this->_originName;
|
e.source = this->_originName;
|
||||||
|
|
||||||
if (this->action == ROTARY_ACTION_PRESSED) {
|
if (this->action == ROTARY_ACTION_PRESSED) {
|
||||||
LOG_DEBUG("Rotary event Press\n");
|
LOG_DEBUG("Rotary event Press");
|
||||||
e.inputEvent = this->_eventPressed;
|
e.inputEvent = this->_eventPressed;
|
||||||
} else if (this->action == ROTARY_ACTION_CW) {
|
} else if (this->action == ROTARY_ACTION_CW) {
|
||||||
LOG_DEBUG("Rotary event CW\n");
|
LOG_DEBUG("Rotary event CW");
|
||||||
e.inputEvent = this->_eventCw;
|
e.inputEvent = this->_eventCw;
|
||||||
} else if (this->action == ROTARY_ACTION_CCW) {
|
} else if (this->action == ROTARY_ACTION_CCW) {
|
||||||
LOG_DEBUG("Rotary event CCW\n");
|
LOG_DEBUG("Rotary event CCW");
|
||||||
e.inputEvent = this->_eventCcw;
|
e.inputEvent = this->_eventCcw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ bool ScanAndSelectInput::init()
|
|||||||
// Connect our class to the canned message module
|
// Connect our class to the canned message module
|
||||||
inputBroker->registerSource(this);
|
inputBroker->registerSource(this);
|
||||||
|
|
||||||
LOG_INFO("Initialized 'Scan and Select' input for Canned Messages, using pin %d\n", pin);
|
LOG_INFO("Initialized 'Scan and Select' input for Canned Messages, using pin %d", pin);
|
||||||
return true; // Init succeded
|
return true; // Init succeded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ int32_t SerialKeyboard::runOnce()
|
|||||||
digitalWrite(KB_LOAD, HIGH);
|
digitalWrite(KB_LOAD, HIGH);
|
||||||
digitalWrite(KB_CLK, LOW);
|
digitalWrite(KB_CLK, LOW);
|
||||||
prevKeys = 0b1111111111111111;
|
prevKeys = 0b1111111111111111;
|
||||||
LOG_DEBUG("Serial Keyboard setup\n");
|
LOG_DEBUG("Serial Keyboard setup");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (INPUTBROKER_SERIAL_TYPE == 1) { // Chatter V1.0 & V2.0 keypads
|
if (INPUTBROKER_SERIAL_TYPE == 1) { // Chatter V1.0 & V2.0 keypads
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ TouchScreenBase::TouchScreenBase(const char *name, uint16_t width, uint16_t heig
|
|||||||
void TouchScreenBase::init(bool hasTouch)
|
void TouchScreenBase::init(bool hasTouch)
|
||||||
{
|
{
|
||||||
if (hasTouch) {
|
if (hasTouch) {
|
||||||
LOG_INFO("TouchScreen initialized %d %d\n", TOUCH_THRESHOLD_X, TOUCH_THRESHOLD_Y);
|
LOG_INFO("TouchScreen initialized %d %d", TOUCH_THRESHOLD_X, TOUCH_THRESHOLD_Y);
|
||||||
this->setInterval(100);
|
this->setInterval(100);
|
||||||
} else {
|
} else {
|
||||||
disable();
|
disable();
|
||||||
@@ -68,20 +68,20 @@ int32_t TouchScreenBase::runOnce()
|
|||||||
if (adx > ady && adx > TOUCH_THRESHOLD_X) {
|
if (adx > ady && adx > TOUCH_THRESHOLD_X) {
|
||||||
if (0 > dx) { // swipe right to left
|
if (0 > dx) { // swipe right to left
|
||||||
e.touchEvent = static_cast<char>(TOUCH_ACTION_LEFT);
|
e.touchEvent = static_cast<char>(TOUCH_ACTION_LEFT);
|
||||||
LOG_DEBUG("action SWIPE: right to left\n");
|
LOG_DEBUG("action SWIPE: right to left");
|
||||||
} else { // swipe left to right
|
} else { // swipe left to right
|
||||||
e.touchEvent = static_cast<char>(TOUCH_ACTION_RIGHT);
|
e.touchEvent = static_cast<char>(TOUCH_ACTION_RIGHT);
|
||||||
LOG_DEBUG("action SWIPE: left to right\n");
|
LOG_DEBUG("action SWIPE: left to right");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// swipe vertical
|
// swipe vertical
|
||||||
else if (ady > adx && ady > TOUCH_THRESHOLD_Y) {
|
else if (ady > adx && ady > TOUCH_THRESHOLD_Y) {
|
||||||
if (0 > dy) { // swipe bottom to top
|
if (0 > dy) { // swipe bottom to top
|
||||||
e.touchEvent = static_cast<char>(TOUCH_ACTION_UP);
|
e.touchEvent = static_cast<char>(TOUCH_ACTION_UP);
|
||||||
LOG_DEBUG("action SWIPE: bottom to top\n");
|
LOG_DEBUG("action SWIPE: bottom to top");
|
||||||
} else { // swipe top to bottom
|
} else { // swipe top to bottom
|
||||||
e.touchEvent = static_cast<char>(TOUCH_ACTION_DOWN);
|
e.touchEvent = static_cast<char>(TOUCH_ACTION_DOWN);
|
||||||
LOG_DEBUG("action SWIPE: top to bottom\n");
|
LOG_DEBUG("action SWIPE: top to bottom");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// tap
|
// tap
|
||||||
@@ -90,7 +90,7 @@ int32_t TouchScreenBase::runOnce()
|
|||||||
if (_tapped) {
|
if (_tapped) {
|
||||||
_tapped = false;
|
_tapped = false;
|
||||||
e.touchEvent = static_cast<char>(TOUCH_ACTION_DOUBLE_TAP);
|
e.touchEvent = static_cast<char>(TOUCH_ACTION_DOUBLE_TAP);
|
||||||
LOG_DEBUG("action DOUBLE TAP(%d/%d)\n", x, y);
|
LOG_DEBUG("action DOUBLE TAP(%d/%d)", x, y);
|
||||||
} else {
|
} else {
|
||||||
_tapped = true;
|
_tapped = true;
|
||||||
}
|
}
|
||||||
@@ -106,7 +106,7 @@ int32_t TouchScreenBase::runOnce()
|
|||||||
if (_tapped && (time_t(millis()) - _start) > TIME_LONG_PRESS - 50) {
|
if (_tapped && (time_t(millis()) - _start) > TIME_LONG_PRESS - 50) {
|
||||||
_tapped = false;
|
_tapped = false;
|
||||||
e.touchEvent = static_cast<char>(TOUCH_ACTION_TAP);
|
e.touchEvent = static_cast<char>(TOUCH_ACTION_TAP);
|
||||||
LOG_DEBUG("action TAP(%d/%d)\n", _last_x, _last_y);
|
LOG_DEBUG("action TAP(%d/%d)", _last_x, _last_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fire LONG_PRESS event without the need for release
|
// fire LONG_PRESS event without the need for release
|
||||||
@@ -114,7 +114,7 @@ int32_t TouchScreenBase::runOnce()
|
|||||||
// tricky: prevent reoccurring events and another touch event when releasing
|
// tricky: prevent reoccurring events and another touch event when releasing
|
||||||
_start = millis() + 30000;
|
_start = millis() + 30000;
|
||||||
e.touchEvent = static_cast<char>(TOUCH_ACTION_LONG_PRESS);
|
e.touchEvent = static_cast<char>(TOUCH_ACTION_LONG_PRESS);
|
||||||
LOG_DEBUG("action LONG PRESS(%d/%d)\n", _last_x, _last_y);
|
LOG_DEBUG("action LONG PRESS(%d/%d)", _last_x, _last_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.touchEvent != TOUCH_ACTION_NONE) {
|
if (e.touchEvent != TOUCH_ACTION_NONE) {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ void TrackballInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinLef
|
|||||||
attachInterrupt(this->_pinLeft, onIntLeft, RISING);
|
attachInterrupt(this->_pinLeft, onIntLeft, RISING);
|
||||||
attachInterrupt(this->_pinRight, onIntRight, RISING);
|
attachInterrupt(this->_pinRight, onIntRight, RISING);
|
||||||
|
|
||||||
LOG_DEBUG("Trackball GPIO initialized (%d, %d, %d, %d, %d)\n", this->_pinUp, this->_pinDown, this->_pinLeft, this->_pinRight,
|
LOG_DEBUG("Trackball GPIO initialized (%d, %d, %d, %d, %d)", this->_pinUp, this->_pinDown, this->_pinLeft, this->_pinRight,
|
||||||
pinPress);
|
pinPress);
|
||||||
|
|
||||||
this->setInterval(100);
|
this->setInterval(100);
|
||||||
@@ -42,19 +42,19 @@ int32_t TrackballInterruptBase::runOnce()
|
|||||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||||
|
|
||||||
if (this->action == TB_ACTION_PRESSED) {
|
if (this->action == TB_ACTION_PRESSED) {
|
||||||
// LOG_DEBUG("Trackball event Press\n");
|
// LOG_DEBUG("Trackball event Press");
|
||||||
e.inputEvent = this->_eventPressed;
|
e.inputEvent = this->_eventPressed;
|
||||||
} else if (this->action == TB_ACTION_UP) {
|
} else if (this->action == TB_ACTION_UP) {
|
||||||
// LOG_DEBUG("Trackball event UP\n");
|
// LOG_DEBUG("Trackball event UP");
|
||||||
e.inputEvent = this->_eventUp;
|
e.inputEvent = this->_eventUp;
|
||||||
} else if (this->action == TB_ACTION_DOWN) {
|
} else if (this->action == TB_ACTION_DOWN) {
|
||||||
// LOG_DEBUG("Trackball event DOWN\n");
|
// LOG_DEBUG("Trackball event DOWN");
|
||||||
e.inputEvent = this->_eventDown;
|
e.inputEvent = this->_eventDown;
|
||||||
} else if (this->action == TB_ACTION_LEFT) {
|
} else if (this->action == TB_ACTION_LEFT) {
|
||||||
// LOG_DEBUG("Trackball event LEFT\n");
|
// LOG_DEBUG("Trackball event LEFT");
|
||||||
e.inputEvent = this->_eventLeft;
|
e.inputEvent = this->_eventLeft;
|
||||||
} else if (this->action == TB_ACTION_RIGHT) {
|
} else if (this->action == TB_ACTION_RIGHT) {
|
||||||
// LOG_DEBUG("Trackball event RIGHT\n");
|
// LOG_DEBUG("Trackball event RIGHT");
|
||||||
e.inputEvent = this->_eventRight;
|
e.inputEvent = this->_eventRight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ void UpDownInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinPress,
|
|||||||
attachInterrupt(this->_pinDown, onIntDown, RISING);
|
attachInterrupt(this->_pinDown, onIntDown, RISING);
|
||||||
attachInterrupt(this->_pinUp, onIntUp, RISING);
|
attachInterrupt(this->_pinUp, onIntUp, RISING);
|
||||||
|
|
||||||
LOG_DEBUG("Up/down/press GPIO initialized (%d, %d, %d)\n", this->_pinUp, this->_pinDown, pinPress);
|
LOG_DEBUG("Up/down/press GPIO initialized (%d, %d, %d)", this->_pinUp, this->_pinDown, pinPress);
|
||||||
|
|
||||||
this->setInterval(100);
|
this->setInterval(100);
|
||||||
}
|
}
|
||||||
@@ -34,13 +34,13 @@ int32_t UpDownInterruptBase::runOnce()
|
|||||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||||
|
|
||||||
if (this->action == UPDOWN_ACTION_PRESSED) {
|
if (this->action == UPDOWN_ACTION_PRESSED) {
|
||||||
LOG_DEBUG("GPIO event Press\n");
|
LOG_DEBUG("GPIO event Press");
|
||||||
e.inputEvent = this->_eventPressed;
|
e.inputEvent = this->_eventPressed;
|
||||||
} else if (this->action == UPDOWN_ACTION_UP) {
|
} else if (this->action == UPDOWN_ACTION_UP) {
|
||||||
LOG_DEBUG("GPIO event Up\n");
|
LOG_DEBUG("GPIO event Up");
|
||||||
e.inputEvent = this->_eventUp;
|
e.inputEvent = this->_eventUp;
|
||||||
} else if (this->action == UPDOWN_ACTION_DOWN) {
|
} else if (this->action == UPDOWN_ACTION_DOWN) {
|
||||||
LOG_DEBUG("GPIO event Down\n");
|
LOG_DEBUG("GPIO event Down");
|
||||||
e.inputEvent = this->_eventDown;
|
e.inputEvent = this->_eventDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ void CardKbI2cImpl::init()
|
|||||||
{
|
{
|
||||||
#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO)
|
#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO)
|
||||||
if (cardkb_found.address == 0x00) {
|
if (cardkb_found.address == 0x00) {
|
||||||
LOG_DEBUG("Rescanning for I2C keyboard\n");
|
LOG_DEBUG("Rescanning for I2C keyboard");
|
||||||
uint8_t i2caddr_scan[] = {CARDKB_ADDR, TDECK_KB_ADDR, BBQ10_KB_ADDR};
|
uint8_t i2caddr_scan[] = {CARDKB_ADDR, TDECK_KB_ADDR, BBQ10_KB_ADDR};
|
||||||
uint8_t i2caddr_asize = 3;
|
uint8_t i2caddr_asize = 3;
|
||||||
auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire());
|
auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire());
|
||||||
@@ -41,7 +41,7 @@ void CardKbI2cImpl::init()
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// use this as default since it's also just zero
|
// use this as default since it's also just zero
|
||||||
LOG_WARN("kb_info.type is unknown(0x%02x), setting kb_model=0x00\n", kb_info.type);
|
LOG_WARN("kb_info.type is unknown(0x%02x), setting kb_model=0x00", kb_info.type);
|
||||||
kb_model = 0x00;
|
kb_model = 0x00;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ int32_t KbI2cBase::runOnce()
|
|||||||
switch (cardkb_found.port) {
|
switch (cardkb_found.port) {
|
||||||
case ScanI2C::WIRE1:
|
case ScanI2C::WIRE1:
|
||||||
#if WIRE_INTERFACES_COUNT == 2
|
#if WIRE_INTERFACES_COUNT == 2
|
||||||
LOG_DEBUG("Using I2C Bus 1 (the second one)\n");
|
LOG_DEBUG("Using I2C Bus 1 (the second one)");
|
||||||
i2cBus = &Wire1;
|
i2cBus = &Wire1;
|
||||||
if (cardkb_found.address == BBQ10_KB_ADDR) {
|
if (cardkb_found.address == BBQ10_KB_ADDR) {
|
||||||
Q10keyboard.begin(BBQ10_KB_ADDR, &Wire1);
|
Q10keyboard.begin(BBQ10_KB_ADDR, &Wire1);
|
||||||
@@ -43,7 +43,7 @@ int32_t KbI2cBase::runOnce()
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case ScanI2C::WIRE:
|
case ScanI2C::WIRE:
|
||||||
LOG_DEBUG("Using I2C Bus 0 (the first one)\n");
|
LOG_DEBUG("Using I2C Bus 0 (the first one)");
|
||||||
i2cBus = &Wire;
|
i2cBus = &Wire;
|
||||||
if (cardkb_found.address == BBQ10_KB_ADDR) {
|
if (cardkb_found.address == BBQ10_KB_ADDR) {
|
||||||
Q10keyboard.begin(BBQ10_KB_ADDR, &Wire);
|
Q10keyboard.begin(BBQ10_KB_ADDR, &Wire);
|
||||||
@@ -171,7 +171,7 @@ int32_t KbI2cBase::runOnce()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (PrintDataBuf != 0) {
|
if (PrintDataBuf != 0) {
|
||||||
LOG_DEBUG("RAK14004 key 0x%x pressed\n", PrintDataBuf);
|
LOG_DEBUG("RAK14004 key 0x%x pressed", PrintDataBuf);
|
||||||
InputEvent e;
|
InputEvent e;
|
||||||
e.inputEvent = MATRIXKEY;
|
e.inputEvent = MATRIXKEY;
|
||||||
e.source = this->_originName;
|
e.source = this->_originName;
|
||||||
@@ -297,6 +297,7 @@ int32_t KbI2cBase::runOnce()
|
|||||||
case 0x9e: // fn+g INPUT_BROKER_MSG_GPS_TOGGLE
|
case 0x9e: // fn+g INPUT_BROKER_MSG_GPS_TOGGLE
|
||||||
case 0xaf: // fn+space INPUT_BROKER_MSG_SEND_PING
|
case 0xaf: // fn+space INPUT_BROKER_MSG_SEND_PING
|
||||||
case 0x8b: // fn+del INPUT_BROKEN_MSG_DISMISS_FRAME
|
case 0x8b: // fn+del INPUT_BROKEN_MSG_DISMISS_FRAME
|
||||||
|
case 0xAA: // fn+b INPUT_BROKER_MSG_BLUETOOTH_TOGGLE
|
||||||
// just pass those unmodified
|
// just pass those unmodified
|
||||||
e.inputEvent = ANYKEY;
|
e.inputEvent = ANYKEY;
|
||||||
e.kbchar = c;
|
e.kbchar = c;
|
||||||
@@ -325,7 +326,7 @@ int32_t KbI2cBase::runOnce()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
LOG_WARN("Unknown kb_model 0x%02x\n", kb_model);
|
LOG_WARN("Unknown kb_model 0x%02x", kb_model);
|
||||||
}
|
}
|
||||||
return 300;
|
return 300;
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ int32_t KbMatrixBase::runOnce()
|
|||||||
// debounce
|
// debounce
|
||||||
if (key != prevkey) {
|
if (key != prevkey) {
|
||||||
if (key != 0) {
|
if (key != 0) {
|
||||||
LOG_DEBUG("Key 0x%x pressed\n", key);
|
LOG_DEBUG("Key 0x%x pressed", key);
|
||||||
// reset shift now that we have a keypress
|
// reset shift now that we have a keypress
|
||||||
InputEvent e;
|
InputEvent e;
|
||||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||||
@@ -122,7 +122,7 @@ int32_t KbMatrixBase::runOnce()
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN("Unknown kb_model 0x%02x\n", INPUTBROKER_MATRIX_TYPE);
|
LOG_WARN("Unknown kb_model 0x%02x", INPUTBROKER_MATRIX_TYPE);
|
||||||
return disable();
|
return disable();
|
||||||
}
|
}
|
||||||
return 50; // Keyscan every 50msec to avoid key bounce
|
return 50; // Keyscan every 50msec to avoid key bounce
|
||||||
|
|||||||
166
src/main.cpp
@@ -1,3 +1,4 @@
|
|||||||
|
#include "../userPrefs.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#if !MESHTASTIC_EXCLUDE_GPS
|
#if !MESHTASTIC_EXCLUDE_GPS
|
||||||
#include "GPS.h"
|
#include "GPS.h"
|
||||||
@@ -119,6 +120,8 @@ float tcxoVoltage = SX126X_DIO3_TCXO_VOLTAGE; // if TCXO is optional, put this h
|
|||||||
|
|
||||||
using namespace concurrency;
|
using namespace concurrency;
|
||||||
|
|
||||||
|
volatile static const char slipstreamTZString[] = USERPREFS_TZ_STRING;
|
||||||
|
|
||||||
// We always create a screen object, but we only init it if we find the hardware
|
// We always create a screen object, but we only init it if we find the hardware
|
||||||
graphics::Screen *screen = nullptr;
|
graphics::Screen *screen = nullptr;
|
||||||
|
|
||||||
@@ -235,7 +238,7 @@ void lateInitVariant() {}
|
|||||||
*/
|
*/
|
||||||
void printInfo()
|
void printInfo()
|
||||||
{
|
{
|
||||||
LOG_INFO("S:B:%d,%s\n", HW_VENDOR, optstr(APP_VERSION));
|
LOG_INFO("S:B:%d,%s", HW_VENDOR, optstr(APP_VERSION));
|
||||||
}
|
}
|
||||||
#ifndef PIO_UNIT_TESTING
|
#ifndef PIO_UNIT_TESTING
|
||||||
void setup()
|
void setup()
|
||||||
@@ -274,7 +277,7 @@ void setup()
|
|||||||
|
|
||||||
serialSinceMsec = millis();
|
serialSinceMsec = millis();
|
||||||
|
|
||||||
LOG_INFO("\n\n//\\ E S H T /\\ S T / C\n\n");
|
LOG_INFO("\n\n//\\ E S H T /\\ S T / C\n");
|
||||||
|
|
||||||
initDeepSleep();
|
initDeepSleep();
|
||||||
|
|
||||||
@@ -295,6 +298,11 @@ void setup()
|
|||||||
digitalWrite(VEXT_ENABLE, VEXT_ON_VALUE); // turn on the display power
|
digitalWrite(VEXT_ENABLE, VEXT_ON_VALUE); // turn on the display power
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(BIAS_T_ENABLE)
|
||||||
|
pinMode(BIAS_T_ENABLE, OUTPUT);
|
||||||
|
digitalWrite(BIAS_T_ENABLE, BIAS_T_VALUE); // turn on 5V for GPS Antenna
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(VTFT_CTRL)
|
#if defined(VTFT_CTRL)
|
||||||
pinMode(VTFT_CTRL, OUTPUT);
|
pinMode(VTFT_CTRL, OUTPUT);
|
||||||
digitalWrite(VTFT_CTRL, LOW);
|
digitalWrite(VTFT_CTRL, LOW);
|
||||||
@@ -316,7 +324,7 @@ void setup()
|
|||||||
#ifdef PERIPHERAL_WARMUP_MS
|
#ifdef PERIPHERAL_WARMUP_MS
|
||||||
// Some peripherals may require additional time to stabilize after power is connected
|
// Some peripherals may require additional time to stabilize after power is connected
|
||||||
// e.g. I2C on Heltec Vision Master
|
// e.g. I2C on Heltec Vision Master
|
||||||
LOG_INFO("Waiting for peripherals to stabilize\n");
|
LOG_INFO("Waiting for peripherals to stabilize");
|
||||||
delay(PERIPHERAL_WARMUP_MS);
|
delay(PERIPHERAL_WARMUP_MS);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -377,10 +385,10 @@ void setup()
|
|||||||
Wire.begin(I2C_SDA, I2C_SCL);
|
Wire.begin(I2C_SDA, I2C_SCL);
|
||||||
#elif defined(ARCH_PORTDUINO)
|
#elif defined(ARCH_PORTDUINO)
|
||||||
if (settingsStrings[i2cdev] != "") {
|
if (settingsStrings[i2cdev] != "") {
|
||||||
LOG_INFO("Using %s as I2C device.\n", settingsStrings[i2cdev].c_str());
|
LOG_INFO("Using %s as I2C device.", settingsStrings[i2cdev].c_str());
|
||||||
Wire.begin(settingsStrings[i2cdev].c_str());
|
Wire.begin(settingsStrings[i2cdev].c_str());
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("No I2C device configured, skipping.\n");
|
LOG_INFO("No I2C device configured, skipping.");
|
||||||
}
|
}
|
||||||
#elif HAS_WIRE
|
#elif HAS_WIRE
|
||||||
Wire.begin();
|
Wire.begin();
|
||||||
@@ -423,7 +431,7 @@ void setup()
|
|||||||
// accessories
|
// accessories
|
||||||
auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire());
|
auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire());
|
||||||
#if HAS_WIRE
|
#if HAS_WIRE
|
||||||
LOG_INFO("Scanning for i2c devices...\n");
|
LOG_INFO("Scanning for i2c devices...");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(I2C_SDA1) && defined(ARCH_RP2040)
|
#if defined(I2C_SDA1) && defined(ARCH_RP2040)
|
||||||
@@ -448,7 +456,7 @@ void setup()
|
|||||||
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE);
|
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE);
|
||||||
#elif defined(ARCH_PORTDUINO)
|
#elif defined(ARCH_PORTDUINO)
|
||||||
if (settingsStrings[i2cdev] != "") {
|
if (settingsStrings[i2cdev] != "") {
|
||||||
LOG_INFO("Scanning for i2c devices...\n");
|
LOG_INFO("Scanning for i2c devices...");
|
||||||
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE);
|
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE);
|
||||||
}
|
}
|
||||||
#elif HAS_WIRE
|
#elif HAS_WIRE
|
||||||
@@ -457,9 +465,9 @@ void setup()
|
|||||||
|
|
||||||
auto i2cCount = i2cScanner->countDevices();
|
auto i2cCount = i2cScanner->countDevices();
|
||||||
if (i2cCount == 0) {
|
if (i2cCount == 0) {
|
||||||
LOG_INFO("No I2C devices found\n");
|
LOG_INFO("No I2C devices found");
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("%i I2C devices found\n", i2cCount);
|
LOG_INFO("%i I2C devices found", i2cCount);
|
||||||
#ifdef SENSOR_GPS_CONFLICT
|
#ifdef SENSOR_GPS_CONFLICT
|
||||||
sensor_detected = true;
|
sensor_detected = true;
|
||||||
#endif
|
#endif
|
||||||
@@ -517,7 +525,7 @@ void setup()
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// use this as default since it's also just zero
|
// use this as default since it's also just zero
|
||||||
LOG_WARN("kb_info.type is unknown(0x%02x), setting kb_model=0x00\n", kb_info.type);
|
LOG_WARN("kb_info.type is unknown(0x%02x), setting kb_model=0x00", kb_info.type);
|
||||||
kb_model = 0x00;
|
kb_model = 0x00;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -535,10 +543,25 @@ void setup()
|
|||||||
rgb_found = i2cScanner->find(ScanI2C::DeviceType::NCP5623);
|
rgb_found = i2cScanner->find(ScanI2C::DeviceType::NCP5623);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAS_TPS65233
|
||||||
|
// TPS65233 is a power management IC for satellite modems, used in the Dreamcatcher
|
||||||
|
// We are switching it off here since we don't use an LNB.
|
||||||
|
if (i2cScanner->exists(ScanI2C::DeviceType::TPS65233)) {
|
||||||
|
Wire.beginTransmission(TPS65233_ADDR);
|
||||||
|
Wire.write(0); // Register 0
|
||||||
|
Wire.write(128); // Turn off the LNB power, keep I2C Control enabled
|
||||||
|
Wire.endTransmission();
|
||||||
|
Wire.beginTransmission(TPS65233_ADDR);
|
||||||
|
Wire.write(1); // Register 1
|
||||||
|
Wire.write(0); // Turn off Tone Generator 22kHz
|
||||||
|
Wire.endTransmission();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||||
auto acc_info = i2cScanner->firstAccelerometer();
|
auto acc_info = i2cScanner->firstAccelerometer();
|
||||||
accelerometer_found = acc_info.type != ScanI2C::DeviceType::NONE ? acc_info.address : accelerometer_found;
|
accelerometer_found = acc_info.type != ScanI2C::DeviceType::NONE ? acc_info.address : accelerometer_found;
|
||||||
LOG_DEBUG("acc_info = %i\n", acc_info.type);
|
LOG_DEBUG("acc_info = %i", acc_info.type);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define STRING(S) #S
|
#define STRING(S) #S
|
||||||
@@ -549,7 +572,7 @@ void setup()
|
|||||||
if (found.type != ScanI2C::DeviceType::NONE) { \
|
if (found.type != ScanI2C::DeviceType::NONE) { \
|
||||||
nodeTelemetrySensorsMap[PB_T].first = found.address.address; \
|
nodeTelemetrySensorsMap[PB_T].first = found.address.address; \
|
||||||
nodeTelemetrySensorsMap[PB_T].second = i2cScanner->fetchI2CBus(found.address); \
|
nodeTelemetrySensorsMap[PB_T].second = i2cScanner->fetchI2CBus(found.address); \
|
||||||
LOG_DEBUG("found i2c sensor %s\n", STRING(PB_T)); \
|
LOG_DEBUG("found i2c sensor %s", STRING(PB_T)); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -577,10 +600,12 @@ void setup()
|
|||||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::TSL2591, meshtastic_TelemetrySensorType_TSL25911FN)
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::TSL2591, meshtastic_TelemetrySensorType_TSL25911FN)
|
||||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::OPT3001, meshtastic_TelemetrySensorType_OPT3001)
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::OPT3001, meshtastic_TelemetrySensorType_OPT3001)
|
||||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MLX90632, meshtastic_TelemetrySensorType_MLX90632)
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MLX90632, meshtastic_TelemetrySensorType_MLX90632)
|
||||||
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MLX90614, meshtastic_TelemetrySensorType_MLX90614)
|
||||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHT4X, meshtastic_TelemetrySensorType_SHT4X)
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHT4X, meshtastic_TelemetrySensorType_SHT4X)
|
||||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::AHT10, meshtastic_TelemetrySensorType_AHT10)
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::AHT10, meshtastic_TelemetrySensorType_AHT10)
|
||||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::DFROBOT_LARK, meshtastic_TelemetrySensorType_DFROBOT_LARK)
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::DFROBOT_LARK, meshtastic_TelemetrySensorType_DFROBOT_LARK)
|
||||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::ICM20948, meshtastic_TelemetrySensorType_ICM20948)
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::ICM20948, meshtastic_TelemetrySensorType_ICM20948)
|
||||||
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MAX30102, meshtastic_TelemetrySensorType_MAX30102)
|
||||||
|
|
||||||
i2cScanner.reset();
|
i2cScanner.reset();
|
||||||
#endif
|
#endif
|
||||||
@@ -599,7 +624,7 @@ void setup()
|
|||||||
// Hello
|
// Hello
|
||||||
printInfo();
|
printInfo();
|
||||||
#ifdef BUILD_EPOCH
|
#ifdef BUILD_EPOCH
|
||||||
LOG_INFO("Build timestamp: %ld\n", BUILD_EPOCH);
|
LOG_INFO("Build timestamp: %ld", BUILD_EPOCH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
@@ -636,7 +661,7 @@ void setup()
|
|||||||
if (config.power.is_power_saving == true &&
|
if (config.power.is_power_saving == true &&
|
||||||
IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_TRACKER,
|
IS_ONE_OF(config.device.role, meshtastic_Config_DeviceConfig_Role_TRACKER,
|
||||||
meshtastic_Config_DeviceConfig_Role_TAK_TRACKER, meshtastic_Config_DeviceConfig_Role_SENSOR))
|
meshtastic_Config_DeviceConfig_Role_TAK_TRACKER, meshtastic_Config_DeviceConfig_Role_SENSOR))
|
||||||
LOG_DEBUG("Tracker/Sensor: Skipping start melody\n");
|
LOG_DEBUG("Tracker/Sensor: Skipping start melody");
|
||||||
else
|
else
|
||||||
playStartMelody();
|
playStartMelody();
|
||||||
|
|
||||||
@@ -646,7 +671,7 @@ void setup()
|
|||||||
|
|
||||||
#if defined(USE_SH1107)
|
#if defined(USE_SH1107)
|
||||||
screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1107; // set dimension of 128x128
|
screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1107; // set dimension of 128x128
|
||||||
display_geometry = GEOMETRY_128_128;
|
screen_geometry = GEOMETRY_128_128;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_SH1107_128_64)
|
#if defined(USE_SH1107_128_64)
|
||||||
@@ -697,7 +722,7 @@ void setup()
|
|||||||
#else
|
#else
|
||||||
// ESP32
|
// ESP32
|
||||||
SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
|
SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
|
||||||
LOG_DEBUG("SPI.begin(SCK=%d, MISO=%d, MOSI=%d, NSS=%d)\n", LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
|
LOG_DEBUG("SPI.begin(SCK=%d, MISO=%d, MOSI=%d, NSS=%d)", LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
|
||||||
SPI.setFrequency(4000000);
|
SPI.setFrequency(4000000);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -706,13 +731,20 @@ void setup()
|
|||||||
|
|
||||||
// setup TZ prior to time actions.
|
// setup TZ prior to time actions.
|
||||||
#if !MESHTASTIC_EXCLUDE_TZ
|
#if !MESHTASTIC_EXCLUDE_TZ
|
||||||
if (*config.device.tzdef) {
|
LOG_DEBUG("Using compiled/slipstreamed %s", slipstreamTZString); // important, removing this clobbers our magic string
|
||||||
|
if (*config.device.tzdef && config.device.tzdef[0] != 0) {
|
||||||
|
LOG_DEBUG("Saved TZ: %s ", config.device.tzdef);
|
||||||
setenv("TZ", config.device.tzdef, 1);
|
setenv("TZ", config.device.tzdef, 1);
|
||||||
} else {
|
} else {
|
||||||
setenv("TZ", "GMT0", 1);
|
if (strncmp((const char *)slipstreamTZString, "tzpl", 4) == 0) {
|
||||||
|
setenv("TZ", "GMT0", 1);
|
||||||
|
} else {
|
||||||
|
setenv("TZ", (const char *)slipstreamTZString, 1);
|
||||||
|
strcpy(config.device.tzdef, (const char *)slipstreamTZString);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tzset();
|
tzset();
|
||||||
LOG_DEBUG("Set Timezone to %s\n", getenv("TZ"));
|
LOG_DEBUG("Set Timezone to %s", getenv("TZ"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time)
|
readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time)
|
||||||
@@ -729,7 +761,7 @@ void setup()
|
|||||||
if (gps) {
|
if (gps) {
|
||||||
gpsStatus->observe(&gps->newStatus);
|
gpsStatus->observe(&gps->newStatus);
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("Running without GPS.\n");
|
LOG_DEBUG("Running without GPS.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -742,7 +774,7 @@ void setup()
|
|||||||
nodeStatus->observe(&nodeDB->newStatus);
|
nodeStatus->observe(&nodeDB->newStatus);
|
||||||
|
|
||||||
#ifdef HAS_I2S
|
#ifdef HAS_I2S
|
||||||
LOG_DEBUG("Starting audio thread\n");
|
LOG_DEBUG("Starting audio thread");
|
||||||
audioThread = new AudioThread();
|
audioThread = new AudioThread();
|
||||||
#endif
|
#endif
|
||||||
service = new MeshService();
|
service = new MeshService();
|
||||||
@@ -766,8 +798,8 @@ void setup()
|
|||||||
#if !MESHTASTIC_EXCLUDE_I2C
|
#if !MESHTASTIC_EXCLUDE_I2C
|
||||||
// Don't call screen setup until after nodedb is setup (because we need
|
// Don't call screen setup until after nodedb is setup (because we need
|
||||||
// the current region name)
|
// the current region name)
|
||||||
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7789_CS) || \
|
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || \
|
||||||
defined(HX8357_CS) || defined(USE_ST7789)
|
defined(ST7789_CS) || defined(HX8357_CS) || defined(USE_ST7789)
|
||||||
screen->setup();
|
screen->setup();
|
||||||
#elif defined(ARCH_PORTDUINO)
|
#elif defined(ARCH_PORTDUINO)
|
||||||
if (screen_found.port != ScanI2C::I2CPort::NO_I2C || settingsMap[displayPanel]) {
|
if (screen_found.port != ScanI2C::I2CPort::NO_I2C || settingsMap[displayPanel]) {
|
||||||
@@ -789,63 +821,63 @@ void setup()
|
|||||||
#ifdef ARCH_PORTDUINO
|
#ifdef ARCH_PORTDUINO
|
||||||
if (settingsMap[use_sx1262]) {
|
if (settingsMap[use_sx1262]) {
|
||||||
if (!rIf) {
|
if (!rIf) {
|
||||||
LOG_DEBUG("Attempting to activate sx1262 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
LOG_DEBUG("Attempting to activate sx1262 radio on SPI port %s", settingsStrings[spidev].c_str());
|
||||||
LockingArduinoHal *RadioLibHAL =
|
LockingArduinoHal *RadioLibHAL =
|
||||||
new LockingArduinoHal(SPI, spiSettings, (settingsMap[ch341Quirk] ? settingsMap[busy] : RADIOLIB_NC));
|
new LockingArduinoHal(SPI, spiSettings, (settingsMap[ch341Quirk] ? settingsMap[busy] : RADIOLIB_NC));
|
||||||
rIf = new SX1262Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
rIf = new SX1262Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
||||||
settingsMap[busy]);
|
settingsMap[busy]);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_ERROR("Failed to find SX1262 radio\n");
|
LOG_ERROR("Failed to find SX1262 radio");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio\n");
|
LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (settingsMap[use_rf95]) {
|
} else if (settingsMap[use_rf95]) {
|
||||||
if (!rIf) {
|
if (!rIf) {
|
||||||
LOG_DEBUG("Attempting to activate rf95 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
LOG_DEBUG("Attempting to activate rf95 radio on SPI port %s", settingsStrings[spidev].c_str());
|
||||||
LockingArduinoHal *RadioLibHAL =
|
LockingArduinoHal *RadioLibHAL =
|
||||||
new LockingArduinoHal(SPI, spiSettings, (settingsMap[ch341Quirk] ? settingsMap[busy] : RADIOLIB_NC));
|
new LockingArduinoHal(SPI, spiSettings, (settingsMap[ch341Quirk] ? settingsMap[busy] : RADIOLIB_NC));
|
||||||
rIf = new RF95Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
rIf = new RF95Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
||||||
settingsMap[busy]);
|
settingsMap[busy]);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_ERROR("Failed to find RF95 radio\n");
|
LOG_ERROR("Failed to find RF95 radio");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("RF95 Radio init succeeded, using RF95 radio\n");
|
LOG_INFO("RF95 Radio init succeeded, using RF95 radio");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (settingsMap[use_sx1280]) {
|
} else if (settingsMap[use_sx1280]) {
|
||||||
if (!rIf) {
|
if (!rIf) {
|
||||||
LOG_DEBUG("Attempting to activate sx1280 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
LOG_DEBUG("Attempting to activate sx1280 radio on SPI port %s", settingsStrings[spidev].c_str());
|
||||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
||||||
rIf = new SX1280Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
rIf = new SX1280Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
||||||
settingsMap[busy]);
|
settingsMap[busy]);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_ERROR("Failed to find SX1280 radio\n");
|
LOG_ERROR("Failed to find SX1280 radio");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio\n");
|
LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (settingsMap[use_sx1268]) {
|
} else if (settingsMap[use_sx1268]) {
|
||||||
if (!rIf) {
|
if (!rIf) {
|
||||||
LOG_DEBUG("Attempting to activate sx1268 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
LOG_DEBUG("Attempting to activate sx1268 radio on SPI port %s", settingsStrings[spidev].c_str());
|
||||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
||||||
rIf = new SX1268Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
rIf = new SX1268Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
||||||
settingsMap[busy]);
|
settingsMap[busy]);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_ERROR("Failed to find SX1268 radio\n");
|
LOG_ERROR("Failed to find SX1268 radio");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio\n");
|
LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -861,11 +893,11 @@ void setup()
|
|||||||
if (!rIf) {
|
if (!rIf) {
|
||||||
rIf = new STM32WLE5JCInterface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
|
rIf = new STM32WLE5JCInterface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_WARN("Failed to find STM32WL radio\n");
|
LOG_WARN("Failed to find STM32WL radio");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("STM32WL Radio init succeeded, using STM32WL radio\n");
|
LOG_INFO("STM32WL Radio init succeeded, using STM32WL radio");
|
||||||
radioType = STM32WLx_RADIO;
|
radioType = STM32WLx_RADIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -875,11 +907,11 @@ void setup()
|
|||||||
if (!rIf) {
|
if (!rIf) {
|
||||||
rIf = new SimRadio;
|
rIf = new SimRadio;
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_WARN("Failed to find simulated radio\n");
|
LOG_WARN("Failed to find simulated radio");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("Using SIMULATED radio!\n");
|
LOG_INFO("Using SIMULATED radio!");
|
||||||
radioType = SIM_RADIO;
|
radioType = SIM_RADIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -889,11 +921,11 @@ void setup()
|
|||||||
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
|
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
|
||||||
rIf = new RF95Interface(RadioLibHAL, LORA_CS, RF95_IRQ, RF95_RESET, RF95_DIO1);
|
rIf = new RF95Interface(RadioLibHAL, LORA_CS, RF95_IRQ, RF95_RESET, RF95_DIO1);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_WARN("Failed to find RF95 radio\n");
|
LOG_WARN("Failed to find RF95 radio");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("RF95 Radio init succeeded, using RF95 radio\n");
|
LOG_INFO("RF95 Radio init succeeded, using RF95 radio");
|
||||||
radioType = RF95_RADIO;
|
radioType = RF95_RADIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -903,11 +935,11 @@ void setup()
|
|||||||
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
|
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
|
||||||
rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
|
rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_WARN("Failed to find SX1262 radio\n");
|
LOG_WARN("Failed to find SX1262 radio");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio\n");
|
LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio");
|
||||||
radioType = SX1262_RADIO;
|
radioType = SX1262_RADIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -918,14 +950,12 @@ void setup()
|
|||||||
// Try using the specified TCXO voltage
|
// Try using the specified TCXO voltage
|
||||||
rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
|
rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_WARN("Failed to find SX1262 radio with TCXO using DIO3 reference voltage at %f V\n", tcxoVoltage);
|
LOG_WARN("Failed to find SX1262 radio with TCXO, Vref %f V", tcxoVoltage);
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
tcxoVoltage = 0; // if it fails, set the TCXO voltage to zero for the next attempt
|
tcxoVoltage = 0; // if it fails, set the TCXO voltage to zero for the next attempt
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("SX1262 Radio init succeeded, using ");
|
LOG_WARN("SX1262 Radio init succeeded, TCXO, Vref %f V", tcxoVoltage);
|
||||||
LOG_WARN("SX1262 Radio with TCXO");
|
|
||||||
LOG_INFO(", reference voltage at %f V\n", tcxoVoltage);
|
|
||||||
radioType = SX1262_RADIO;
|
radioType = SX1262_RADIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -934,14 +964,12 @@ void setup()
|
|||||||
// If specified TCXO voltage fails, attempt to use DIO3 as a reference instea
|
// If specified TCXO voltage fails, attempt to use DIO3 as a reference instea
|
||||||
rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
|
rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_WARN("Failed to find SX1262 radio with XTAL using DIO3 reference voltage at %f V\n", tcxoVoltage);
|
LOG_WARN("Failed to find SX1262 radio with XTAL, Vref %f V", tcxoVoltage);
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
tcxoVoltage = SX126X_DIO3_TCXO_VOLTAGE; // if it fails, set the TCXO voltage back for the next radio search
|
tcxoVoltage = SX126X_DIO3_TCXO_VOLTAGE; // if it fails, set the TCXO voltage back for the next radio search
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("SX1262 Radio init succeeded, using ");
|
LOG_INFO("SX1262 Radio init succeeded, XTAL, Vref %f V", tcxoVoltage);
|
||||||
LOG_WARN("SX1262 Radio with XTAL");
|
|
||||||
LOG_INFO(", reference voltage at %f V\n", tcxoVoltage);
|
|
||||||
radioType = SX1262_RADIO;
|
radioType = SX1262_RADIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -951,11 +979,11 @@ void setup()
|
|||||||
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
|
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
|
||||||
rIf = new SX1268Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
|
rIf = new SX1268Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_WARN("Failed to find SX1268 radio\n");
|
LOG_WARN("Failed to find SX1268 radio");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio\n");
|
LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio");
|
||||||
radioType = SX1268_RADIO;
|
radioType = SX1268_RADIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -965,11 +993,11 @@ void setup()
|
|||||||
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
|
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
|
||||||
rIf = new LLCC68Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
|
rIf = new LLCC68Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_WARN("Failed to find LLCC68 radio\n");
|
LOG_WARN("Failed to find LLCC68 radio");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("LLCC68 Radio init succeeded, using LLCC68 radio\n");
|
LOG_INFO("LLCC68 Radio init succeeded, using LLCC68 radio");
|
||||||
radioType = LLCC68_RADIO;
|
radioType = LLCC68_RADIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -979,11 +1007,11 @@ void setup()
|
|||||||
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
|
if ((!rIf) && (config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_LORA_24)) {
|
||||||
rIf = new LR1110Interface(RadioLibHAL, LR1110_SPI_NSS_PIN, LR1110_IRQ_PIN, LR1110_NRESET_PIN, LR1110_BUSY_PIN);
|
rIf = new LR1110Interface(RadioLibHAL, LR1110_SPI_NSS_PIN, LR1110_IRQ_PIN, LR1110_NRESET_PIN, LR1110_BUSY_PIN);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_WARN("Failed to find LR1110 radio\n");
|
LOG_WARN("Failed to find LR1110 radio");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("LR1110 Radio init succeeded, using LR1110 radio\n");
|
LOG_INFO("LR1110 Radio init succeeded, using LR1110 radio");
|
||||||
radioType = LR1110_RADIO;
|
radioType = LR1110_RADIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -993,11 +1021,11 @@ void setup()
|
|||||||
if (!rIf) {
|
if (!rIf) {
|
||||||
rIf = new LR1120Interface(RadioLibHAL, LR1120_SPI_NSS_PIN, LR1120_IRQ_PIN, LR1120_NRESET_PIN, LR1120_BUSY_PIN);
|
rIf = new LR1120Interface(RadioLibHAL, LR1120_SPI_NSS_PIN, LR1120_IRQ_PIN, LR1120_NRESET_PIN, LR1120_BUSY_PIN);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_WARN("Failed to find LR1120 radio\n");
|
LOG_WARN("Failed to find LR1120 radio");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("LR1120 Radio init succeeded, using LR1120 radio\n");
|
LOG_INFO("LR1120 Radio init succeeded, using LR1120 radio");
|
||||||
radioType = LR1120_RADIO;
|
radioType = LR1120_RADIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1007,11 +1035,11 @@ void setup()
|
|||||||
if (!rIf) {
|
if (!rIf) {
|
||||||
rIf = new LR1121Interface(RadioLibHAL, LR1121_SPI_NSS_PIN, LR1121_IRQ_PIN, LR1121_NRESET_PIN, LR1121_BUSY_PIN);
|
rIf = new LR1121Interface(RadioLibHAL, LR1121_SPI_NSS_PIN, LR1121_IRQ_PIN, LR1121_NRESET_PIN, LR1121_BUSY_PIN);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_WARN("Failed to find LR1121 radio\n");
|
LOG_WARN("Failed to find LR1121 radio");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("LR1121 Radio init succeeded, using LR1121 radio\n");
|
LOG_INFO("LR1121 Radio init succeeded, using LR1121 radio");
|
||||||
radioType = LR1121_RADIO;
|
radioType = LR1121_RADIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1021,11 +1049,11 @@ void setup()
|
|||||||
if (!rIf) {
|
if (!rIf) {
|
||||||
rIf = new SX1280Interface(RadioLibHAL, SX128X_CS, SX128X_DIO1, SX128X_RESET, SX128X_BUSY);
|
rIf = new SX1280Interface(RadioLibHAL, SX128X_CS, SX128X_DIO1, SX128X_RESET, SX128X_BUSY);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
LOG_WARN("Failed to find SX1280 radio\n");
|
LOG_WARN("Failed to find SX1280 radio");
|
||||||
delete rIf;
|
delete rIf;
|
||||||
rIf = NULL;
|
rIf = NULL;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio\n");
|
LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio");
|
||||||
radioType = SX1280_RADIO;
|
radioType = SX1280_RADIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1033,11 +1061,11 @@ void setup()
|
|||||||
|
|
||||||
// check if the radio chip matches the selected region
|
// check if the radio chip matches the selected region
|
||||||
if ((config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_LORA_24) && (!rIf->wideLora())) {
|
if ((config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_LORA_24) && (!rIf->wideLora())) {
|
||||||
LOG_WARN("Radio chip does not support 2.4GHz LoRa. Reverting to unset.\n");
|
LOG_WARN("Radio chip does not support 2.4GHz LoRa. Reverting to unset.");
|
||||||
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET;
|
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET;
|
||||||
nodeDB->saveToDisk(SEGMENT_CONFIG);
|
nodeDB->saveToDisk(SEGMENT_CONFIG);
|
||||||
if (!rIf->reconfigure()) {
|
if (!rIf->reconfigure()) {
|
||||||
LOG_WARN("Reconfigure failed, rebooting\n");
|
LOG_WARN("Reconfigure failed, rebooting");
|
||||||
screen->startAlert("Rebooting...");
|
screen->startAlert("Rebooting...");
|
||||||
rebootAtMsec = millis() + 5000;
|
rebootAtMsec = millis() + 5000;
|
||||||
}
|
}
|
||||||
@@ -1092,9 +1120,9 @@ void setup()
|
|||||||
router->addInterface(rIf);
|
router->addInterface(rIf);
|
||||||
|
|
||||||
// Log bit rate to debug output
|
// Log bit rate to debug output
|
||||||
LOG_DEBUG("LoRA bitrate = %f bytes / sec\n", (float(meshtastic_Constants_DATA_PAYLOAD_LEN) /
|
LOG_DEBUG("LoRA bitrate = %f bytes / sec", (float(meshtastic_Constants_DATA_PAYLOAD_LEN) /
|
||||||
(float(rIf->getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN)))) *
|
(float(rIf->getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN)))) *
|
||||||
1000);
|
1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This must be _after_ service.init because we need our preferences loaded from flash to have proper timeout values
|
// This must be _after_ service.init because we need our preferences loaded from flash to have proper timeout values
|
||||||
@@ -1158,4 +1186,4 @@ void loop()
|
|||||||
mainDelay.delay(delayMsec);
|
mainDelay.delay(delayMsec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -76,6 +76,23 @@ meshtastic_Channel &Channels::fixupChannel(ChannelIndex chIndex)
|
|||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Channels::initDefaultLoraConfig()
|
||||||
|
{
|
||||||
|
meshtastic_Config_LoRaConfig &loraConfig = config.lora;
|
||||||
|
|
||||||
|
loraConfig.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST; // Default to Long Range & Fast
|
||||||
|
loraConfig.use_preset = true;
|
||||||
|
loraConfig.tx_power = 0; // default
|
||||||
|
loraConfig.channel_num = 0;
|
||||||
|
|
||||||
|
#ifdef USERPREFS_LORACONFIG_MODEM_PRESET
|
||||||
|
loraConfig.modem_preset = USERPREFS_LORACONFIG_MODEM_PRESET;
|
||||||
|
#endif
|
||||||
|
#ifdef USERPREFS_LORACONFIG_CHANNEL_NUM
|
||||||
|
loraConfig.channel_num = USERPREFS_LORACONFIG_CHANNEL_NUM;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a default channel to the specified channel index
|
* Write a default channel to the specified channel index
|
||||||
*/
|
*/
|
||||||
@@ -83,12 +100,7 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
|
|||||||
{
|
{
|
||||||
meshtastic_Channel &ch = getByIndex(chIndex);
|
meshtastic_Channel &ch = getByIndex(chIndex);
|
||||||
meshtastic_ChannelSettings &channelSettings = ch.settings;
|
meshtastic_ChannelSettings &channelSettings = ch.settings;
|
||||||
meshtastic_Config_LoRaConfig &loraConfig = config.lora;
|
|
||||||
|
|
||||||
loraConfig.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST; // Default to Long Range & Fast
|
|
||||||
loraConfig.use_preset = true;
|
|
||||||
loraConfig.tx_power = 0; // default
|
|
||||||
loraConfig.channel_num = 0;
|
|
||||||
uint8_t defaultpskIndex = 1;
|
uint8_t defaultpskIndex = 1;
|
||||||
channelSettings.psk.bytes[0] = defaultpskIndex;
|
channelSettings.psk.bytes[0] = defaultpskIndex;
|
||||||
channelSettings.psk.size = 1;
|
channelSettings.psk.size = 1;
|
||||||
@@ -97,29 +109,53 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
|
|||||||
channelSettings.has_module_settings = true;
|
channelSettings.has_module_settings = true;
|
||||||
|
|
||||||
ch.has_settings = true;
|
ch.has_settings = true;
|
||||||
ch.role = meshtastic_Channel_Role_PRIMARY;
|
ch.role = chIndex == 0 ? meshtastic_Channel_Role_PRIMARY : meshtastic_Channel_Role_SECONDARY;
|
||||||
|
|
||||||
#ifdef LORACONFIG_MODEM_PRESET_USERPREFS
|
switch (chIndex) {
|
||||||
loraConfig.modem_preset = LORACONFIG_MODEM_PRESET_USERPREFS;
|
case 0:
|
||||||
#endif
|
#ifdef USERPREFS_CHANNEL_0_PSK
|
||||||
#ifdef LORACONFIG_CHANNEL_NUM_USERPREFS
|
static const uint8_t defaultpsk0[] = USERPREFS_CHANNEL_0_PSK;
|
||||||
loraConfig.channel_num = LORACONFIG_CHANNEL_NUM_USERPREFS;
|
memcpy(channelSettings.psk.bytes, defaultpsk0, sizeof(defaultpsk0));
|
||||||
#endif
|
channelSettings.psk.size = sizeof(defaultpsk0);
|
||||||
|
|
||||||
// Install custom defaults. Will eventually support setting multiple default channels
|
|
||||||
if (chIndex == 0) {
|
|
||||||
#ifdef CHANNEL_0_PSK_USERPREFS
|
|
||||||
static const uint8_t defaultpsk[] = CHANNEL_0_PSK_USERPREFS;
|
|
||||||
memcpy(channelSettings.psk.bytes, defaultpsk, sizeof(defaultpsk));
|
|
||||||
channelSettings.psk.size = sizeof(defaultpsk);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef CHANNEL_0_NAME_USERPREFS
|
#ifdef USERPREFS_CHANNEL_0_NAME
|
||||||
strcpy(channelSettings.name, CHANNEL_0_NAME_USERPREFS);
|
strcpy(channelSettings.name, USERPREFS_CHANNEL_0_NAME);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CHANNEL_0_PRECISION_USERPREFS
|
#ifdef USERPREFS_CHANNEL_0_PRECISION
|
||||||
channelSettings.module_settings.position_precision = CHANNEL_0_PRECISION_USERPREFS;
|
channelSettings.module_settings.position_precision = USERPREFS_CHANNEL_0_PRECISION;
|
||||||
#endif
|
#endif
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
#ifdef USERPREFS_CHANNEL_1_PSK
|
||||||
|
static const uint8_t defaultpsk1[] = USERPREFS_CHANNEL_1_PSK;
|
||||||
|
memcpy(channelSettings.psk.bytes, defaultpsk1, sizeof(defaultpsk1));
|
||||||
|
channelSettings.psk.size = sizeof(defaultpsk1);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#ifdef USERPREFS_CHANNEL_1_NAME
|
||||||
|
strcpy(channelSettings.name, USERPREFS_CHANNEL_1_NAME);
|
||||||
|
#endif
|
||||||
|
#ifdef USERPREFS_CHANNEL_1_PRECISION
|
||||||
|
channelSettings.module_settings.position_precision = USERPREFS_CHANNEL_1_PRECISION;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
#ifdef USERPREFS_CHANNEL_2_PSK
|
||||||
|
static const uint8_t defaultpsk2[] = USERPREFS_CHANNEL_2_PSK;
|
||||||
|
memcpy(channelSettings.psk.bytes, defaultpsk2, sizeof(defaultpsk2));
|
||||||
|
channelSettings.psk.size = sizeof(defaultpsk2);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#ifdef USERPREFS_CHANNEL_2_NAME
|
||||||
|
strcpy(channelSettings.name, USERPREFS_CHANNEL_2_NAME);
|
||||||
|
#endif
|
||||||
|
#ifdef USERPREFS_CHANNEL_2_PRECISION
|
||||||
|
channelSettings.module_settings.position_precision = USERPREFS_CHANNEL_2_PRECISION;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,34 +175,19 @@ CryptoKey Channels::getKey(ChannelIndex chIndex)
|
|||||||
k.length = channelSettings.psk.size;
|
k.length = channelSettings.psk.size;
|
||||||
if (k.length == 0) {
|
if (k.length == 0) {
|
||||||
if (ch.role == meshtastic_Channel_Role_SECONDARY) {
|
if (ch.role == meshtastic_Channel_Role_SECONDARY) {
|
||||||
LOG_DEBUG("Unset PSK for secondary channel %s. using primary key\n", ch.settings.name);
|
LOG_DEBUG("Unset PSK for secondary channel %s. using primary key", ch.settings.name);
|
||||||
k = getKey(primaryIndex);
|
k = getKey(primaryIndex);
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN("User disabled encryption\n");
|
LOG_WARN("User disabled encryption");
|
||||||
}
|
}
|
||||||
} else if (k.length == 1) {
|
} else if (k.length == 1) {
|
||||||
// Convert the short single byte variants of psk into variant that can be used more generally
|
// Convert the short single byte variants of psk into variant that can be used more generally
|
||||||
|
|
||||||
uint8_t pskIndex = k.bytes[0];
|
uint8_t pskIndex = k.bytes[0];
|
||||||
LOG_DEBUG("Expanding short PSK #%d\n", pskIndex);
|
LOG_DEBUG("Expanding short PSK #%d", pskIndex);
|
||||||
if (pskIndex == 0)
|
if (pskIndex == 0)
|
||||||
k.length = 0; // Turn off encryption
|
k.length = 0; // Turn off encryption
|
||||||
else if (oemStore.oem_aes_key.size > 1) {
|
else {
|
||||||
// Use the OEM key
|
|
||||||
LOG_DEBUG("Using OEM Key with %d bytes\n", oemStore.oem_aes_key.size);
|
|
||||||
memcpy(k.bytes, oemStore.oem_aes_key.bytes, oemStore.oem_aes_key.size);
|
|
||||||
k.length = oemStore.oem_aes_key.size;
|
|
||||||
// Bump up the last byte of PSK as needed
|
|
||||||
uint8_t *last = k.bytes + oemStore.oem_aes_key.size - 1;
|
|
||||||
*last = *last + pskIndex - 1; // index of 1 means no change vs defaultPSK
|
|
||||||
if (k.length < 16) {
|
|
||||||
LOG_WARN("OEM provided a too short AES128 key - padding\n");
|
|
||||||
k.length = 16;
|
|
||||||
} else if (k.length < 32 && k.length != 16) {
|
|
||||||
LOG_WARN("OEM provided a too short AES256 key - padding\n");
|
|
||||||
k.length = 32;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
memcpy(k.bytes, defaultpsk, sizeof(defaultpsk));
|
memcpy(k.bytes, defaultpsk, sizeof(defaultpsk));
|
||||||
k.length = sizeof(defaultpsk);
|
k.length = sizeof(defaultpsk);
|
||||||
// Bump up the last byte of PSK as needed
|
// Bump up the last byte of PSK as needed
|
||||||
@@ -176,12 +197,12 @@ CryptoKey Channels::getKey(ChannelIndex chIndex)
|
|||||||
} else if (k.length < 16) {
|
} else if (k.length < 16) {
|
||||||
// Error! The user specified only the first few bits of an AES128 key. So by convention we just pad the rest of the
|
// Error! The user specified only the first few bits of an AES128 key. So by convention we just pad the rest of the
|
||||||
// key with zeros
|
// key with zeros
|
||||||
LOG_WARN("User provided a too short AES128 key - padding\n");
|
LOG_WARN("User provided a too short AES128 key - padding");
|
||||||
k.length = 16;
|
k.length = 16;
|
||||||
} else if (k.length < 32 && k.length != 16) {
|
} else if (k.length < 32 && k.length != 16) {
|
||||||
// Error! The user specified only the first few bits of an AES256 key. So by convention we just pad the rest of the
|
// Error! The user specified only the first few bits of an AES256 key. So by convention we just pad the rest of the
|
||||||
// key with zeros
|
// key with zeros
|
||||||
LOG_WARN("User provided a too short AES256 key - padding\n");
|
LOG_WARN("User provided a too short AES256 key - padding");
|
||||||
k.length = 32;
|
k.length = 32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -209,7 +230,15 @@ void Channels::initDefaults()
|
|||||||
channelFile.channels_count = MAX_NUM_CHANNELS;
|
channelFile.channels_count = MAX_NUM_CHANNELS;
|
||||||
for (int i = 0; i < channelFile.channels_count; i++)
|
for (int i = 0; i < channelFile.channels_count; i++)
|
||||||
fixupChannel(i);
|
fixupChannel(i);
|
||||||
|
initDefaultLoraConfig();
|
||||||
|
|
||||||
|
#ifdef USERPREFS_CHANNELS_TO_WRITE
|
||||||
|
for (int i = 0; i < USERPREFS_CHANNELS_TO_WRITE; i++) {
|
||||||
|
initDefaultChannel(i);
|
||||||
|
}
|
||||||
|
#else
|
||||||
initDefaultChannel(0);
|
initDefaultChannel(0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Channels::onConfigChanged()
|
void Channels::onConfigChanged()
|
||||||
@@ -223,7 +252,7 @@ void Channels::onConfigChanged()
|
|||||||
}
|
}
|
||||||
#if !MESHTASTIC_EXCLUDE_MQTT
|
#if !MESHTASTIC_EXCLUDE_MQTT
|
||||||
if (channels.anyMqttEnabled() && mqtt && !mqtt->isEnabled()) {
|
if (channels.anyMqttEnabled() && mqtt && !mqtt->isEnabled()) {
|
||||||
LOG_DEBUG("MQTT is enabled on at least one channel, so set MQTT thread to run immediately\n");
|
LOG_DEBUG("MQTT is enabled on at least one channel, so set MQTT thread to run immediately");
|
||||||
mqtt->start();
|
mqtt->start();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -236,7 +265,7 @@ meshtastic_Channel &Channels::getByIndex(ChannelIndex chIndex)
|
|||||||
meshtastic_Channel *ch = channelFile.channels + chIndex;
|
meshtastic_Channel *ch = channelFile.channels + chIndex;
|
||||||
return *ch;
|
return *ch;
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("Invalid channel index %d > %d, malformed packet received?\n", chIndex, channelFile.channels_count);
|
LOG_ERROR("Invalid channel index %d > %d, malformed packet received?", chIndex, channelFile.channels_count);
|
||||||
|
|
||||||
static meshtastic_Channel *ch = (meshtastic_Channel *)malloc(sizeof(meshtastic_Channel));
|
static meshtastic_Channel *ch = (meshtastic_Channel *)malloc(sizeof(meshtastic_Channel));
|
||||||
memset(ch, 0, sizeof(meshtastic_Channel));
|
memset(ch, 0, sizeof(meshtastic_Channel));
|
||||||
@@ -273,7 +302,7 @@ void Channels::setChannel(const meshtastic_Channel &c)
|
|||||||
|
|
||||||
bool Channels::anyMqttEnabled()
|
bool Channels::anyMqttEnabled()
|
||||||
{
|
{
|
||||||
#if EVENT_MODE
|
#if USERPREFS_EVENT_MODE
|
||||||
// Don't publish messages on the public MQTT broker if we are in event mode
|
// Don't publish messages on the public MQTT broker if we are in event mode
|
||||||
if (strcmp(moduleConfig.mqtt.address, default_mqtt_address) == 0) {
|
if (strcmp(moduleConfig.mqtt.address, default_mqtt_address) == 0) {
|
||||||
return false;
|
return false;
|
||||||
@@ -340,11 +369,11 @@ bool Channels::hasDefaultChannel()
|
|||||||
bool Channels::decryptForHash(ChannelIndex chIndex, ChannelHash channelHash)
|
bool Channels::decryptForHash(ChannelIndex chIndex, ChannelHash channelHash)
|
||||||
{
|
{
|
||||||
if (chIndex > getNumChannels() || getHash(chIndex) != channelHash) {
|
if (chIndex > getNumChannels() || getHash(chIndex) != channelHash) {
|
||||||
// LOG_DEBUG("Skipping channel %d (hash %x) due to invalid hash/index, want=%x\n", chIndex, getHash(chIndex),
|
// LOG_DEBUG("Skipping channel %d (hash %x) due to invalid hash/index, want=%x", chIndex, getHash(chIndex),
|
||||||
// channelHash);
|
// channelHash);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("Using channel %d (hash 0x%x)\n", chIndex, channelHash);
|
LOG_DEBUG("Using channel %d (hash 0x%x)", chIndex, channelHash);
|
||||||
setCrypto(chIndex);
|
setCrypto(chIndex);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -359,4 +388,4 @@ bool Channels::decryptForHash(ChannelIndex chIndex, ChannelHash channelHash)
|
|||||||
int16_t Channels::setActiveByIndex(ChannelIndex channelIndex)
|
int16_t Channels::setActiveByIndex(ChannelIndex channelIndex)
|
||||||
{
|
{
|
||||||
return setCrypto(channelIndex);
|
return setCrypto(channelIndex);
|
||||||
}
|
}
|
||||||
@@ -117,7 +117,12 @@ class Channels
|
|||||||
meshtastic_Channel &fixupChannel(ChannelIndex chIndex);
|
meshtastic_Channel &fixupChannel(ChannelIndex chIndex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a default channel to the specified channel index
|
* Writes the default lora config
|
||||||
|
*/
|
||||||
|
void initDefaultLoraConfig();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write default channels defined in UserPrefs
|
||||||
*/
|
*/
|
||||||
void initDefaultChannel(ChannelIndex chIndex);
|
void initDefaultChannel(ChannelIndex chIndex);
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
#include "CryptoEngine.h"
|
#include "CryptoEngine.h"
|
||||||
#include "NodeDB.h"
|
// #include "NodeDB.h"
|
||||||
#include "RadioInterface.h"
|
|
||||||
#include "architecture.h"
|
#include "architecture.h"
|
||||||
#include "configuration.h"
|
|
||||||
|
|
||||||
#if !(MESHTASTIC_EXCLUDE_PKI)
|
#if !(MESHTASTIC_EXCLUDE_PKI)
|
||||||
#include "aes-ccm.h"
|
#include "aes-ccm.h"
|
||||||
@@ -20,7 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
void CryptoEngine::generateKeyPair(uint8_t *pubKey, uint8_t *privKey)
|
void CryptoEngine::generateKeyPair(uint8_t *pubKey, uint8_t *privKey)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Generating Curve25519 key pair...\n");
|
LOG_DEBUG("Generating Curve25519 key pair...");
|
||||||
Curve25519::dh1(public_key, private_key);
|
Curve25519::dh1(public_key, private_key);
|
||||||
memcpy(pubKey, public_key, sizeof(public_key));
|
memcpy(pubKey, public_key, sizeof(public_key));
|
||||||
memcpy(privKey, private_key, sizeof(private_key));
|
memcpy(privKey, private_key, sizeof(private_key));
|
||||||
@@ -37,14 +35,14 @@ bool CryptoEngine::regeneratePublicKey(uint8_t *pubKey, uint8_t *privKey)
|
|||||||
if (!memfll(privKey, 0, sizeof(private_key))) {
|
if (!memfll(privKey, 0, sizeof(private_key))) {
|
||||||
Curve25519::eval(pubKey, privKey, 0);
|
Curve25519::eval(pubKey, privKey, 0);
|
||||||
if (Curve25519::isWeakPoint(pubKey)) {
|
if (Curve25519::isWeakPoint(pubKey)) {
|
||||||
LOG_ERROR("PKI key generation failed. Specified private key results in a weak\n");
|
LOG_ERROR("PKI key generation failed. Specified private key results in a weak");
|
||||||
memset(pubKey, 0, 32);
|
memset(pubKey, 0, 32);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
memcpy(private_key, privKey, sizeof(private_key));
|
memcpy(private_key, privKey, sizeof(private_key));
|
||||||
memcpy(public_key, pubKey, sizeof(public_key));
|
memcpy(public_key, pubKey, sizeof(public_key));
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN("X25519 key generation failed due to blank private key\n");
|
LOG_WARN("X25519 key generation failed due to blank private key");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -62,24 +60,23 @@ void CryptoEngine::clearKeys()
|
|||||||
*
|
*
|
||||||
* @param bytes is updated in place
|
* @param bytes is updated in place
|
||||||
*/
|
*/
|
||||||
bool CryptoEngine::encryptCurve25519(uint32_t toNode, uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes,
|
bool CryptoEngine::encryptCurve25519(uint32_t toNode, uint32_t fromNode, meshtastic_UserLite_public_key_t remotePublic,
|
||||||
uint8_t *bytesOut)
|
uint64_t packetNum, size_t numBytes, uint8_t *bytes, uint8_t *bytesOut)
|
||||||
{
|
{
|
||||||
uint8_t *auth;
|
uint8_t *auth;
|
||||||
uint32_t *extraNonce;
|
|
||||||
long extraNonceTmp = random();
|
long extraNonceTmp = random();
|
||||||
auth = bytesOut + numBytes;
|
auth = bytesOut + numBytes;
|
||||||
memcpy((uint8_t *)(auth + 8), &extraNonceTmp,
|
memcpy((uint8_t *)(auth + 8), &extraNonceTmp,
|
||||||
sizeof(uint32_t)); // do not use dereference on potential non aligned pointers : *extraNonce = extraNonceTmp;
|
sizeof(uint32_t)); // do not use dereference on potential non aligned pointers : *extraNonce = extraNonceTmp;
|
||||||
LOG_INFO("Random nonce value: %d\n", extraNonceTmp);
|
LOG_INFO("Random nonce value: %d", extraNonceTmp);
|
||||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(toNode);
|
if (remotePublic.size == 0) {
|
||||||
if (node->num < 1 || node->user.public_key.size == 0) {
|
LOG_DEBUG("Node %d or their public_key not found", toNode);
|
||||||
LOG_DEBUG("Node %d or their public_key not found\n", toNode);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!crypto->setDHKey(toNode)) {
|
if (!crypto->setDHPublicKey(remotePublic.bytes)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
crypto->hash(shared_key, 32);
|
||||||
initNonce(fromNode, packetNum, extraNonceTmp);
|
initNonce(fromNode, packetNum, extraNonceTmp);
|
||||||
|
|
||||||
// Calculate the shared secret with the destination node and encrypt
|
// Calculate the shared secret with the destination node and encrypt
|
||||||
@@ -98,27 +95,27 @@ bool CryptoEngine::encryptCurve25519(uint32_t toNode, uint32_t fromNode, uint64_
|
|||||||
*
|
*
|
||||||
* @param bytes is updated in place
|
* @param bytes is updated in place
|
||||||
*/
|
*/
|
||||||
bool CryptoEngine::decryptCurve25519(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes, uint8_t *bytesOut)
|
bool CryptoEngine::decryptCurve25519(uint32_t fromNode, meshtastic_UserLite_public_key_t remotePublic, uint64_t packetNum,
|
||||||
|
size_t numBytes, uint8_t *bytes, uint8_t *bytesOut)
|
||||||
{
|
{
|
||||||
uint8_t *auth; // set to last 8 bytes of text?
|
uint8_t *auth; // set to last 8 bytes of text?
|
||||||
uint32_t extraNonce; // pointer was not really used
|
uint32_t extraNonce; // pointer was not really used
|
||||||
auth = bytes + numBytes - 12;
|
auth = bytes + numBytes - 12;
|
||||||
#ifndef PIO_UNIT_TESTING
|
|
||||||
memcpy(&extraNonce, auth + 8,
|
memcpy(&extraNonce, auth + 8,
|
||||||
sizeof(uint32_t)); // do not use dereference on potential non aligned pointers : (uint32_t *)(auth + 8);
|
sizeof(uint32_t)); // do not use dereference on potential non aligned pointers : (uint32_t *)(auth + 8);
|
||||||
LOG_INFO("Random nonce value: %d\n", extraNonce);
|
LOG_INFO("Random nonce value: %d", extraNonce);
|
||||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(fromNode);
|
|
||||||
|
|
||||||
if (node == nullptr || node->num < 1 || node->user.public_key.size == 0) {
|
if (remotePublic.size == 0) {
|
||||||
LOG_DEBUG("Node or its public key not found in database\n");
|
LOG_DEBUG("Node or its public key not found in database");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the shared secret with the sending node and decrypt
|
// Calculate the shared secret with the sending node and decrypt
|
||||||
if (!crypto->setDHKey(fromNode)) {
|
if (!crypto->setDHPublicKey(remotePublic.bytes)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
crypto->hash(shared_key, 32);
|
||||||
|
|
||||||
initNonce(fromNode, packetNum, extraNonce);
|
initNonce(fromNode, packetNum, extraNonce);
|
||||||
printBytes("Attempting decrypt using nonce: ", nonce, 13);
|
printBytes("Attempting decrypt using nonce: ", nonce, 13);
|
||||||
printBytes("Attempting decrypt using shared_key starting with: ", shared_key, 8);
|
printBytes("Attempting decrypt using shared_key starting with: ", shared_key, 8);
|
||||||
@@ -129,38 +126,6 @@ void CryptoEngine::setDHPrivateKey(uint8_t *_private_key)
|
|||||||
{
|
{
|
||||||
memcpy(private_key, _private_key, 32);
|
memcpy(private_key, _private_key, 32);
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Set the PKI key used for encrypt, decrypt.
|
|
||||||
*
|
|
||||||
* @param nodeNum the node number of the node who's public key we want to use
|
|
||||||
*/
|
|
||||||
bool CryptoEngine::setDHKey(uint32_t nodeNum)
|
|
||||||
{
|
|
||||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeNum);
|
|
||||||
if (node->num < 1 || node->user.public_key.size == 0) {
|
|
||||||
LOG_DEBUG("Node %d or their public_key not found\n", nodeNum);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
printBytes("Generating DH with remote pubkey: ", node->user.public_key.bytes, 32);
|
|
||||||
printBytes("And local pubkey: ", config.security.public_key.bytes, 32);
|
|
||||||
if (!setDHPublicKey(node->user.public_key.bytes))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// printBytes("DH Output: ", shared_key, 32);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* D.J. Bernstein reccomends hashing the shared key. We want to do this because there are
|
|
||||||
* at least 128 bits of entropy in the 256-bit output of the DH key exchange, but we don't
|
|
||||||
* really know where. If you extract, for instance, the first 128 bits with basic truncation,
|
|
||||||
* then you don't know if you got all of your 128 entropy bits, or less, possibly much less.
|
|
||||||
*
|
|
||||||
* No exploitable bias is really known at that point, but we know enough to be wary.
|
|
||||||
* Hashing the DH output is a simple and safe way to gather all the entropy and spread
|
|
||||||
* it around as needed.
|
|
||||||
*/
|
|
||||||
crypto->hash(shared_key, 32);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hash arbitrary data using SHA256.
|
* Hash arbitrary data using SHA256.
|
||||||
@@ -209,7 +174,7 @@ bool CryptoEngine::setDHPublicKey(uint8_t *pubKey)
|
|||||||
// Calculate the shared secret with the specified node's public key and our private key
|
// Calculate the shared secret with the specified node's public key and our private key
|
||||||
// This includes an internal weak key check, which among other things looks for an all 0 public key and shared key.
|
// This includes an internal weak key check, which among other things looks for an all 0 public key and shared key.
|
||||||
if (!Curve25519::dh2(shared_key, local_priv)) {
|
if (!Curve25519::dh2(shared_key, local_priv)) {
|
||||||
LOG_WARN("Curve25519DH step 2 failed!\n");
|
LOG_WARN("Curve25519DH step 2 failed!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -220,7 +185,7 @@ concurrency::Lock *cryptLock;
|
|||||||
|
|
||||||
void CryptoEngine::setKey(const CryptoKey &k)
|
void CryptoEngine::setKey(const CryptoKey &k)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Using AES%d key!\n", k.length * 8);
|
LOG_DEBUG("Using AES%d key!", k.length * 8);
|
||||||
key = k;
|
key = k;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +201,7 @@ void CryptoEngine::encryptPacket(uint32_t fromNode, uint64_t packetId, size_t nu
|
|||||||
if (numBytes <= MAX_BLOCKSIZE) {
|
if (numBytes <= MAX_BLOCKSIZE) {
|
||||||
encryptAESCtr(key, nonce, numBytes, bytes);
|
encryptAESCtr(key, nonce, numBytes, bytes);
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("Packet too large for crypto engine: %d. noop encryption!\n", numBytes);
|
LOG_ERROR("Packet too large for crypto engine: %d. noop encryption!", numBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ class CryptoEngine
|
|||||||
#endif
|
#endif
|
||||||
void clearKeys();
|
void clearKeys();
|
||||||
void setDHPrivateKey(uint8_t *_private_key);
|
void setDHPrivateKey(uint8_t *_private_key);
|
||||||
virtual bool encryptCurve25519(uint32_t toNode, uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes,
|
virtual bool encryptCurve25519(uint32_t toNode, uint32_t fromNode, meshtastic_UserLite_public_key_t remotePublic,
|
||||||
uint8_t *bytesOut);
|
uint64_t packetNum, size_t numBytes, uint8_t *bytes, uint8_t *bytesOut);
|
||||||
virtual bool decryptCurve25519(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes, uint8_t *bytesOut);
|
virtual bool decryptCurve25519(uint32_t fromNode, meshtastic_UserLite_public_key_t remotePublic, uint64_t packetNum,
|
||||||
bool setDHKey(uint32_t nodeNum);
|
size_t numBytes, uint8_t *bytes, uint8_t *bytesOut);
|
||||||
virtual bool setDHPublicKey(uint8_t *publicKey);
|
virtual bool setDHPublicKey(uint8_t *publicKey);
|
||||||
virtual void hash(uint8_t *bytes, size_t numBytes);
|
virtual void hash(uint8_t *bytes, size_t numBytes);
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ uint32_t Default::getConfiguredOrDefaultMsScaled(uint32_t configured, uint32_t d
|
|||||||
|
|
||||||
uint8_t Default::getConfiguredOrDefaultHopLimit(uint8_t configured)
|
uint8_t Default::getConfiguredOrDefaultHopLimit(uint8_t configured)
|
||||||
{
|
{
|
||||||
#if EVENT_MODE
|
#if USERPREFS_EVENT_MODE
|
||||||
return (configured > HOP_RELIABLE) ? HOP_RELIABLE : config.lora.hop_limit;
|
return (configured > HOP_RELIABLE) ? HOP_RELIABLE : config.lora.hop_limit;
|
||||||
#else
|
#else
|
||||||
return (configured >= HOP_MAX) ? HOP_MAX : config.lora.hop_limit;
|
return (configured >= HOP_MAX) ? HOP_MAX : config.lora.hop_limit;
|
||||||
|
|||||||
@@ -21,11 +21,13 @@ ErrorCode FloodingRouter::send(meshtastic_MeshPacket *p)
|
|||||||
bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
|
bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
|
||||||
{
|
{
|
||||||
if (wasSeenRecently(p)) { // Note: this will also add a recent packet record
|
if (wasSeenRecently(p)) { // Note: this will also add a recent packet record
|
||||||
printPacket("Ignoring incoming msg we've already seen", p);
|
printPacket("Ignoring dupe incoming msg", p);
|
||||||
|
rxDupe++;
|
||||||
if (config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER &&
|
if (config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER &&
|
||||||
config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER) {
|
config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER) {
|
||||||
// cancel rebroadcast of this message *if* there was already one, unless we're a router/repeater!
|
// cancel rebroadcast of this message *if* there was already one, unless we're a router/repeater!
|
||||||
Router::cancelSending(p->from, p->id);
|
if (Router::cancelSending(p->from, p->id))
|
||||||
|
txRelayCanceled++;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -33,21 +35,27 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
|
|||||||
return Router::shouldFilterReceived(p);
|
return Router::shouldFilterReceived(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FloodingRouter::isRebroadcaster()
|
||||||
|
{
|
||||||
|
return config.device.role != meshtastic_Config_DeviceConfig_Role_CLIENT_MUTE &&
|
||||||
|
config.device.rebroadcast_mode != meshtastic_Config_DeviceConfig_RebroadcastMode_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c)
|
void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c)
|
||||||
{
|
{
|
||||||
bool isAckorReply = (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) && (p->decoded.request_id != 0);
|
bool isAckorReply = (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) && (p->decoded.request_id != 0);
|
||||||
if (isAckorReply && p->to != getNodeNum() && p->to != NODENUM_BROADCAST) {
|
if (isAckorReply && !isToUs(p) && p->to != NODENUM_BROADCAST) {
|
||||||
// do not flood direct message that is ACKed or replied to
|
// do not flood direct message that is ACKed or replied to
|
||||||
LOG_DEBUG("Receiving an ACK or reply not for me, but don't need to rebroadcast this direct message anymore.\n");
|
LOG_DEBUG("Rxd an ACK/reply not for me, cancel rebroadcast.");
|
||||||
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM
|
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM
|
||||||
}
|
}
|
||||||
if ((p->to != getNodeNum()) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum())) {
|
if (!isToUs(p) && (p->hop_limit > 0) && !isFromUs(p)) {
|
||||||
if (p->id != 0) {
|
if (p->id != 0) {
|
||||||
if (config.device.role != meshtastic_Config_DeviceConfig_Role_CLIENT_MUTE) {
|
if (isRebroadcaster()) {
|
||||||
meshtastic_MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it
|
meshtastic_MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it
|
||||||
|
|
||||||
tosend->hop_limit--; // bump down the hop count
|
tosend->hop_limit--; // bump down the hop count
|
||||||
#if EVENT_MODE
|
#if USERPREFS_EVENT_MODE
|
||||||
if (tosend->hop_limit > 2) {
|
if (tosend->hop_limit > 2) {
|
||||||
// if we are "correcting" the hop_limit, "correct" the hop_start by the same amount to preserve hops away.
|
// if we are "correcting" the hop_limit, "correct" the hop_start by the same amount to preserve hops away.
|
||||||
tosend->hop_start -= (tosend->hop_limit - 2);
|
tosend->hop_start -= (tosend->hop_limit - 2);
|
||||||
@@ -55,15 +63,15 @@ void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LOG_INFO("Rebroadcasting received floodmsg to neighbors\n");
|
LOG_INFO("Rebroadcasting received floodmsg");
|
||||||
// Note: we are careful to resend using the original senders node id
|
// Note: we are careful to resend using the original senders node id
|
||||||
// We are careful not to call our hooked version of send() - because we don't want to check this again
|
// We are careful not to call our hooked version of send() - because we don't want to check this again
|
||||||
Router::send(tosend);
|
Router::send(tosend);
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("Not rebroadcasting. Role = Role_ClientMute\n");
|
LOG_DEBUG("Not rebroadcasting: Role = CLIENT_MUTE or Rebroadcast Mode = NONE");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("Ignoring a simple (0 id) broadcast\n");
|
LOG_DEBUG("Ignoring 0 id broadcast");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// handle the packet as normal
|
// handle the packet as normal
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
class FloodingRouter : public Router, protected PacketHistory
|
class FloodingRouter : public Router, protected PacketHistory
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
bool isRebroadcaster();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ LR11x0Interface<T>::LR11x0Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs
|
|||||||
RADIOLIB_PIN_TYPE busy)
|
RADIOLIB_PIN_TYPE busy)
|
||||||
: RadioLibInterface(hal, cs, irq, rst, busy, &lora), lora(&module)
|
: RadioLibInterface(hal, cs, irq, rst, busy, &lora), lora(&module)
|
||||||
{
|
{
|
||||||
LOG_WARN("LR11x0Interface(cs=%d, irq=%d, rst=%d, busy=%d)\n", cs, irq, rst, busy);
|
LOG_WARN("LR11x0Interface(cs=%d, irq=%d, rst=%d, busy=%d)", cs, irq, rst, busy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialise the Driver transport hardware and software.
|
/// Initialise the Driver transport hardware and software.
|
||||||
@@ -54,10 +54,10 @@ template <typename T> bool LR11x0Interface<T>::init()
|
|||||||
0; // "TCXO reference voltage to be set on DIO3. Defaults to 1.6 V, set to 0 to skip." per
|
0; // "TCXO reference voltage to be set on DIO3. Defaults to 1.6 V, set to 0 to skip." per
|
||||||
// https://github.com/jgromes/RadioLib/blob/690a050ebb46e6097c5d00c371e961c1caa3b52e/src/modules/LR11x0/LR11x0.h#L471C26-L471C104
|
// https://github.com/jgromes/RadioLib/blob/690a050ebb46e6097c5d00c371e961c1caa3b52e/src/modules/LR11x0/LR11x0.h#L471C26-L471C104
|
||||||
// (DIO3 is free to be used as an IRQ)
|
// (DIO3 is free to be used as an IRQ)
|
||||||
LOG_DEBUG("LR11X0_DIO3_TCXO_VOLTAGE not defined, not using DIO3 as TCXO reference voltage\n");
|
LOG_DEBUG("LR11X0_DIO3_TCXO_VOLTAGE not defined, not using DIO3 as TCXO reference voltage");
|
||||||
#else
|
#else
|
||||||
float tcxoVoltage = LR11X0_DIO3_TCXO_VOLTAGE;
|
float tcxoVoltage = LR11X0_DIO3_TCXO_VOLTAGE;
|
||||||
LOG_DEBUG("LR11X0_DIO3_TCXO_VOLTAGE defined, using DIO3 as TCXO reference voltage at %f V\n", LR11X0_DIO3_TCXO_VOLTAGE);
|
LOG_DEBUG("LR11X0_DIO3_TCXO_VOLTAGE defined, using DIO3 as TCXO reference voltage at %f V", LR11X0_DIO3_TCXO_VOLTAGE);
|
||||||
// (DIO3 is not free to be used as an IRQ)
|
// (DIO3 is not free to be used as an IRQ)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -72,22 +72,33 @@ template <typename T> bool LR11x0Interface<T>::init()
|
|||||||
|
|
||||||
limitPower();
|
limitPower();
|
||||||
|
|
||||||
|
#ifdef LR11X0_RF_SWITCH_SUBGHZ
|
||||||
|
pinMode(LR11X0_RF_SWITCH_SUBGHZ, OUTPUT);
|
||||||
|
digitalWrite(LR11X0_RF_SWITCH_SUBGHZ, getFreq() < 1e9 ? HIGH : LOW);
|
||||||
|
LOG_DEBUG("Setting RF0 switch to %s", getFreq() < 1e9 ? "SubGHz" : "2.4GHz");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LR11X0_RF_SWITCH_2_4GHZ
|
||||||
|
pinMode(LR11X0_RF_SWITCH_2_4GHZ, OUTPUT);
|
||||||
|
digitalWrite(LR11X0_RF_SWITCH_2_4GHZ, getFreq() < 1e9 ? LOW : HIGH);
|
||||||
|
LOG_DEBUG("Setting RF1 switch to %s", getFreq() < 1e9 ? "SubGHz" : "2.4GHz");
|
||||||
|
#endif
|
||||||
|
|
||||||
int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage);
|
int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage);
|
||||||
// \todo Display actual typename of the adapter, not just `LR11x0`
|
// \todo Display actual typename of the adapter, not just `LR11x0`
|
||||||
LOG_INFO("LR11x0 init result %d\n", res);
|
LOG_INFO("LR11x0 init result %d", res);
|
||||||
if (res == RADIOLIB_ERR_CHIP_NOT_FOUND)
|
if (res == RADIOLIB_ERR_CHIP_NOT_FOUND)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
LR11x0VersionInfo_t version;
|
LR11x0VersionInfo_t version;
|
||||||
res = lora.getVersionInfo(&version);
|
res = lora.getVersionInfo(&version);
|
||||||
if (res == RADIOLIB_ERR_NONE)
|
if (res == RADIOLIB_ERR_NONE)
|
||||||
LOG_DEBUG("LR11x0 Device %d, HW %d, FW %d.%d, WiFi %d.%d, GNSS %d.%d\n", version.device, version.hardware,
|
LOG_DEBUG("LR11x0 Device %d, HW %d, FW %d.%d, WiFi %d.%d, GNSS %d.%d", version.device, version.hardware, version.fwMajor,
|
||||||
version.fwMajor, version.fwMinor, version.fwMajorWiFi, version.fwMinorWiFi, version.fwGNSS,
|
version.fwMinor, version.fwMajorWiFi, version.fwMinorWiFi, version.fwGNSS, version.almanacGNSS);
|
||||||
version.almanacGNSS);
|
|
||||||
|
|
||||||
LOG_INFO("Frequency set to %f\n", getFreq());
|
LOG_INFO("Frequency set to %f", getFreq());
|
||||||
LOG_INFO("Bandwidth set to %f\n", bw);
|
LOG_INFO("Bandwidth set to %f", bw);
|
||||||
LOG_INFO("Power output set to %d\n", power);
|
LOG_INFO("Power output set to %d", power);
|
||||||
|
|
||||||
if (res == RADIOLIB_ERR_NONE)
|
if (res == RADIOLIB_ERR_NONE)
|
||||||
res = lora.setCRC(2);
|
res = lora.setCRC(2);
|
||||||
@@ -109,16 +120,16 @@ template <typename T> bool LR11x0Interface<T>::init()
|
|||||||
|
|
||||||
if (dioAsRfSwitch) {
|
if (dioAsRfSwitch) {
|
||||||
lora.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table);
|
lora.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table);
|
||||||
LOG_DEBUG("Setting DIO RF switch\n", res);
|
LOG_DEBUG("Setting DIO RF switch", res);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res == RADIOLIB_ERR_NONE) {
|
if (res == RADIOLIB_ERR_NONE) {
|
||||||
if (config.lora.sx126x_rx_boosted_gain) { // the name is unfortunate but historically accurate
|
if (config.lora.sx126x_rx_boosted_gain) { // the name is unfortunate but historically accurate
|
||||||
res = lora.setRxBoostedGainMode(true);
|
res = lora.setRxBoostedGainMode(true);
|
||||||
LOG_INFO("Set RX gain to boosted mode; result: %d\n", res);
|
LOG_INFO("Set RX gain to boosted mode; result: %d", res);
|
||||||
} else {
|
} else {
|
||||||
res = lora.setRxBoostedGainMode(false);
|
res = lora.setRxBoostedGainMode(false);
|
||||||
LOG_INFO("Set RX gain to power saving mode (boosted mode off); result: %d\n", res);
|
LOG_INFO("Set RX gain to power saving mode (boosted mode off); result: %d", res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +199,7 @@ template <typename T> void LR11x0Interface<T>::setStandby()
|
|||||||
int err = lora.standby();
|
int err = lora.standby();
|
||||||
|
|
||||||
if (err != RADIOLIB_ERR_NONE) {
|
if (err != RADIOLIB_ERR_NONE) {
|
||||||
LOG_DEBUG("LR11x0 standby failed with error %d\n", err);
|
LOG_DEBUG("LR11x0 standby failed with error %d", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(err == RADIOLIB_ERR_NONE);
|
assert(err == RADIOLIB_ERR_NONE);
|
||||||
@@ -205,7 +216,7 @@ template <typename T> void LR11x0Interface<T>::setStandby()
|
|||||||
*/
|
*/
|
||||||
template <typename T> void LR11x0Interface<T>::addReceiveMetadata(meshtastic_MeshPacket *mp)
|
template <typename T> void LR11x0Interface<T>::addReceiveMetadata(meshtastic_MeshPacket *mp)
|
||||||
{
|
{
|
||||||
// LOG_DEBUG("PacketStatus %x\n", lora.getPacketStatus());
|
// LOG_DEBUG("PacketStatus %x", lora.getPacketStatus());
|
||||||
mp->rx_snr = lora.getSNR();
|
mp->rx_snr = lora.getSNR();
|
||||||
mp->rx_rssi = lround(lora.getRSSI());
|
mp->rx_rssi = lround(lora.getRSSI());
|
||||||
}
|
}
|
||||||
@@ -270,7 +281,7 @@ template <typename T> bool LR11x0Interface<T>::isActivelyReceiving()
|
|||||||
template <typename T> bool LR11x0Interface<T>::sleep()
|
template <typename T> bool LR11x0Interface<T>::sleep()
|
||||||
{
|
{
|
||||||
// \todo Display actual typename of the adapter, not just `LR11x0`
|
// \todo Display actual typename of the adapter, not just `LR11x0`
|
||||||
LOG_DEBUG("LR11x0 entering sleep mode\n");
|
LOG_DEBUG("LR11x0 entering sleep mode");
|
||||||
setStandby(); // Stop any pending operations
|
setStandby(); // Stop any pending operations
|
||||||
|
|
||||||
// turn off TCXO if it was powered
|
// turn off TCXO if it was powered
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ meshtastic_MeshPacket *MeshModule::allocAckNak(meshtastic_Routing_Error err, Nod
|
|||||||
p->decoded.request_id = idFrom;
|
p->decoded.request_id = idFrom;
|
||||||
p->channel = chIndex;
|
p->channel = chIndex;
|
||||||
if (err != meshtastic_Routing_Error_NONE)
|
if (err != meshtastic_Routing_Error_NONE)
|
||||||
LOG_WARN("Alloc an err=%d,to=0x%x,idFrom=0x%x,id=0x%x\n", err, to, idFrom, p->id);
|
LOG_WARN("Alloc an err=%d,to=0x%x,idFrom=0x%x,id=0x%x", err, to, idFrom, p->id);
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,7 @@ meshtastic_MeshPacket *MeshModule::allocErrorResponse(meshtastic_Routing_Error e
|
|||||||
|
|
||||||
void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
|
void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
|
||||||
{
|
{
|
||||||
// LOG_DEBUG("In call modules\n");
|
// LOG_DEBUG("In call modules");
|
||||||
bool moduleFound = false;
|
bool moduleFound = false;
|
||||||
|
|
||||||
// We now allow **encrypted** packets to pass through the modules
|
// We now allow **encrypted** packets to pass through the modules
|
||||||
@@ -86,7 +86,7 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
|
|||||||
|
|
||||||
// Was this message directed to us specifically? Will be false if we are sniffing someone elses packets
|
// Was this message directed to us specifically? Will be false if we are sniffing someone elses packets
|
||||||
auto ourNodeNum = nodeDB->getNodeNum();
|
auto ourNodeNum = nodeDB->getNodeNum();
|
||||||
bool toUs = mp.to == NODENUM_BROADCAST || mp.to == ourNodeNum;
|
bool toUs = mp.to == NODENUM_BROADCAST || isToUs(&mp);
|
||||||
|
|
||||||
for (auto i = modules->begin(); i != modules->end(); ++i) {
|
for (auto i = modules->begin(); i != modules->end(); ++i) {
|
||||||
auto &pi = **i;
|
auto &pi = **i;
|
||||||
@@ -104,7 +104,7 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
|
|||||||
assert(!pi.myReply); // If it is !null it means we have a bug, because it should have been sent the previous time
|
assert(!pi.myReply); // If it is !null it means we have a bug, because it should have been sent the previous time
|
||||||
|
|
||||||
if (wantsPacket) {
|
if (wantsPacket) {
|
||||||
LOG_DEBUG("Module '%s' wantsPacket=%d\n", pi.name, wantsPacket);
|
LOG_DEBUG("Module '%s' wantsPacket=%d", pi.name, wantsPacket);
|
||||||
|
|
||||||
moduleFound = true;
|
moduleFound = true;
|
||||||
|
|
||||||
@@ -141,24 +141,23 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
|
|||||||
// because currently when the phone sends things, it sends things using the local node ID as the from address. A
|
// because currently when the phone sends things, it sends things using the local node ID as the from address. A
|
||||||
// better solution (FIXME) would be to let phones have their own distinct addresses and we 'route' to them like
|
// better solution (FIXME) would be to let phones have their own distinct addresses and we 'route' to them like
|
||||||
// any other node.
|
// any other node.
|
||||||
if (isDecoded && mp.decoded.want_response && toUs && (getFrom(&mp) != ourNodeNum || mp.to == ourNodeNum) &&
|
if (isDecoded && mp.decoded.want_response && toUs && (!isFromUs(&mp) || isToUs(&mp)) && !currentReply) {
|
||||||
!currentReply) {
|
|
||||||
pi.sendResponse(mp);
|
pi.sendResponse(mp);
|
||||||
ignoreRequest = ignoreRequest || pi.ignoreRequest; // If at least one module asks it, we may ignore a request
|
ignoreRequest = ignoreRequest || pi.ignoreRequest; // If at least one module asks it, we may ignore a request
|
||||||
LOG_INFO("Asked module '%s' to send a response\n", pi.name);
|
LOG_INFO("Asked module '%s' to send a response", pi.name);
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("Module '%s' considered\n", pi.name);
|
LOG_DEBUG("Module '%s' considered", pi.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the requester didn't ask for a response we might need to discard unused replies to prevent memory leaks
|
// If the requester didn't ask for a response we might need to discard unused replies to prevent memory leaks
|
||||||
if (pi.myReply) {
|
if (pi.myReply) {
|
||||||
LOG_DEBUG("Discarding an unneeded response\n");
|
LOG_DEBUG("Discarding an unneeded response");
|
||||||
packetPool.release(pi.myReply);
|
packetPool.release(pi.myReply);
|
||||||
pi.myReply = NULL;
|
pi.myReply = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handled == ProcessMessage::STOP) {
|
if (handled == ProcessMessage::STOP) {
|
||||||
LOG_DEBUG("Module '%s' handled and skipped other processing\n", pi.name);
|
LOG_DEBUG("Module '%s' handled and skipped other processing", pi.name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,7 +176,7 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
|
|||||||
// no response reply
|
// no response reply
|
||||||
|
|
||||||
// No one wanted to reply to this request, tell the requster that happened
|
// No one wanted to reply to this request, tell the requster that happened
|
||||||
LOG_DEBUG("No one responded, send a nak\n");
|
LOG_DEBUG("No one responded, send a nak");
|
||||||
|
|
||||||
// SECURITY NOTE! I considered sending back a different error code if we didn't find the psk (i.e. !isDecoded)
|
// SECURITY NOTE! I considered sending back a different error code if we didn't find the psk (i.e. !isDecoded)
|
||||||
// but opted NOT TO. Because it is not a good idea to let remote nodes 'probe' to find out which PSKs were "good" vs
|
// but opted NOT TO. Because it is not a good idea to let remote nodes 'probe' to find out which PSKs were "good" vs
|
||||||
@@ -188,8 +187,7 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!moduleFound && isDecoded) {
|
if (!moduleFound && isDecoded) {
|
||||||
LOG_DEBUG("No modules interested in portnum=%d, src=%s\n", mp.decoded.portnum,
|
LOG_DEBUG("No modules interested in portnum=%d, src=%s", mp.decoded.portnum, (src == RX_SRC_LOCAL) ? "LOCAL" : "REMOTE");
|
||||||
(src == RX_SRC_LOCAL) ? "LOCAL" : "REMOTE");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,7 +210,7 @@ void MeshModule::sendResponse(const meshtastic_MeshPacket &req)
|
|||||||
currentReply = r;
|
currentReply = r;
|
||||||
} else {
|
} else {
|
||||||
// Ignore - this is now expected behavior for routing module (because it ignores some replies)
|
// Ignore - this is now expected behavior for routing module (because it ignores some replies)
|
||||||
// LOG_WARN("Client requested response but this module did not provide\n");
|
// LOG_WARN("Client requested response but this module did not provide");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,7 +239,7 @@ std::vector<MeshModule *> MeshModule::GetMeshModulesWithUIFrames()
|
|||||||
for (auto i = modules->begin(); i != modules->end(); ++i) {
|
for (auto i = modules->begin(); i != modules->end(); ++i) {
|
||||||
auto &pi = **i;
|
auto &pi = **i;
|
||||||
if (pi.wantUIFrame()) {
|
if (pi.wantUIFrame()) {
|
||||||
LOG_DEBUG("Module wants a UI Frame\n");
|
LOG_DEBUG("%s wants a UI Frame", pi.name);
|
||||||
modulesWithUIFrames.push_back(&pi);
|
modulesWithUIFrames.push_back(&pi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -256,7 +254,7 @@ void MeshModule::observeUIEvents(Observer<const UIFrameEvent *> *observer)
|
|||||||
auto &pi = **i;
|
auto &pi = **i;
|
||||||
Observable<const UIFrameEvent *> *observable = pi.getUIFrameObservable();
|
Observable<const UIFrameEvent *> *observable = pi.getUIFrameObservable();
|
||||||
if (observable != NULL) {
|
if (observable != NULL) {
|
||||||
LOG_DEBUG("Module wants a UI Frame\n");
|
LOG_DEBUG("%s wants a UI Frame", pi.name);
|
||||||
observer->observe(observable);
|
observer->observe(observable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,7 +272,7 @@ AdminMessageHandleResult MeshModule::handleAdminMessageForAllModules(const mesht
|
|||||||
AdminMessageHandleResult h = pi.handleAdminMessageForModule(mp, request, response);
|
AdminMessageHandleResult h = pi.handleAdminMessageForModule(mp, request, response);
|
||||||
if (h == AdminMessageHandleResult::HANDLED_WITH_RESPONSE) {
|
if (h == AdminMessageHandleResult::HANDLED_WITH_RESPONSE) {
|
||||||
// In case we have a response it always has priority.
|
// In case we have a response it always has priority.
|
||||||
LOG_DEBUG("Reply prepared by module '%s' of variant: %d\n", pi.name, response->which_payload_variant);
|
LOG_DEBUG("Reply prepared by module '%s' of variant: %d", pi.name, response->which_payload_variant);
|
||||||
handled = h;
|
handled = h;
|
||||||
} else if ((handled != AdminMessageHandleResult::HANDLED_WITH_RESPONSE) && (h == AdminMessageHandleResult::HANDLED)) {
|
} else if ((handled != AdminMessageHandleResult::HANDLED_WITH_RESPONSE) && (h == AdminMessageHandleResult::HANDLED)) {
|
||||||
// In case the message is handled it should be populated, but will not overwrite
|
// In case the message is handled it should be populated, but will not overwrite
|
||||||
@@ -297,4 +295,4 @@ bool MeshModule::isRequestingFocus()
|
|||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ bool CompareMeshPacketFunc(const meshtastic_MeshPacket *p1, const meshtastic_Mes
|
|||||||
auto p1p = getPriority(p1), p2p = getPriority(p2);
|
auto p1p = getPriority(p1), p2p = getPriority(p2);
|
||||||
// If priorities differ, use that
|
// If priorities differ, use that
|
||||||
// for equal priorities, prefer packets already on mesh.
|
// for equal priorities, prefer packets already on mesh.
|
||||||
return (p1p != p2p) ? (p1p > p2p) : (getFrom(p1) != nodeDB->getNodeNum() && getFrom(p2) == nodeDB->getNodeNum());
|
return (p1p != p2p) ? (p1p > p2p) : (!isFromUs(p1) && isFromUs(p2));
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshPacketQueue::MeshPacketQueue(size_t _maxLen) : maxLen(_maxLen) {}
|
MeshPacketQueue::MeshPacketQueue(size_t _maxLen) : maxLen(_maxLen) {}
|
||||||
|
|||||||
@@ -80,16 +80,15 @@ int MeshService::handleFromRadio(const meshtastic_MeshPacket *mp)
|
|||||||
nodeDB->updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio
|
nodeDB->updateFrom(*mp); // update our DB state based off sniffing every RX packet from the radio
|
||||||
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
|
if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag &&
|
||||||
mp->decoded.portnum == meshtastic_PortNum_TELEMETRY_APP && mp->decoded.request_id > 0) {
|
mp->decoded.portnum == meshtastic_PortNum_TELEMETRY_APP && mp->decoded.request_id > 0) {
|
||||||
LOG_DEBUG(
|
LOG_DEBUG("Received telemetry response. Skip sending our NodeInfo."); // because this potentially a Repeater which will
|
||||||
"Received telemetry response. Skip sending our NodeInfo because this potentially a Repeater which will ignore our "
|
// ignore our request for its NodeInfo
|
||||||
"request for its NodeInfo.\n");
|
|
||||||
} else if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB->getMeshNode(mp->from)->has_user &&
|
} else if (mp->which_payload_variant == meshtastic_MeshPacket_decoded_tag && !nodeDB->getMeshNode(mp->from)->has_user &&
|
||||||
nodeInfoModule) {
|
nodeInfoModule) {
|
||||||
LOG_INFO("Heard a node on channel %d we don't know, sending NodeInfo and asking for a response.\n", mp->channel);
|
LOG_INFO("Heard new node on channel %d, sending NodeInfo and asking for a response.", mp->channel);
|
||||||
if (airTime->isTxAllowedChannelUtil(true)) {
|
if (airTime->isTxAllowedChannelUtil(true)) {
|
||||||
nodeInfoModule->sendOurNodeInfo(mp->from, true, mp->channel);
|
nodeInfoModule->sendOurNodeInfo(mp->from, true, mp->channel);
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("Skip sending NodeInfo due to > 25 percent channel util.\n");
|
LOG_DEBUG("Skip sending NodeInfo due to > 25 percent channel util.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +130,7 @@ bool MeshService::reloadConfig(int saveWhat)
|
|||||||
/// The owner User record just got updated, update our node DB and broadcast the info into the mesh
|
/// The owner User record just got updated, update our node DB and broadcast the info into the mesh
|
||||||
void MeshService::reloadOwner(bool shouldSave)
|
void MeshService::reloadOwner(bool shouldSave)
|
||||||
{
|
{
|
||||||
// LOG_DEBUG("reloadOwner()\n");
|
// LOG_DEBUG("reloadOwner()");
|
||||||
// update our local data directly
|
// update our local data directly
|
||||||
nodeDB->updateUser(nodeDB->getNodeNum(), owner);
|
nodeDB->updateUser(nodeDB->getNodeNum(), owner);
|
||||||
assert(nodeInfoModule);
|
assert(nodeInfoModule);
|
||||||
@@ -181,7 +180,7 @@ void MeshService::handleToRadio(meshtastic_MeshPacket &p)
|
|||||||
// Switch the port from PortNum_SIMULATOR_APP back to the original PortNum
|
// Switch the port from PortNum_SIMULATOR_APP back to the original PortNum
|
||||||
p.decoded.portnum = decoded->portnum;
|
p.decoded.portnum = decoded->portnum;
|
||||||
} else
|
} else
|
||||||
LOG_ERROR("Error decoding protobuf for simulator message!\n");
|
LOG_ERROR("Error decoding protobuf for simulator message!");
|
||||||
}
|
}
|
||||||
// Let SimRadio receive as if it did via its LoRa chip
|
// Let SimRadio receive as if it did via its LoRa chip
|
||||||
SimRadio::instance->startReceive(&p);
|
SimRadio::instance->startReceive(&p);
|
||||||
@@ -223,7 +222,7 @@ ErrorCode MeshService::sendQueueStatusToPhone(const meshtastic_QueueStatus &qs,
|
|||||||
copied->mesh_packet_id = mesh_packet_id;
|
copied->mesh_packet_id = mesh_packet_id;
|
||||||
|
|
||||||
if (toPhoneQueueStatusQueue.numFree() == 0) {
|
if (toPhoneQueueStatusQueue.numFree() == 0) {
|
||||||
LOG_DEBUG("NOTE: tophone queue status queue is full, discarding oldest\n");
|
LOG_INFO("tophone queue status queue is full, discarding oldest");
|
||||||
meshtastic_QueueStatus *d = toPhoneQueueStatusQueue.dequeuePtr(0);
|
meshtastic_QueueStatus *d = toPhoneQueueStatusQueue.dequeuePtr(0);
|
||||||
if (d)
|
if (d)
|
||||||
releaseQueueStatusToPool(d);
|
releaseQueueStatusToPool(d);
|
||||||
@@ -267,14 +266,14 @@ bool MeshService::trySendPosition(NodeNum dest, bool wantReplies)
|
|||||||
if (hasValidPosition(node)) {
|
if (hasValidPosition(node)) {
|
||||||
#if HAS_GPS && !MESHTASTIC_EXCLUDE_GPS
|
#if HAS_GPS && !MESHTASTIC_EXCLUDE_GPS
|
||||||
if (positionModule) {
|
if (positionModule) {
|
||||||
LOG_INFO("Sending position ping to 0x%x, wantReplies=%d, channel=%d\n", dest, wantReplies, node->channel);
|
LOG_INFO("Sending position ping to 0x%x, wantReplies=%d, channel=%d", dest, wantReplies, node->channel);
|
||||||
positionModule->sendOurPosition(dest, wantReplies, node->channel);
|
positionModule->sendOurPosition(dest, wantReplies, node->channel);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#endif
|
#endif
|
||||||
if (nodeInfoModule) {
|
if (nodeInfoModule) {
|
||||||
LOG_INFO("Sending nodeinfo ping to 0x%x, wantReplies=%d, channel=%d\n", dest, wantReplies, node->channel);
|
LOG_INFO("Sending nodeinfo ping to 0x%x, wantReplies=%d, channel=%d", dest, wantReplies, node->channel);
|
||||||
nodeInfoModule->sendOurNodeInfo(dest, wantReplies, node->channel);
|
nodeInfoModule->sendOurNodeInfo(dest, wantReplies, node->channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -299,12 +298,12 @@ void MeshService::sendToPhone(meshtastic_MeshPacket *p)
|
|||||||
if (toPhoneQueue.numFree() == 0) {
|
if (toPhoneQueue.numFree() == 0) {
|
||||||
if (p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP ||
|
if (p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP ||
|
||||||
p->decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP) {
|
p->decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP) {
|
||||||
LOG_WARN("ToPhone queue is full, discarding oldest\n");
|
LOG_WARN("ToPhone queue is full, discarding oldest");
|
||||||
meshtastic_MeshPacket *d = toPhoneQueue.dequeuePtr(0);
|
meshtastic_MeshPacket *d = toPhoneQueue.dequeuePtr(0);
|
||||||
if (d)
|
if (d)
|
||||||
releaseToPool(d);
|
releaseToPool(d);
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN("ToPhone queue is full, dropping packet.\n");
|
LOG_WARN("ToPhone queue is full, dropping packet.");
|
||||||
releaseToPool(p);
|
releaseToPool(p);
|
||||||
fromNum++; // Make sure to notify observers in case they are reconnected so they can get the packets
|
fromNum++; // Make sure to notify observers in case they are reconnected so they can get the packets
|
||||||
return;
|
return;
|
||||||
@@ -317,9 +316,9 @@ void MeshService::sendToPhone(meshtastic_MeshPacket *p)
|
|||||||
|
|
||||||
void MeshService::sendMqttMessageToClientProxy(meshtastic_MqttClientProxyMessage *m)
|
void MeshService::sendMqttMessageToClientProxy(meshtastic_MqttClientProxyMessage *m)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Sending mqtt message on topic '%s' to client for proxying to server\n", m->topic);
|
LOG_DEBUG("Sending mqtt message on topic '%s' to client for proxy", m->topic);
|
||||||
if (toPhoneMqttProxyQueue.numFree() == 0) {
|
if (toPhoneMqttProxyQueue.numFree() == 0) {
|
||||||
LOG_WARN("MqttClientProxyMessagePool queue is full, discarding oldest\n");
|
LOG_WARN("MqttClientProxyMessagePool queue is full, discarding oldest");
|
||||||
meshtastic_MqttClientProxyMessage *d = toPhoneMqttProxyQueue.dequeuePtr(0);
|
meshtastic_MqttClientProxyMessage *d = toPhoneMqttProxyQueue.dequeuePtr(0);
|
||||||
if (d)
|
if (d)
|
||||||
releaseMqttClientProxyMessageToPool(d);
|
releaseMqttClientProxyMessageToPool(d);
|
||||||
@@ -331,9 +330,9 @@ void MeshService::sendMqttMessageToClientProxy(meshtastic_MqttClientProxyMessage
|
|||||||
|
|
||||||
void MeshService::sendClientNotification(meshtastic_ClientNotification *n)
|
void MeshService::sendClientNotification(meshtastic_ClientNotification *n)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Sending client notification to phone\n");
|
LOG_DEBUG("Sending client notification to phone");
|
||||||
if (toPhoneClientNotificationQueue.numFree() == 0) {
|
if (toPhoneClientNotificationQueue.numFree() == 0) {
|
||||||
LOG_WARN("ClientNotification queue is full, discarding oldest\n");
|
LOG_WARN("ClientNotification queue is full, discarding oldest");
|
||||||
meshtastic_ClientNotification *d = toPhoneClientNotificationQueue.dequeuePtr(0);
|
meshtastic_ClientNotification *d = toPhoneClientNotificationQueue.dequeuePtr(0);
|
||||||
if (d)
|
if (d)
|
||||||
releaseClientNotificationToPool(d);
|
releaseClientNotificationToPool(d);
|
||||||
@@ -382,12 +381,12 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
|
|||||||
} else {
|
} else {
|
||||||
// The GPS has lost lock
|
// The GPS has lost lock
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
LOG_DEBUG("onGPSchanged() - lost validLocation\n");
|
LOG_DEBUG("onGPSchanged() - lost validLocation");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// Used fixed position if configured regardless of GPS lock
|
// Used fixed position if configured regardless of GPS lock
|
||||||
if (config.position.fixed_position) {
|
if (config.position.fixed_position) {
|
||||||
LOG_WARN("Using fixed position\n");
|
LOG_WARN("Using fixed position");
|
||||||
pos = TypeConversions::ConvertToPosition(node->position);
|
pos = TypeConversions::ConvertToPosition(node->position);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,7 +394,7 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
|
|||||||
pos.time = getValidTime(RTCQualityFromNet);
|
pos.time = getValidTime(RTCQualityFromNet);
|
||||||
|
|
||||||
// In debug logs, identify position by @timestamp:stage (stage 4 = nodeDB)
|
// In debug logs, identify position by @timestamp:stage (stage 4 = nodeDB)
|
||||||
LOG_DEBUG("onGPSChanged() pos@%x time=%u lat=%d lon=%d alt=%d\n", pos.timestamp, pos.time, pos.latitude_i, pos.longitude_i,
|
LOG_DEBUG("onGPSChanged() pos@%x time=%u lat=%d lon=%d alt=%d", pos.timestamp, pos.time, pos.latitude_i, pos.longitude_i,
|
||||||
pos.altitude);
|
pos.altitude);
|
||||||
|
|
||||||
// Update our current position in the local DB
|
// Update our current position in the local DB
|
||||||
@@ -408,3 +407,15 @@ bool MeshService::isToPhoneQueueEmpty()
|
|||||||
{
|
{
|
||||||
return toPhoneQueue.isEmpty();
|
return toPhoneQueue.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t MeshService::GetTimeSinceMeshPacket(const meshtastic_MeshPacket *mp)
|
||||||
|
{
|
||||||
|
uint32_t now = getTime();
|
||||||
|
|
||||||
|
uint32_t last_seen = mp->rx_time;
|
||||||
|
int delta = (int)(now - last_seen);
|
||||||
|
if (delta < 0) // our clock must be slightly off still - not set from GPS yet
|
||||||
|
delta = 0;
|
||||||
|
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|||||||
@@ -151,6 +151,8 @@ class MeshService
|
|||||||
|
|
||||||
ErrorCode sendQueueStatusToPhone(const meshtastic_QueueStatus &qs, ErrorCode res, uint32_t mesh_packet_id);
|
ErrorCode sendQueueStatusToPhone(const meshtastic_QueueStatus &qs, ErrorCode res, uint32_t mesh_packet_id);
|
||||||
|
|
||||||
|
uint32_t GetTimeSinceMeshPacket(const meshtastic_MeshPacket *mp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#if HAS_GPS
|
#if HAS_GPS
|
||||||
/// Called when our gps position has changed - updates nodedb and sends Location message out into the mesh
|
/// Called when our gps position has changed - updates nodedb and sends Location message out into the mesh
|
||||||
@@ -163,4 +165,4 @@ class MeshService
|
|||||||
friend class RoutingModule;
|
friend class RoutingModule;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern MeshService *service;
|
extern MeshService *service;
|
||||||
|
|||||||
@@ -50,5 +50,11 @@ extern Allocator<meshtastic_MeshPacket> &packetPool;
|
|||||||
*/
|
*/
|
||||||
NodeNum getFrom(const meshtastic_MeshPacket *p);
|
NodeNum getFrom(const meshtastic_MeshPacket *p);
|
||||||
|
|
||||||
|
// Returns true if the packet originated from the local node
|
||||||
|
bool isFromUs(const meshtastic_MeshPacket *p);
|
||||||
|
|
||||||
|
// Returns true if the packet is destined to us
|
||||||
|
bool isToUs(const meshtastic_MeshPacket *p);
|
||||||
|
|
||||||
/* Some clients might not properly set priority, therefore we fix it here. */
|
/* Some clients might not properly set priority, therefore we fix it here. */
|
||||||
void fixPriority(meshtastic_MeshPacket *p);
|
void fixPriority(meshtastic_MeshPacket *p);
|
||||||
@@ -55,8 +55,6 @@ meshtastic_MyNodeInfo &myNodeInfo = devicestate.my_node;
|
|||||||
meshtastic_LocalConfig config;
|
meshtastic_LocalConfig config;
|
||||||
meshtastic_LocalModuleConfig moduleConfig;
|
meshtastic_LocalModuleConfig moduleConfig;
|
||||||
meshtastic_ChannelFile channelFile;
|
meshtastic_ChannelFile channelFile;
|
||||||
meshtastic_OEMStore oemStore;
|
|
||||||
static bool hasOemStore = false;
|
|
||||||
|
|
||||||
bool meshtastic_DeviceState_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field)
|
bool meshtastic_DeviceState_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field)
|
||||||
{
|
{
|
||||||
@@ -102,7 +100,7 @@ static uint8_t ourMacAddr[6];
|
|||||||
|
|
||||||
NodeDB::NodeDB()
|
NodeDB::NodeDB()
|
||||||
{
|
{
|
||||||
LOG_INFO("Initializing NodeDB\n");
|
LOG_INFO("Initializing NodeDB");
|
||||||
loadFromDisk();
|
loadFromDisk();
|
||||||
cleanupMeshDB();
|
cleanupMeshDB();
|
||||||
|
|
||||||
@@ -140,7 +138,7 @@ NodeDB::NodeDB()
|
|||||||
keygenSuccess = true;
|
keygenSuccess = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("Generating new PKI keys\n");
|
LOG_INFO("Generating new PKI keys");
|
||||||
crypto->generateKeyPair(config.security.public_key.bytes, config.security.private_key.bytes);
|
crypto->generateKeyPair(config.security.public_key.bytes, config.security.private_key.bytes);
|
||||||
keygenSuccess = true;
|
keygenSuccess = true;
|
||||||
}
|
}
|
||||||
@@ -167,11 +165,11 @@ NodeDB::NodeDB()
|
|||||||
preferences.begin("meshtastic", false);
|
preferences.begin("meshtastic", false);
|
||||||
myNodeInfo.reboot_count = preferences.getUInt("rebootCounter", 0);
|
myNodeInfo.reboot_count = preferences.getUInt("rebootCounter", 0);
|
||||||
preferences.end();
|
preferences.end();
|
||||||
LOG_DEBUG("Number of Device Reboots: %d\n", myNodeInfo.reboot_count);
|
LOG_DEBUG("Number of Device Reboots: %d", myNodeInfo.reboot_count);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
resetRadioConfig(); // If bogus settings got saved, then fix them
|
resetRadioConfig(); // If bogus settings got saved, then fix them
|
||||||
// nodeDB->LOG_DEBUG("region=%d, NODENUM=0x%x, dbsize=%d\n", config.lora.region, myNodeInfo.my_node_num, numMeshNodes);
|
// nodeDB->LOG_DEBUG("region=%d, NODENUM=0x%x, dbsize=%d", config.lora.region, myNodeInfo.my_node_num, numMeshNodes);
|
||||||
|
|
||||||
if (devicestateCRC != crc32Buffer(&devicestate, sizeof(devicestate)))
|
if (devicestateCRC != crc32Buffer(&devicestate, sizeof(devicestate)))
|
||||||
saveWhat |= SEGMENT_DEVICESTATE;
|
saveWhat |= SEGMENT_DEVICESTATE;
|
||||||
@@ -196,6 +194,18 @@ NodeNum getFrom(const meshtastic_MeshPacket *p)
|
|||||||
return (p->from == 0) ? nodeDB->getNodeNum() : p->from;
|
return (p->from == 0) ? nodeDB->getNodeNum() : p->from;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true if the packet originated from the local node
|
||||||
|
bool isFromUs(const meshtastic_MeshPacket *p)
|
||||||
|
{
|
||||||
|
return p->from == 0 || p->from == nodeDB->getNodeNum();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if the packet is destined to us
|
||||||
|
bool isToUs(const meshtastic_MeshPacket *p)
|
||||||
|
{
|
||||||
|
return p->to == nodeDB->getNodeNum();
|
||||||
|
}
|
||||||
|
|
||||||
bool NodeDB::resetRadioConfig(bool factory_reset)
|
bool NodeDB::resetRadioConfig(bool factory_reset)
|
||||||
{
|
{
|
||||||
bool didFactoryReset = false;
|
bool didFactoryReset = false;
|
||||||
@@ -207,7 +217,7 @@ bool NodeDB::resetRadioConfig(bool factory_reset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (channelFile.channels_count != MAX_NUM_CHANNELS) {
|
if (channelFile.channels_count != MAX_NUM_CHANNELS) {
|
||||||
LOG_INFO("Setting default channel and radio preferences!\n");
|
LOG_INFO("Setting default channel and radio preferences!");
|
||||||
|
|
||||||
channels.initDefaults();
|
channels.initDefaults();
|
||||||
}
|
}
|
||||||
@@ -228,12 +238,12 @@ bool NodeDB::resetRadioConfig(bool factory_reset)
|
|||||||
|
|
||||||
bool NodeDB::factoryReset(bool eraseBleBonds)
|
bool NodeDB::factoryReset(bool eraseBleBonds)
|
||||||
{
|
{
|
||||||
LOG_INFO("Performing factory reset!\n");
|
LOG_INFO("Performing factory reset!");
|
||||||
// first, remove the "/prefs" (this removes most prefs)
|
// first, remove the "/prefs" (this removes most prefs)
|
||||||
rmDir("/prefs");
|
rmDir("/prefs");
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
if (FSCom.exists("/static/rangetest.csv") && !FSCom.remove("/static/rangetest.csv")) {
|
if (FSCom.exists("/static/rangetest.csv") && !FSCom.remove("/static/rangetest.csv")) {
|
||||||
LOG_ERROR("Could not remove rangetest.csv file\n");
|
LOG_ERROR("Could not remove rangetest.csv file");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// second, install default state (this will deal with the duplicate mac address issue)
|
// second, install default state (this will deal with the duplicate mac address issue)
|
||||||
@@ -244,14 +254,14 @@ bool NodeDB::factoryReset(bool eraseBleBonds)
|
|||||||
// third, write everything to disk
|
// third, write everything to disk
|
||||||
saveToDisk();
|
saveToDisk();
|
||||||
if (eraseBleBonds) {
|
if (eraseBleBonds) {
|
||||||
LOG_INFO("Erasing BLE bonds\n");
|
LOG_INFO("Erasing BLE bonds");
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
// This will erase what's in NVS including ssl keys, persistent variables and ble pairing
|
// This will erase what's in NVS including ssl keys, persistent variables and ble pairing
|
||||||
nvs_flash_erase();
|
nvs_flash_erase();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ARCH_NRF52
|
#ifdef ARCH_NRF52
|
||||||
Bluefruit.begin();
|
Bluefruit.begin();
|
||||||
LOG_INFO("Clearing bluetooth bonds!\n");
|
LOG_INFO("Clearing bluetooth bonds!");
|
||||||
bond_print_list(BLE_GAP_ROLE_PERIPH);
|
bond_print_list(BLE_GAP_ROLE_PERIPH);
|
||||||
bond_print_list(BLE_GAP_ROLE_CENTRAL);
|
bond_print_list(BLE_GAP_ROLE_CENTRAL);
|
||||||
Bluefruit.Periph.clearBonds();
|
Bluefruit.Periph.clearBonds();
|
||||||
@@ -268,7 +278,7 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
|
|||||||
if (shouldPreserveKey) {
|
if (shouldPreserveKey) {
|
||||||
memcpy(private_key_temp, config.security.private_key.bytes, config.security.private_key.size);
|
memcpy(private_key_temp, config.security.private_key.bytes, config.security.private_key.size);
|
||||||
}
|
}
|
||||||
LOG_INFO("Installing default LocalConfig\n");
|
LOG_INFO("Installing default LocalConfig");
|
||||||
memset(&config, 0, sizeof(meshtastic_LocalConfig));
|
memset(&config, 0, sizeof(meshtastic_LocalConfig));
|
||||||
config.version = DEVICESTATE_CUR_VER;
|
config.version = DEVICESTATE_CUR_VER;
|
||||||
config.has_device = true;
|
config.has_device = true;
|
||||||
@@ -286,27 +296,26 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
|
|||||||
true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off)
|
true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off)
|
||||||
config.lora.override_duty_cycle = false;
|
config.lora.override_duty_cycle = false;
|
||||||
config.lora.config_ok_to_mqtt = false;
|
config.lora.config_ok_to_mqtt = false;
|
||||||
#ifdef CONFIG_LORA_REGION_USERPREFS
|
#ifdef USERPREFS_CONFIG_LORA_REGION
|
||||||
config.lora.region = CONFIG_LORA_REGION_USERPREFS;
|
config.lora.region = USERPREFS_CONFIG_LORA_REGION;
|
||||||
#else
|
#else
|
||||||
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET;
|
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET;
|
||||||
#endif
|
#endif
|
||||||
#ifdef LORACONFIG_MODEM_PRESET_USERPREFS
|
#ifdef USERPREFS_LORACONFIG_MODEM_PRESET
|
||||||
config.lora.modem_preset = LORACONFIG_MODEM_PRESET_USERPREFS;
|
config.lora.modem_preset = USERPREFS_LORACONFIG_MODEM_PRESET;
|
||||||
#else
|
#else
|
||||||
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST;
|
config.lora.modem_preset = meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST;
|
||||||
#endif
|
#endif
|
||||||
config.lora.hop_limit = HOP_RELIABLE;
|
config.lora.hop_limit = HOP_RELIABLE;
|
||||||
#ifdef CONFIG_LORA_IGNORE_MQTT_USERPREFS
|
#ifdef USERPREFS_CONFIG_LORA_IGNORE_MQTT
|
||||||
config.lora.ignore_mqtt = CONFIG_LORA_IGNORE_MQTT_USERPREFS;
|
config.lora.ignore_mqtt = USERPREFS_CONFIG_LORA_IGNORE_MQTT;
|
||||||
#else
|
#else
|
||||||
config.lora.ignore_mqtt = false;
|
config.lora.ignore_mqtt = false;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ADMIN_KEY_USERPREFS
|
#ifdef USERPREFS_USE_ADMIN_KEY
|
||||||
memcpy(config.security.admin_key[0].bytes, admin_key_userprefs, 32);
|
memcpy(config.security.admin_key[0].bytes, USERPREFS_ADMIN_KEY, 32);
|
||||||
config.security.admin_key[0].size = 32;
|
config.security.admin_key[0].size = 32;
|
||||||
#else
|
config.security.admin_key_count = 1;
|
||||||
config.security.admin_key[0].size = 0;
|
|
||||||
#endif
|
#endif
|
||||||
if (shouldPreserveKey) {
|
if (shouldPreserveKey) {
|
||||||
config.security.private_key.size = 32;
|
config.security.private_key.size = 32;
|
||||||
@@ -324,7 +333,9 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
|
|||||||
#else
|
#else
|
||||||
config.device.disable_triple_click = true;
|
config.device.disable_triple_click = true;
|
||||||
#endif
|
#endif
|
||||||
#if !HAS_GPS || defined(T_DECK) || defined(TLORA_T3S3_EPAPER)
|
#if defined(USERPREFS_CONFIG_GPS_MODE)
|
||||||
|
config.position.gps_mode = USERPREFS_CONFIG_GPS_MODE;
|
||||||
|
#elif !HAS_GPS || defined(T_DECK) || defined(TLORA_T3S3_EPAPER)
|
||||||
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT;
|
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT;
|
||||||
#elif !defined(GPS_RX_PIN)
|
#elif !defined(GPS_RX_PIN)
|
||||||
if (config.position.rx_gpio == 0)
|
if (config.position.rx_gpio == 0)
|
||||||
@@ -346,8 +357,8 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
|
|||||||
// FIXME: Default to bluetooth capability of platform as default
|
// FIXME: Default to bluetooth capability of platform as default
|
||||||
config.bluetooth.enabled = true;
|
config.bluetooth.enabled = true;
|
||||||
config.bluetooth.fixed_pin = defaultBLEPin;
|
config.bluetooth.fixed_pin = defaultBLEPin;
|
||||||
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7789_CS) || defined(HX8357_CS) || \
|
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7789_CS) || \
|
||||||
defined(USE_ST7789)
|
defined(HX8357_CS) || defined(USE_ST7789)
|
||||||
bool hasScreen = true;
|
bool hasScreen = true;
|
||||||
#elif ARCH_PORTDUINO
|
#elif ARCH_PORTDUINO
|
||||||
bool hasScreen = false;
|
bool hasScreen = false;
|
||||||
@@ -405,7 +416,7 @@ void NodeDB::initConfigIntervals()
|
|||||||
|
|
||||||
void NodeDB::installDefaultModuleConfig()
|
void NodeDB::installDefaultModuleConfig()
|
||||||
{
|
{
|
||||||
LOG_INFO("Installing default ModuleConfig\n");
|
LOG_INFO("Installing default ModuleConfig");
|
||||||
memset(&moduleConfig, 0, sizeof(meshtastic_ModuleConfig));
|
memset(&moduleConfig, 0, sizeof(meshtastic_ModuleConfig));
|
||||||
|
|
||||||
moduleConfig.version = DEVICESTATE_CUR_VER;
|
moduleConfig.version = DEVICESTATE_CUR_VER;
|
||||||
@@ -520,6 +531,7 @@ void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role)
|
|||||||
moduleConfig.telemetry.device_update_interval = UINT32_MAX;
|
moduleConfig.telemetry.device_update_interval = UINT32_MAX;
|
||||||
moduleConfig.telemetry.environment_update_interval = UINT32_MAX;
|
moduleConfig.telemetry.environment_update_interval = UINT32_MAX;
|
||||||
moduleConfig.telemetry.air_quality_interval = UINT32_MAX;
|
moduleConfig.telemetry.air_quality_interval = UINT32_MAX;
|
||||||
|
moduleConfig.telemetry.health_update_interval = UINT32_MAX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -530,22 +542,26 @@ void NodeDB::initModuleConfigIntervals()
|
|||||||
moduleConfig.telemetry.environment_update_interval = 0;
|
moduleConfig.telemetry.environment_update_interval = 0;
|
||||||
moduleConfig.telemetry.air_quality_interval = 0;
|
moduleConfig.telemetry.air_quality_interval = 0;
|
||||||
moduleConfig.telemetry.power_update_interval = 0;
|
moduleConfig.telemetry.power_update_interval = 0;
|
||||||
|
moduleConfig.telemetry.health_update_interval = 0;
|
||||||
moduleConfig.neighbor_info.update_interval = 0;
|
moduleConfig.neighbor_info.update_interval = 0;
|
||||||
moduleConfig.paxcounter.paxcounter_update_interval = 0;
|
moduleConfig.paxcounter.paxcounter_update_interval = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeDB::installDefaultChannels()
|
void NodeDB::installDefaultChannels()
|
||||||
{
|
{
|
||||||
LOG_INFO("Installing default ChannelFile\n");
|
LOG_INFO("Installing default ChannelFile");
|
||||||
memset(&channelFile, 0, sizeof(meshtastic_ChannelFile));
|
memset(&channelFile, 0, sizeof(meshtastic_ChannelFile));
|
||||||
channelFile.version = DEVICESTATE_CUR_VER;
|
channelFile.version = DEVICESTATE_CUR_VER;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeDB::resetNodes()
|
void NodeDB::resetNodes()
|
||||||
{
|
{
|
||||||
clearLocalPosition();
|
if (!config.position.fixed_position)
|
||||||
|
clearLocalPosition();
|
||||||
numMeshNodes = 1;
|
numMeshNodes = 1;
|
||||||
std::fill(devicestate.node_db_lite.begin() + 1, devicestate.node_db_lite.end(), meshtastic_NodeInfoLite());
|
std::fill(devicestate.node_db_lite.begin() + 1, devicestate.node_db_lite.end(), meshtastic_NodeInfoLite());
|
||||||
|
devicestate.has_rx_text_message = false;
|
||||||
|
devicestate.has_rx_waypoint = false;
|
||||||
saveDeviceStateToDisk();
|
saveDeviceStateToDisk();
|
||||||
if (neighborInfoModule && moduleConfig.neighbor_info.enabled)
|
if (neighborInfoModule && moduleConfig.neighbor_info.enabled)
|
||||||
neighborInfoModule->resetNeighbors();
|
neighborInfoModule->resetNeighbors();
|
||||||
@@ -563,7 +579,7 @@ void NodeDB::removeNodeByNum(NodeNum nodeNum)
|
|||||||
numMeshNodes -= removed;
|
numMeshNodes -= removed;
|
||||||
std::fill(devicestate.node_db_lite.begin() + numMeshNodes, devicestate.node_db_lite.begin() + numMeshNodes + 1,
|
std::fill(devicestate.node_db_lite.begin() + numMeshNodes, devicestate.node_db_lite.begin() + numMeshNodes + 1,
|
||||||
meshtastic_NodeInfoLite());
|
meshtastic_NodeInfoLite());
|
||||||
LOG_DEBUG("NodeDB::removeNodeByNum purged %d entries. Saving changes...\n", removed);
|
LOG_DEBUG("NodeDB::removeNodeByNum purged %d entries. Saving changes...", removed);
|
||||||
saveDeviceStateToDisk();
|
saveDeviceStateToDisk();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -595,12 +611,12 @@ void NodeDB::cleanupMeshDB()
|
|||||||
numMeshNodes -= removed;
|
numMeshNodes -= removed;
|
||||||
std::fill(devicestate.node_db_lite.begin() + numMeshNodes, devicestate.node_db_lite.begin() + numMeshNodes + removed,
|
std::fill(devicestate.node_db_lite.begin() + numMeshNodes, devicestate.node_db_lite.begin() + numMeshNodes + removed,
|
||||||
meshtastic_NodeInfoLite());
|
meshtastic_NodeInfoLite());
|
||||||
LOG_DEBUG("cleanupMeshDB purged %d entries\n", removed);
|
LOG_DEBUG("cleanupMeshDB purged %d entries", removed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeDB::installDefaultDeviceState()
|
void NodeDB::installDefaultDeviceState()
|
||||||
{
|
{
|
||||||
LOG_INFO("Installing default DeviceState\n");
|
LOG_INFO("Installing default DeviceState");
|
||||||
// memset(&devicestate, 0, sizeof(meshtastic_DeviceState));
|
// memset(&devicestate, 0, sizeof(meshtastic_DeviceState));
|
||||||
|
|
||||||
numMeshNodes = 0;
|
numMeshNodes = 0;
|
||||||
@@ -612,18 +628,20 @@ void NodeDB::installDefaultDeviceState()
|
|||||||
// devicestate.node_db_lite_count = 0;
|
// devicestate.node_db_lite_count = 0;
|
||||||
devicestate.version = DEVICESTATE_CUR_VER;
|
devicestate.version = DEVICESTATE_CUR_VER;
|
||||||
devicestate.receive_queue_count = 0; // Not yet implemented FIXME
|
devicestate.receive_queue_count = 0; // Not yet implemented FIXME
|
||||||
|
devicestate.has_rx_waypoint = false;
|
||||||
|
devicestate.has_rx_text_message = false;
|
||||||
|
|
||||||
generatePacketId(); // FIXME - ugly way to init current_packet_id;
|
generatePacketId(); // FIXME - ugly way to init current_packet_id;
|
||||||
|
|
||||||
// Set default owner name
|
// Set default owner name
|
||||||
pickNewNodeNum(); // based on macaddr now
|
pickNewNodeNum(); // based on macaddr now
|
||||||
#ifdef CONFIG_OWNER_LONG_NAME_USERPREFS
|
#ifdef USERPREFS_CONFIG_OWNER_LONG_NAME
|
||||||
snprintf(owner.long_name, sizeof(owner.long_name), CONFIG_OWNER_LONG_NAME_USERPREFS);
|
snprintf(owner.long_name, sizeof(owner.long_name), USERPREFS_CONFIG_OWNER_LONG_NAME);
|
||||||
#else
|
#else
|
||||||
snprintf(owner.long_name, sizeof(owner.long_name), "Meshtastic %02x%02x", ourMacAddr[4], ourMacAddr[5]);
|
snprintf(owner.long_name, sizeof(owner.long_name), "Meshtastic %02x%02x", ourMacAddr[4], ourMacAddr[5]);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_OWNER_SHORT_NAME_USERPREFS
|
#ifdef USERPREFS_CONFIG_OWNER_SHORT_NAME
|
||||||
snprintf(owner.short_name, sizeof(owner.short_name), CONFIG_OWNER_SHORT_NAME_USERPREFS);
|
snprintf(owner.short_name, sizeof(owner.short_name), USERPREFS_CONFIG_OWNER_SHORT_NAME);
|
||||||
#else
|
#else
|
||||||
snprintf(owner.short_name, sizeof(owner.short_name), "%02x%02x", ourMacAddr[4], ourMacAddr[5]);
|
snprintf(owner.short_name, sizeof(owner.short_name), "%02x%02x", ourMacAddr[4], ourMacAddr[5]);
|
||||||
#endif
|
#endif
|
||||||
@@ -652,11 +670,11 @@ void NodeDB::pickNewNodeNum()
|
|||||||
NodeNum candidate = random(NUM_RESERVED, LONG_MAX); // try a new random choice
|
NodeNum candidate = random(NUM_RESERVED, LONG_MAX); // try a new random choice
|
||||||
if (found)
|
if (found)
|
||||||
LOG_WARN("NOTE! Our desired nodenum 0x%x is invalid or in use, by MAC ending in 0x%02x%02x vs our 0x%02x%02x, so "
|
LOG_WARN("NOTE! Our desired nodenum 0x%x is invalid or in use, by MAC ending in 0x%02x%02x vs our 0x%02x%02x, so "
|
||||||
"trying for 0x%x\n",
|
"trying for 0x%x",
|
||||||
nodeNum, found->user.macaddr[4], found->user.macaddr[5], ourMacAddr[4], ourMacAddr[5], candidate);
|
nodeNum, found->user.macaddr[4], found->user.macaddr[5], ourMacAddr[4], ourMacAddr[5], candidate);
|
||||||
nodeNum = candidate;
|
nodeNum = candidate;
|
||||||
}
|
}
|
||||||
LOG_DEBUG("Using nodenum 0x%x \n", nodeNum);
|
LOG_DEBUG("Using nodenum 0x%x ", nodeNum);
|
||||||
|
|
||||||
myNodeInfo.my_node_num = nodeNum;
|
myNodeInfo.my_node_num = nodeNum;
|
||||||
}
|
}
|
||||||
@@ -665,7 +683,6 @@ static const char *prefFileName = "/prefs/db.proto";
|
|||||||
static const char *configFileName = "/prefs/config.proto";
|
static const char *configFileName = "/prefs/config.proto";
|
||||||
static const char *moduleConfigFileName = "/prefs/module.proto";
|
static const char *moduleConfigFileName = "/prefs/module.proto";
|
||||||
static const char *channelFileName = "/prefs/channels.proto";
|
static const char *channelFileName = "/prefs/channels.proto";
|
||||||
static const char *oemConfigFile = "/oem/oem.proto";
|
|
||||||
|
|
||||||
/** Load a protobuf from a file, return LoadFileResult */
|
/** Load a protobuf from a file, return LoadFileResult */
|
||||||
LoadFileResult NodeDB::loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields,
|
LoadFileResult NodeDB::loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields,
|
||||||
@@ -677,23 +694,23 @@ LoadFileResult NodeDB::loadProto(const char *filename, size_t protoSize, size_t
|
|||||||
auto f = FSCom.open(filename, FILE_O_READ);
|
auto f = FSCom.open(filename, FILE_O_READ);
|
||||||
|
|
||||||
if (f) {
|
if (f) {
|
||||||
LOG_INFO("Loading %s\n", filename);
|
LOG_INFO("Loading %s", filename);
|
||||||
pb_istream_t stream = {&readcb, &f, protoSize};
|
pb_istream_t stream = {&readcb, &f, protoSize};
|
||||||
|
|
||||||
memset(dest_struct, 0, objSize);
|
memset(dest_struct, 0, objSize);
|
||||||
if (!pb_decode(&stream, fields, dest_struct)) {
|
if (!pb_decode(&stream, fields, dest_struct)) {
|
||||||
LOG_ERROR("Error: can't decode protobuf %s\n", PB_GET_ERROR(&stream));
|
LOG_ERROR("Error: can't decode protobuf %s", PB_GET_ERROR(&stream));
|
||||||
state = LoadFileResult::DECODE_FAILED;
|
state = LoadFileResult::DECODE_FAILED;
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("Loaded %s successfully\n", filename);
|
LOG_INFO("Loaded %s successfully", filename);
|
||||||
state = LoadFileResult::LOAD_SUCCESS;
|
state = LoadFileResult::LOAD_SUCCESS;
|
||||||
}
|
}
|
||||||
f.close();
|
f.close();
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("Could not open / read %s\n", filename);
|
LOG_ERROR("Could not open / read %s", filename);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
LOG_ERROR("ERROR: Filesystem not implemented\n");
|
LOG_ERROR("ERROR: Filesystem not implemented");
|
||||||
state = LoadFileResult::NO_FILESYSTEM;
|
state = LoadFileResult::NO_FILESYSTEM;
|
||||||
#endif
|
#endif
|
||||||
return state;
|
return state;
|
||||||
@@ -718,11 +735,10 @@ void NodeDB::loadFromDisk()
|
|||||||
// installDefaultDeviceState(); // Our in RAM copy might now be corrupt
|
// installDefaultDeviceState(); // Our in RAM copy might now be corrupt
|
||||||
//} else {
|
//} else {
|
||||||
if (devicestate.version < DEVICESTATE_MIN_VER) {
|
if (devicestate.version < DEVICESTATE_MIN_VER) {
|
||||||
LOG_WARN("Devicestate %d is old, discarding\n", devicestate.version);
|
LOG_WARN("Devicestate %d is old, discarding", devicestate.version);
|
||||||
installDefaultDeviceState();
|
installDefaultDeviceState();
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("Loaded saved devicestate version %d, with nodecount: %d\n", devicestate.version,
|
LOG_INFO("Loaded saved devicestate version %d, with nodecount: %d", devicestate.version, devicestate.node_db_lite.size());
|
||||||
devicestate.node_db_lite.size());
|
|
||||||
meshNodes = &devicestate.node_db_lite;
|
meshNodes = &devicestate.node_db_lite;
|
||||||
numMeshNodes = devicestate.node_db_lite.size();
|
numMeshNodes = devicestate.node_db_lite.size();
|
||||||
}
|
}
|
||||||
@@ -734,10 +750,10 @@ void NodeDB::loadFromDisk()
|
|||||||
installDefaultConfig(); // Our in RAM copy might now be corrupt
|
installDefaultConfig(); // Our in RAM copy might now be corrupt
|
||||||
} else {
|
} else {
|
||||||
if (config.version < DEVICESTATE_MIN_VER) {
|
if (config.version < DEVICESTATE_MIN_VER) {
|
||||||
LOG_WARN("config %d is old, discarding\n", config.version);
|
LOG_WARN("config %d is old, discarding", config.version);
|
||||||
installDefaultConfig(true);
|
installDefaultConfig(true);
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("Loaded saved config version %d\n", config.version);
|
LOG_INFO("Loaded saved config version %d", config.version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -747,10 +763,10 @@ void NodeDB::loadFromDisk()
|
|||||||
installDefaultModuleConfig(); // Our in RAM copy might now be corrupt
|
installDefaultModuleConfig(); // Our in RAM copy might now be corrupt
|
||||||
} else {
|
} else {
|
||||||
if (moduleConfig.version < DEVICESTATE_MIN_VER) {
|
if (moduleConfig.version < DEVICESTATE_MIN_VER) {
|
||||||
LOG_WARN("moduleConfig %d is old, discarding\n", moduleConfig.version);
|
LOG_WARN("moduleConfig %d is old, discarding", moduleConfig.version);
|
||||||
installDefaultModuleConfig();
|
installDefaultModuleConfig();
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("Loaded saved moduleConfig version %d\n", moduleConfig.version);
|
LOG_INFO("Loaded saved moduleConfig version %d", moduleConfig.version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -760,22 +776,16 @@ void NodeDB::loadFromDisk()
|
|||||||
installDefaultChannels(); // Our in RAM copy might now be corrupt
|
installDefaultChannels(); // Our in RAM copy might now be corrupt
|
||||||
} else {
|
} else {
|
||||||
if (channelFile.version < DEVICESTATE_MIN_VER) {
|
if (channelFile.version < DEVICESTATE_MIN_VER) {
|
||||||
LOG_WARN("channelFile %d is old, discarding\n", channelFile.version);
|
LOG_WARN("channelFile %d is old, discarding", channelFile.version);
|
||||||
installDefaultChannels();
|
installDefaultChannels();
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("Loaded saved channelFile version %d\n", channelFile.version);
|
LOG_INFO("Loaded saved channelFile version %d", channelFile.version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state = loadProto(oemConfigFile, meshtastic_OEMStore_size, sizeof(meshtastic_OEMStore), &meshtastic_OEMStore_msg, &oemStore);
|
|
||||||
if (state == LoadFileResult::LOAD_SUCCESS) {
|
|
||||||
LOG_INFO("Loaded OEMStore\n");
|
|
||||||
hasOemStore = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2.4.X - configuration migration to update new default intervals
|
// 2.4.X - configuration migration to update new default intervals
|
||||||
if (moduleConfig.version < 23) {
|
if (moduleConfig.version < 23) {
|
||||||
LOG_DEBUG("ModuleConfig version %d is stale, upgrading to new default intervals\n", moduleConfig.version);
|
LOG_DEBUG("ModuleConfig version %d is stale, upgrading to new default intervals", moduleConfig.version);
|
||||||
moduleConfig.version = DEVICESTATE_CUR_VER;
|
moduleConfig.version = DEVICESTATE_CUR_VER;
|
||||||
if (moduleConfig.telemetry.device_update_interval == 900)
|
if (moduleConfig.telemetry.device_update_interval == 900)
|
||||||
moduleConfig.telemetry.device_update_interval = 0;
|
moduleConfig.telemetry.device_update_interval = 0;
|
||||||
@@ -802,11 +812,11 @@ bool NodeDB::saveProto(const char *filename, size_t protoSize, const pb_msgdesc_
|
|||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
auto f = SafeFile(filename, fullAtomic);
|
auto f = SafeFile(filename, fullAtomic);
|
||||||
|
|
||||||
LOG_INFO("Saving %s\n", filename);
|
LOG_INFO("Saving %s", filename);
|
||||||
pb_ostream_t stream = {&writecb, static_cast<Print *>(&f), protoSize};
|
pb_ostream_t stream = {&writecb, static_cast<Print *>(&f), protoSize};
|
||||||
|
|
||||||
if (!pb_encode(&stream, fields, dest_struct)) {
|
if (!pb_encode(&stream, fields, dest_struct)) {
|
||||||
LOG_ERROR("Error: can't encode protobuf %s\n", PB_GET_ERROR(&stream));
|
LOG_ERROR("Error: can't encode protobuf %s", PB_GET_ERROR(&stream));
|
||||||
} else {
|
} else {
|
||||||
okay = true;
|
okay = true;
|
||||||
}
|
}
|
||||||
@@ -814,10 +824,10 @@ bool NodeDB::saveProto(const char *filename, size_t protoSize, const pb_msgdesc_
|
|||||||
bool writeSucceeded = f.close();
|
bool writeSucceeded = f.close();
|
||||||
|
|
||||||
if (!okay || !writeSucceeded) {
|
if (!okay || !writeSucceeded) {
|
||||||
LOG_ERROR("Can't write prefs!\n");
|
LOG_ERROR("Can't write prefs!");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
LOG_ERROR("ERROR: Filesystem not implemented\n");
|
LOG_ERROR("ERROR: Filesystem not implemented");
|
||||||
#endif
|
#endif
|
||||||
return okay;
|
return okay;
|
||||||
}
|
}
|
||||||
@@ -879,11 +889,6 @@ bool NodeDB::saveToDiskNoRetry(int saveWhat)
|
|||||||
saveProto(moduleConfigFileName, meshtastic_LocalModuleConfig_size, &meshtastic_LocalModuleConfig_msg, &moduleConfig);
|
saveProto(moduleConfigFileName, meshtastic_LocalModuleConfig_size, &meshtastic_LocalModuleConfig_msg, &moduleConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We might need to rewrite the OEM data if we are reformatting the FS
|
|
||||||
if ((saveWhat & SEGMENT_OEM) && hasOemStore) {
|
|
||||||
success &= saveProto(oemConfigFile, meshtastic_OEMStore_size, &meshtastic_OEMStore_msg, &oemStore);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (saveWhat & SEGMENT_CHANNELS) {
|
if (saveWhat & SEGMENT_CHANNELS) {
|
||||||
success &= saveChannelsToDisk();
|
success &= saveChannelsToDisk();
|
||||||
}
|
}
|
||||||
@@ -900,12 +905,10 @@ bool NodeDB::saveToDisk(int saveWhat)
|
|||||||
bool success = saveToDiskNoRetry(saveWhat);
|
bool success = saveToDiskNoRetry(saveWhat);
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
LOG_ERROR("Failed to save to disk, retrying...\n");
|
LOG_ERROR("Failed to save to disk, retrying...");
|
||||||
#ifdef ARCH_NRF52 // @geeksville is not ready yet to say we should do this on other platforms. See bug #4184 discussion
|
#ifdef ARCH_NRF52 // @geeksville is not ready yet to say we should do this on other platforms. See bug #4184 discussion
|
||||||
FSCom.format();
|
FSCom.format();
|
||||||
|
|
||||||
// We need to rewrite the OEM data if we are reformatting the FS
|
|
||||||
saveWhat |= SEGMENT_OEM;
|
|
||||||
#endif
|
#endif
|
||||||
success = saveToDiskNoRetry(saveWhat);
|
success = saveToDiskNoRetry(saveWhat);
|
||||||
|
|
||||||
@@ -978,7 +981,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
|
|||||||
|
|
||||||
if (src == RX_SRC_LOCAL) {
|
if (src == RX_SRC_LOCAL) {
|
||||||
// Local packet, fully authoritative
|
// Local packet, fully authoritative
|
||||||
LOG_INFO("updatePosition LOCAL pos@%x time=%u lat=%d lon=%d alt=%d\n", p.timestamp, p.time, p.latitude_i, p.longitude_i,
|
LOG_INFO("updatePosition LOCAL pos@%x time=%u lat=%d lon=%d alt=%d", p.timestamp, p.time, p.latitude_i, p.longitude_i,
|
||||||
p.altitude);
|
p.altitude);
|
||||||
|
|
||||||
setLocalPosition(p);
|
setLocalPosition(p);
|
||||||
@@ -986,7 +989,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
|
|||||||
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
|
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
|
||||||
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
|
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
|
||||||
// (stop-gap fix for issue #900)
|
// (stop-gap fix for issue #900)
|
||||||
LOG_DEBUG("updatePosition SPECIAL time setting time=%u\n", p.time);
|
LOG_DEBUG("updatePosition SPECIAL time setting time=%u", p.time);
|
||||||
info->position.time = p.time;
|
info->position.time = p.time;
|
||||||
} else {
|
} else {
|
||||||
// Be careful to only update fields that have been set by the REMOTE sender
|
// Be careful to only update fields that have been set by the REMOTE sender
|
||||||
@@ -994,7 +997,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
|
|||||||
// recorded based on the packet rxTime
|
// recorded based on the packet rxTime
|
||||||
//
|
//
|
||||||
// FIXME perhaps handle RX_SRC_USER separately?
|
// FIXME perhaps handle RX_SRC_USER separately?
|
||||||
LOG_INFO("updatePosition REMOTE node=0x%x time=%u lat=%d lon=%d\n", nodeId, p.time, p.latitude_i, p.longitude_i);
|
LOG_INFO("updatePosition REMOTE node=0x%x time=%u lat=%d lon=%d", nodeId, p.time, p.latitude_i, p.longitude_i);
|
||||||
|
|
||||||
// First, back up fields that we want to protect from overwrite
|
// First, back up fields that we want to protect from overwrite
|
||||||
uint32_t tmp_time = info->position.time;
|
uint32_t tmp_time = info->position.time;
|
||||||
@@ -1024,9 +1027,9 @@ void NodeDB::updateTelemetry(uint32_t nodeId, const meshtastic_Telemetry &t, RxS
|
|||||||
|
|
||||||
if (src == RX_SRC_LOCAL) {
|
if (src == RX_SRC_LOCAL) {
|
||||||
// Local packet, fully authoritative
|
// Local packet, fully authoritative
|
||||||
LOG_DEBUG("updateTelemetry LOCAL\n");
|
LOG_DEBUG("updateTelemetry LOCAL");
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("updateTelemetry REMOTE node=0x%x \n", nodeId);
|
LOG_DEBUG("updateTelemetry REMOTE node=0x%x ", nodeId);
|
||||||
}
|
}
|
||||||
info->device_metrics = t.variant.device_metrics;
|
info->device_metrics = t.variant.device_metrics;
|
||||||
info->has_device_metrics = true;
|
info->has_device_metrics = true;
|
||||||
@@ -1043,16 +1046,16 @@ bool NodeDB::updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelInde
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("old user %s/%s, channel=%d\n", info->user.long_name, info->user.short_name, info->channel);
|
LOG_DEBUG("old user %s/%s, channel=%d", info->user.long_name, info->user.short_name, info->channel);
|
||||||
#if !(MESHTASTIC_EXCLUDE_PKI)
|
#if !(MESHTASTIC_EXCLUDE_PKI)
|
||||||
if (p.public_key.size > 0) {
|
if (p.public_key.size > 0) {
|
||||||
printBytes("Incoming Pubkey: ", p.public_key.bytes, 32);
|
printBytes("Incoming Pubkey: ", p.public_key.bytes, 32);
|
||||||
if (info->user.public_key.size > 0) { // if we have a key for this user already, don't overwrite with a new one
|
if (info->user.public_key.size > 0) { // if we have a key for this user already, don't overwrite with a new one
|
||||||
LOG_INFO("Public Key set for node, not updating!\n");
|
LOG_INFO("Public Key set for node, not updating!");
|
||||||
// we copy the key into the incoming packet, to prevent overwrite
|
// we copy the key into the incoming packet, to prevent overwrite
|
||||||
memcpy(p.public_key.bytes, info->user.public_key.bytes, 32);
|
memcpy(p.public_key.bytes, info->user.public_key.bytes, 32);
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("Updating Node Pubkey!\n");
|
LOG_INFO("Updating Node Pubkey!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1067,8 +1070,7 @@ bool NodeDB::updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelInde
|
|||||||
}
|
}
|
||||||
if (nodeId != getNodeNum())
|
if (nodeId != getNodeNum())
|
||||||
info->channel = channelIndex; // Set channel we need to use to reach this node (but don't set our own channel)
|
info->channel = channelIndex; // Set channel we need to use to reach this node (but don't set our own channel)
|
||||||
LOG_DEBUG("updating changed=%d user %s/%s, channel=%d\n", changed, info->user.long_name, info->user.short_name,
|
LOG_DEBUG("updating changed=%d user %s/%s, channel=%d", changed, info->user.long_name, info->user.short_name, info->channel);
|
||||||
info->channel);
|
|
||||||
info->has_user = true;
|
info->has_user = true;
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
@@ -1079,7 +1081,7 @@ bool NodeDB::updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelInde
|
|||||||
// We just changed something about the user, store our DB
|
// We just changed something about the user, store our DB
|
||||||
Throttle::execute(
|
Throttle::execute(
|
||||||
&lastNodeDbSave, ONE_MINUTE_MS, []() { nodeDB->saveToDisk(SEGMENT_DEVICESTATE); },
|
&lastNodeDbSave, ONE_MINUTE_MS, []() { nodeDB->saveToDisk(SEGMENT_DEVICESTATE); },
|
||||||
[]() { LOG_DEBUG("Deferring NodeDB saveToDisk for now, since we saved less than a minute ago\n"); });
|
[]() { LOG_DEBUG("Deferring NodeDB saveToDisk for now"); }); // since we saved less than a minute ago
|
||||||
}
|
}
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
@@ -1090,7 +1092,7 @@ bool NodeDB::updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelInde
|
|||||||
void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
|
void NodeDB::updateFrom(const meshtastic_MeshPacket &mp)
|
||||||
{
|
{
|
||||||
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.from) {
|
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.from) {
|
||||||
LOG_DEBUG("Update DB node 0x%x, rx_time=%u\n", mp.from, mp.rx_time);
|
LOG_DEBUG("Update DB node 0x%x, rx_time=%u", mp.from, mp.rx_time);
|
||||||
|
|
||||||
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(getFrom(&mp));
|
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(getFrom(&mp));
|
||||||
if (!info) {
|
if (!info) {
|
||||||
@@ -1142,7 +1144,7 @@ meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n)
|
|||||||
if ((numMeshNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < MINIMUM_SAFE_FREE_HEAP)) {
|
if ((numMeshNodes >= MAX_NUM_NODES) || (memGet.getFreeHeap() < MINIMUM_SAFE_FREE_HEAP)) {
|
||||||
if (screen)
|
if (screen)
|
||||||
screen->print("Warn: node database full!\nErasing oldest entry\n");
|
screen->print("Warn: node database full!\nErasing oldest entry\n");
|
||||||
LOG_WARN("Node database full with %i nodes and %i bytes free! Erasing oldest entry\n", numMeshNodes,
|
LOG_WARN("Node database full with %i nodes and %i bytes free! Erasing oldest entry", numMeshNodes,
|
||||||
memGet.getFreeHeap());
|
memGet.getFreeHeap());
|
||||||
// look for oldest node and erase it
|
// look for oldest node and erase it
|
||||||
uint32_t oldest = UINT32_MAX;
|
uint32_t oldest = UINT32_MAX;
|
||||||
@@ -1178,7 +1180,7 @@ meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n)
|
|||||||
// everything is missing except the nodenum
|
// everything is missing except the nodenum
|
||||||
memset(lite, 0, sizeof(*lite));
|
memset(lite, 0, sizeof(*lite));
|
||||||
lite->num = n;
|
lite->num = n;
|
||||||
LOG_INFO("Adding node to database with %i nodes and %i bytes free!\n", numMeshNodes, memGet.getFreeHeap());
|
LOG_INFO("Adding node to database with %i nodes and %i bytes free!", numMeshNodes, memGet.getFreeHeap());
|
||||||
}
|
}
|
||||||
|
|
||||||
return lite;
|
return lite;
|
||||||
@@ -1189,11 +1191,12 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
|
|||||||
{
|
{
|
||||||
// Print error to screen and serial port
|
// Print error to screen and serial port
|
||||||
String lcd = String("Critical error ") + code + "!\n";
|
String lcd = String("Critical error ") + code + "!\n";
|
||||||
screen->print(lcd.c_str());
|
if (screen)
|
||||||
|
screen->print(lcd.c_str());
|
||||||
if (filename) {
|
if (filename) {
|
||||||
LOG_ERROR("NOTE! Recording critical error %d at %s:%lu\n", code, filename, address);
|
LOG_ERROR("NOTE! Recording critical error %d at %s:%lu", code, filename, address);
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("NOTE! Recording critical error %d, address=0x%lx\n", code, address);
|
LOG_ERROR("NOTE! Recording critical error %d, address=0x%lx", code, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record error to DB
|
// Record error to DB
|
||||||
@@ -1205,4 +1208,4 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
|
|||||||
LOG_ERROR("A critical failure occurred, portduino is exiting...");
|
LOG_ERROR("A critical failure occurred, portduino is exiting...");
|
||||||
exit(2);
|
exit(2);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ DeviceState versions used to be defined in the .proto file but really only this
|
|||||||
#define SEGMENT_MODULECONFIG 2
|
#define SEGMENT_MODULECONFIG 2
|
||||||
#define SEGMENT_DEVICESTATE 4
|
#define SEGMENT_DEVICESTATE 4
|
||||||
#define SEGMENT_CHANNELS 8
|
#define SEGMENT_CHANNELS 8
|
||||||
#define SEGMENT_OEM 16
|
|
||||||
|
|
||||||
#define DEVICESTATE_CUR_VER 23
|
#define DEVICESTATE_CUR_VER 23
|
||||||
#define DEVICESTATE_MIN_VER 22
|
#define DEVICESTATE_MIN_VER 22
|
||||||
@@ -31,7 +30,6 @@ extern meshtastic_ChannelFile channelFile;
|
|||||||
extern meshtastic_MyNodeInfo &myNodeInfo;
|
extern meshtastic_MyNodeInfo &myNodeInfo;
|
||||||
extern meshtastic_LocalConfig config;
|
extern meshtastic_LocalConfig config;
|
||||||
extern meshtastic_LocalModuleConfig moduleConfig;
|
extern meshtastic_LocalModuleConfig moduleConfig;
|
||||||
extern meshtastic_OEMStore oemStore;
|
|
||||||
extern meshtastic_User &owner;
|
extern meshtastic_User &owner;
|
||||||
extern meshtastic_Position localPosition;
|
extern meshtastic_Position localPosition;
|
||||||
|
|
||||||
@@ -154,12 +152,12 @@ class NodeDB
|
|||||||
void setLocalPosition(meshtastic_Position position, bool timeOnly = false)
|
void setLocalPosition(meshtastic_Position position, bool timeOnly = false)
|
||||||
{
|
{
|
||||||
if (timeOnly) {
|
if (timeOnly) {
|
||||||
LOG_DEBUG("Setting local position time only: time=%u timestamp=%u\n", position.time, position.timestamp);
|
LOG_DEBUG("Setting local position time only: time=%u timestamp=%u", position.time, position.timestamp);
|
||||||
localPosition.time = position.time;
|
localPosition.time = position.time;
|
||||||
localPosition.timestamp = position.timestamp > 0 ? position.timestamp : position.time;
|
localPosition.timestamp = position.timestamp > 0 ? position.timestamp : position.time;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG_DEBUG("Setting local position: lat=%i lon=%i time=%u timestamp=%u\n", position.latitude_i, position.longitude_i,
|
LOG_DEBUG("Setting local position: lat=%i lon=%i time=%u timestamp=%u", position.latitude_i, position.longitude_i,
|
||||||
position.time, position.timestamp);
|
position.time, position.timestamp);
|
||||||
localPosition = position;
|
localPosition = position;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ PacketHistory::PacketHistory()
|
|||||||
bool PacketHistory::wasSeenRecently(const meshtastic_MeshPacket *p, bool withUpdate)
|
bool PacketHistory::wasSeenRecently(const meshtastic_MeshPacket *p, bool withUpdate)
|
||||||
{
|
{
|
||||||
if (p->id == 0) {
|
if (p->id == 0) {
|
||||||
LOG_DEBUG("Ignoring message with zero id\n");
|
LOG_DEBUG("Ignoring message with zero id");
|
||||||
return false; // Not a floodable message ID, so we don't care
|
return false; // Not a floodable message ID, so we don't care
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ bool PacketHistory::wasSeenRecently(const meshtastic_MeshPacket *p, bool withUpd
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (seenRecently) {
|
if (seenRecently) {
|
||||||
LOG_DEBUG("Found existing packet record for fr=0x%x,to=0x%x,id=0x%x\n", p->from, p->to, p->id);
|
LOG_DEBUG("Found existing packet record for fr=0x%x,to=0x%x,id=0x%x", p->from, p->to, p->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (withUpdate) {
|
if (withUpdate) {
|
||||||
@@ -64,7 +64,7 @@ bool PacketHistory::wasSeenRecently(const meshtastic_MeshPacket *p, bool withUpd
|
|||||||
*/
|
*/
|
||||||
void PacketHistory::clearExpiredRecentPackets()
|
void PacketHistory::clearExpiredRecentPackets()
|
||||||
{
|
{
|
||||||
LOG_DEBUG("recentPackets size=%ld\n", recentPackets.size());
|
LOG_DEBUG("recentPackets size=%ld", recentPackets.size());
|
||||||
|
|
||||||
for (auto it = recentPackets.begin(); it != recentPackets.end();) {
|
for (auto it = recentPackets.begin(); it != recentPackets.end();) {
|
||||||
if (!Throttle::isWithinTimespanMs(it->rxTimeMsec, FLOOD_EXPIRE_TIME)) {
|
if (!Throttle::isWithinTimespanMs(it->rxTimeMsec, FLOOD_EXPIRE_TIME)) {
|
||||||
@@ -74,5 +74,5 @@ void PacketHistory::clearExpiredRecentPackets()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("recentPackets size=%ld (after clearing expired packets)\n", recentPackets.size());
|
LOG_DEBUG("recentPackets size=%ld (after clearing expired packets)", recentPackets.size());
|
||||||
}
|
}
|
||||||
@@ -55,16 +55,16 @@ void PhoneAPI::handleStartConfig()
|
|||||||
state = STATE_SEND_MY_INFO;
|
state = STATE_SEND_MY_INFO;
|
||||||
pauseBluetoothLogging = true;
|
pauseBluetoothLogging = true;
|
||||||
filesManifest = getFiles("/", 10);
|
filesManifest = getFiles("/", 10);
|
||||||
LOG_DEBUG("Got %d files in manifest\n", filesManifest.size());
|
LOG_DEBUG("Got %d files in manifest", filesManifest.size());
|
||||||
|
|
||||||
LOG_INFO("Starting API client config\n");
|
LOG_INFO("Starting API client config");
|
||||||
nodeInfoForPhone.num = 0; // Don't keep returning old nodeinfos
|
nodeInfoForPhone.num = 0; // Don't keep returning old nodeinfos
|
||||||
resetReadIndex();
|
resetReadIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhoneAPI::close()
|
void PhoneAPI::close()
|
||||||
{
|
{
|
||||||
LOG_INFO("PhoneAPI::close()\n");
|
LOG_INFO("PhoneAPI::close()");
|
||||||
|
|
||||||
if (state != STATE_SEND_NOTHING) {
|
if (state != STATE_SEND_NOTHING) {
|
||||||
state = STATE_SEND_NOTHING;
|
state = STATE_SEND_NOTHING;
|
||||||
@@ -95,7 +95,7 @@ bool PhoneAPI::checkConnectionTimeout()
|
|||||||
if (isConnected()) {
|
if (isConnected()) {
|
||||||
bool newContact = checkIsConnected();
|
bool newContact = checkIsConnected();
|
||||||
if (!newContact) {
|
if (!newContact) {
|
||||||
LOG_INFO("Lost phone connection\n");
|
LOG_INFO("Lost phone connection");
|
||||||
close();
|
close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -118,41 +118,41 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength)
|
|||||||
return handleToRadioPacket(toRadioScratch.packet);
|
return handleToRadioPacket(toRadioScratch.packet);
|
||||||
case meshtastic_ToRadio_want_config_id_tag:
|
case meshtastic_ToRadio_want_config_id_tag:
|
||||||
config_nonce = toRadioScratch.want_config_id;
|
config_nonce = toRadioScratch.want_config_id;
|
||||||
LOG_INFO("Client wants config, nonce=%u\n", config_nonce);
|
LOG_INFO("Client wants config, nonce=%u", config_nonce);
|
||||||
handleStartConfig();
|
handleStartConfig();
|
||||||
break;
|
break;
|
||||||
case meshtastic_ToRadio_disconnect_tag:
|
case meshtastic_ToRadio_disconnect_tag:
|
||||||
LOG_INFO("Disconnecting from phone\n");
|
LOG_INFO("Disconnecting from phone");
|
||||||
close();
|
close();
|
||||||
break;
|
break;
|
||||||
case meshtastic_ToRadio_xmodemPacket_tag:
|
case meshtastic_ToRadio_xmodemPacket_tag:
|
||||||
LOG_INFO("Got xmodem packet\n");
|
LOG_INFO("Got xmodem packet");
|
||||||
#ifdef FSCom
|
#ifdef FSCom
|
||||||
xModem.handlePacket(toRadioScratch.xmodemPacket);
|
xModem.handlePacket(toRadioScratch.xmodemPacket);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
#if !MESHTASTIC_EXCLUDE_MQTT
|
#if !MESHTASTIC_EXCLUDE_MQTT
|
||||||
case meshtastic_ToRadio_mqttClientProxyMessage_tag:
|
case meshtastic_ToRadio_mqttClientProxyMessage_tag:
|
||||||
LOG_INFO("Got MqttClientProxy message\n");
|
LOG_INFO("Got MqttClientProxy message");
|
||||||
if (mqtt && moduleConfig.mqtt.proxy_to_client_enabled && moduleConfig.mqtt.enabled &&
|
if (mqtt && moduleConfig.mqtt.proxy_to_client_enabled && moduleConfig.mqtt.enabled &&
|
||||||
(channels.anyMqttEnabled() || moduleConfig.mqtt.map_reporting_enabled)) {
|
(channels.anyMqttEnabled() || moduleConfig.mqtt.map_reporting_enabled)) {
|
||||||
mqtt->onClientProxyReceive(toRadioScratch.mqttClientProxyMessage);
|
mqtt->onClientProxyReceive(toRadioScratch.mqttClientProxyMessage);
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN("MqttClientProxy received but proxy is not enabled, no channels have up/downlink, or map reporting "
|
LOG_WARN("MqttClientProxy received but proxy is not enabled, no channels have up/downlink, or map reporting "
|
||||||
"not enabled\n");
|
"not enabled");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case meshtastic_ToRadio_heartbeat_tag:
|
case meshtastic_ToRadio_heartbeat_tag:
|
||||||
LOG_DEBUG("Got client heartbeat\n");
|
LOG_DEBUG("Got client heartbeat");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Ignore nop messages
|
// Ignore nop messages
|
||||||
// LOG_DEBUG("Error: unexpected ToRadio variant\n");
|
// LOG_DEBUG("Error: unexpected ToRadio variant");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("Error: ignoring malformed toradio\n");
|
LOG_ERROR("Error: ignoring malformed toradio");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -179,7 +179,7 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength)
|
|||||||
size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||||
{
|
{
|
||||||
if (!available()) {
|
if (!available()) {
|
||||||
// LOG_DEBUG("getFromRadio=not available\n");
|
// LOG_DEBUG("getFromRadio=not available");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// In case we send a FromRadio packet
|
// In case we send a FromRadio packet
|
||||||
@@ -188,11 +188,11 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
// Advance states as needed
|
// Advance states as needed
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case STATE_SEND_NOTHING:
|
case STATE_SEND_NOTHING:
|
||||||
LOG_INFO("getFromRadio=STATE_SEND_NOTHING\n");
|
LOG_INFO("getFromRadio=STATE_SEND_NOTHING");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_SEND_MY_INFO:
|
case STATE_SEND_MY_INFO:
|
||||||
LOG_INFO("getFromRadio=STATE_SEND_MY_INFO\n");
|
LOG_INFO("getFromRadio=STATE_SEND_MY_INFO");
|
||||||
// If the user has specified they don't want our node to share its location, make sure to tell the phone
|
// If the user has specified they don't want our node to share its location, make sure to tell the phone
|
||||||
// app not to send locations on our behalf.
|
// app not to send locations on our behalf.
|
||||||
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_my_info_tag;
|
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_my_info_tag;
|
||||||
@@ -203,7 +203,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_SEND_OWN_NODEINFO: {
|
case STATE_SEND_OWN_NODEINFO: {
|
||||||
LOG_INFO("getFromRadio=STATE_SEND_OWN_NODEINFO\n");
|
LOG_INFO("getFromRadio=STATE_SEND_OWN_NODEINFO");
|
||||||
auto us = nodeDB->readNextMeshNode(readIndex);
|
auto us = nodeDB->readNextMeshNode(readIndex);
|
||||||
if (us) {
|
if (us) {
|
||||||
nodeInfoForPhone = TypeConversions::ConvertToNodeInfo(us);
|
nodeInfoForPhone = TypeConversions::ConvertToNodeInfo(us);
|
||||||
@@ -219,14 +219,14 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case STATE_SEND_METADATA:
|
case STATE_SEND_METADATA:
|
||||||
LOG_INFO("getFromRadio=STATE_SEND_METADATA\n");
|
LOG_INFO("getFromRadio=STATE_SEND_METADATA");
|
||||||
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_metadata_tag;
|
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_metadata_tag;
|
||||||
fromRadioScratch.metadata = getDeviceMetadata();
|
fromRadioScratch.metadata = getDeviceMetadata();
|
||||||
state = STATE_SEND_CHANNELS;
|
state = STATE_SEND_CHANNELS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_SEND_CHANNELS:
|
case STATE_SEND_CHANNELS:
|
||||||
LOG_INFO("getFromRadio=STATE_SEND_CHANNELS\n");
|
LOG_INFO("getFromRadio=STATE_SEND_CHANNELS");
|
||||||
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_channel_tag;
|
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_channel_tag;
|
||||||
fromRadioScratch.channel = channels.getByIndex(config_state);
|
fromRadioScratch.channel = channels.getByIndex(config_state);
|
||||||
config_state++;
|
config_state++;
|
||||||
@@ -238,7 +238,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_SEND_CONFIG:
|
case STATE_SEND_CONFIG:
|
||||||
LOG_INFO("getFromRadio=STATE_SEND_CONFIG\n");
|
LOG_INFO("getFromRadio=STATE_SEND_CONFIG");
|
||||||
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_tag;
|
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_tag;
|
||||||
switch (config_state) {
|
switch (config_state) {
|
||||||
case meshtastic_Config_device_tag:
|
case meshtastic_Config_device_tag:
|
||||||
@@ -278,7 +278,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
fromRadioScratch.config.which_payload_variant = meshtastic_Config_sessionkey_tag;
|
fromRadioScratch.config.which_payload_variant = meshtastic_Config_sessionkey_tag;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR("Unknown config type %d\n", config_state);
|
LOG_ERROR("Unknown config type %d", config_state);
|
||||||
}
|
}
|
||||||
// NOTE: The phone app needs to know the ls_secs value so it can properly expect sleep behavior.
|
// NOTE: The phone app needs to know the ls_secs value so it can properly expect sleep behavior.
|
||||||
// So even if we internally use 0 to represent 'use default' we still need to send the value we are
|
// So even if we internally use 0 to represent 'use default' we still need to send the value we are
|
||||||
@@ -293,7 +293,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_SEND_MODULECONFIG:
|
case STATE_SEND_MODULECONFIG:
|
||||||
LOG_INFO("getFromRadio=STATE_SEND_MODULECONFIG\n");
|
LOG_INFO("getFromRadio=STATE_SEND_MODULECONFIG");
|
||||||
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_moduleConfig_tag;
|
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_moduleConfig_tag;
|
||||||
switch (config_state) {
|
switch (config_state) {
|
||||||
case meshtastic_ModuleConfig_mqtt_tag:
|
case meshtastic_ModuleConfig_mqtt_tag:
|
||||||
@@ -349,7 +349,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
fromRadioScratch.moduleConfig.payload_variant.paxcounter = moduleConfig.paxcounter;
|
fromRadioScratch.moduleConfig.payload_variant.paxcounter = moduleConfig.paxcounter;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR("Unknown module config type %d\n", config_state);
|
LOG_ERROR("Unknown module config type %d", config_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
config_state++;
|
config_state++;
|
||||||
@@ -362,16 +362,16 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_SEND_OTHER_NODEINFOS: {
|
case STATE_SEND_OTHER_NODEINFOS: {
|
||||||
LOG_INFO("getFromRadio=STATE_SEND_OTHER_NODEINFOS\n");
|
LOG_INFO("getFromRadio=STATE_SEND_OTHER_NODEINFOS");
|
||||||
if (nodeInfoForPhone.num != 0) {
|
if (nodeInfoForPhone.num != 0) {
|
||||||
LOG_INFO("nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s\n", nodeInfoForPhone.num, nodeInfoForPhone.last_heard,
|
LOG_INFO("nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s", nodeInfoForPhone.num, nodeInfoForPhone.last_heard,
|
||||||
nodeInfoForPhone.user.id, nodeInfoForPhone.user.long_name);
|
nodeInfoForPhone.user.id, nodeInfoForPhone.user.long_name);
|
||||||
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_node_info_tag;
|
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_node_info_tag;
|
||||||
fromRadioScratch.node_info = nodeInfoForPhone;
|
fromRadioScratch.node_info = nodeInfoForPhone;
|
||||||
// Stay in current state until done sending nodeinfos
|
// Stay in current state until done sending nodeinfos
|
||||||
nodeInfoForPhone.num = 0; // We just consumed a nodeinfo, will need a new one next time
|
nodeInfoForPhone.num = 0; // We just consumed a nodeinfo, will need a new one next time
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("Done sending nodeinfos\n");
|
LOG_INFO("Done sending nodeinfos");
|
||||||
state = STATE_SEND_FILEMANIFEST;
|
state = STATE_SEND_FILEMANIFEST;
|
||||||
// Go ahead and send that ID right now
|
// Go ahead and send that ID right now
|
||||||
return getFromRadio(buf);
|
return getFromRadio(buf);
|
||||||
@@ -380,7 +380,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case STATE_SEND_FILEMANIFEST: {
|
case STATE_SEND_FILEMANIFEST: {
|
||||||
LOG_INFO("getFromRadio=STATE_SEND_FILEMANIFEST\n");
|
LOG_INFO("getFromRadio=STATE_SEND_FILEMANIFEST");
|
||||||
// last element
|
// last element
|
||||||
if (config_state == filesManifest.size()) { // also handles an empty filesManifest
|
if (config_state == filesManifest.size()) { // also handles an empty filesManifest
|
||||||
config_state = 0;
|
config_state = 0;
|
||||||
@@ -390,7 +390,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
} else {
|
} else {
|
||||||
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_fileInfo_tag;
|
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_fileInfo_tag;
|
||||||
fromRadioScratch.fileInfo = filesManifest.at(config_state);
|
fromRadioScratch.fileInfo = filesManifest.at(config_state);
|
||||||
LOG_DEBUG("File: %s (%d) bytes\n", fromRadioScratch.fileInfo.file_name, fromRadioScratch.fileInfo.size_bytes);
|
LOG_DEBUG("File: %s (%d) bytes", fromRadioScratch.fileInfo.file_name, fromRadioScratch.fileInfo.size_bytes);
|
||||||
config_state++;
|
config_state++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -403,7 +403,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
case STATE_SEND_PACKETS:
|
case STATE_SEND_PACKETS:
|
||||||
pauseBluetoothLogging = false;
|
pauseBluetoothLogging = false;
|
||||||
// Do we have a message from the mesh or packet from the local device?
|
// Do we have a message from the mesh or packet from the local device?
|
||||||
LOG_INFO("getFromRadio=STATE_SEND_PACKETS\n");
|
LOG_INFO("getFromRadio=STATE_SEND_PACKETS");
|
||||||
if (queueStatusPacketForPhone) {
|
if (queueStatusPacketForPhone) {
|
||||||
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_queueStatus_tag;
|
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_queueStatus_tag;
|
||||||
fromRadioScratch.queueStatus = *queueStatusPacketForPhone;
|
fromRadioScratch.queueStatus = *queueStatusPacketForPhone;
|
||||||
@@ -431,7 +431,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_ERROR("getFromRadio unexpected state %d\n", state);
|
LOG_ERROR("getFromRadio unexpected state %d", state);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do we have a message from the mesh?
|
// Do we have a message from the mesh?
|
||||||
@@ -441,17 +441,17 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
|
|
||||||
// VERY IMPORTANT to not print debug messages while writing to fromRadioScratch - because we use that same buffer
|
// VERY IMPORTANT to not print debug messages while writing to fromRadioScratch - because we use that same buffer
|
||||||
// for logging (when we are encapsulating with protobufs)
|
// for logging (when we are encapsulating with protobufs)
|
||||||
// LOG_DEBUG("encoding toPhone packet to phone variant=%d, %d bytes\n", fromRadioScratch.which_payload_variant, numbytes);
|
// LOG_DEBUG("encoding toPhone packet to phone variant=%d, %d bytes", fromRadioScratch.which_payload_variant, numbytes);
|
||||||
return numbytes;
|
return numbytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("no FromRadio packet available\n");
|
LOG_DEBUG("no FromRadio packet available");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhoneAPI::sendConfigComplete()
|
void PhoneAPI::sendConfigComplete()
|
||||||
{
|
{
|
||||||
LOG_INFO("getFromRadio=STATE_SEND_COMPLETE_ID\n");
|
LOG_INFO("getFromRadio=STATE_SEND_COMPLETE_ID");
|
||||||
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_complete_id_tag;
|
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_complete_id_tag;
|
||||||
fromRadioScratch.config_complete_id = config_nonce;
|
fromRadioScratch.config_complete_id = config_nonce;
|
||||||
config_nonce = 0;
|
config_nonce = 0;
|
||||||
@@ -551,11 +551,11 @@ bool PhoneAPI::available()
|
|||||||
if (!packetForPhone)
|
if (!packetForPhone)
|
||||||
packetForPhone = service->getForPhone();
|
packetForPhone = service->getForPhone();
|
||||||
hasPacket = !!packetForPhone;
|
hasPacket = !!packetForPhone;
|
||||||
// LOG_DEBUG("available hasPacket=%d\n", hasPacket);
|
// LOG_DEBUG("available hasPacket=%d", hasPacket);
|
||||||
return hasPacket;
|
return hasPacket;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
LOG_ERROR("PhoneAPI::available unexpected state %d\n", state);
|
LOG_ERROR("PhoneAPI::available unexpected state %d", state);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -597,20 +597,20 @@ bool PhoneAPI::handleToRadioPacket(meshtastic_MeshPacket &p)
|
|||||||
printPacket("PACKET FROM PHONE", &p);
|
printPacket("PACKET FROM PHONE", &p);
|
||||||
|
|
||||||
if (p.id > 0 && wasSeenRecently(p.id)) {
|
if (p.id > 0 && wasSeenRecently(p.id)) {
|
||||||
LOG_DEBUG("Ignoring packet from phone, already seen recently\n");
|
LOG_DEBUG("Ignoring packet from phone, already seen recently");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.decoded.portnum == meshtastic_PortNum_TRACEROUTE_APP && lastPortNumToRadio[p.decoded.portnum] &&
|
if (p.decoded.portnum == meshtastic_PortNum_TRACEROUTE_APP && lastPortNumToRadio[p.decoded.portnum] &&
|
||||||
Throttle::isWithinTimespanMs(lastPortNumToRadio[p.decoded.portnum], THIRTY_SECONDS_MS)) {
|
Throttle::isWithinTimespanMs(lastPortNumToRadio[p.decoded.portnum], THIRTY_SECONDS_MS)) {
|
||||||
LOG_WARN("Rate limiting portnum %d\n", p.decoded.portnum);
|
LOG_WARN("Rate limiting portnum %d", p.decoded.portnum);
|
||||||
sendNotification(meshtastic_LogRecord_Level_WARNING, p.id, "TraceRoute can only be sent once every 30 seconds");
|
sendNotification(meshtastic_LogRecord_Level_WARNING, p.id, "TraceRoute can only be sent once every 30 seconds");
|
||||||
meshtastic_QueueStatus qs = router->getQueueStatus();
|
meshtastic_QueueStatus qs = router->getQueueStatus();
|
||||||
service->sendQueueStatusToPhone(qs, 0, p.id);
|
service->sendQueueStatusToPhone(qs, 0, p.id);
|
||||||
return false;
|
return false;
|
||||||
} else if (p.decoded.portnum == meshtastic_PortNum_POSITION_APP && lastPortNumToRadio[p.decoded.portnum] &&
|
} else if (p.decoded.portnum == meshtastic_PortNum_POSITION_APP && lastPortNumToRadio[p.decoded.portnum] &&
|
||||||
Throttle::isWithinTimespanMs(lastPortNumToRadio[p.decoded.portnum], FIVE_SECONDS_MS)) {
|
Throttle::isWithinTimespanMs(lastPortNumToRadio[p.decoded.portnum], FIVE_SECONDS_MS)) {
|
||||||
LOG_WARN("Rate limiting portnum %d\n", p.decoded.portnum);
|
LOG_WARN("Rate limiting portnum %d", p.decoded.portnum);
|
||||||
meshtastic_QueueStatus qs = router->getQueueStatus();
|
meshtastic_QueueStatus qs = router->getQueueStatus();
|
||||||
service->sendQueueStatusToPhone(qs, 0, p.id);
|
service->sendQueueStatusToPhone(qs, 0, p.id);
|
||||||
// FIXME: Figure out why this continues to happen
|
// FIXME: Figure out why this continues to happen
|
||||||
@@ -629,10 +629,10 @@ int PhoneAPI::onNotify(uint32_t newValue)
|
|||||||
// doesn't call this from idle)
|
// doesn't call this from idle)
|
||||||
|
|
||||||
if (state == STATE_SEND_PACKETS) {
|
if (state == STATE_SEND_PACKETS) {
|
||||||
LOG_INFO("Telling client we have new packets %u\n", newValue);
|
LOG_INFO("Telling client we have new packets %u", newValue);
|
||||||
onNowHasData(newValue);
|
onNowHasData(newValue);
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("(Client not yet interested in packets)\n");
|
LOG_DEBUG("(Client not yet interested in packets)");
|
||||||
}
|
}
|
||||||
|
|
||||||
return timeout ? -1 : 0; // If we timed out, MeshService should stop iterating through observers as we just removed one
|
return timeout ? -1 : 0; // If we timed out, MeshService should stop iterating through observers as we just removed one
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ template <class T> class ProtobufModule : protected SinglePortModule
|
|||||||
|
|
||||||
p->decoded.payload.size =
|
p->decoded.payload.size =
|
||||||
pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), fields, &payload);
|
pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), fields, &payload);
|
||||||
// LOG_DEBUG("did encode\n");
|
// LOG_DEBUG("did encode");
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ template <class T> class ProtobufModule : protected SinglePortModule
|
|||||||
// it would be better to update even if the message was destined to others.
|
// it would be better to update even if the message was destined to others.
|
||||||
|
|
||||||
auto &p = mp.decoded;
|
auto &p = mp.decoded;
|
||||||
LOG_INFO("Received %s from=0x%0x, id=0x%x, portnum=%d, payloadlen=%d\n", name, mp.from, mp.id, p.portnum, p.payload.size);
|
LOG_INFO("Received %s from=0x%0x, id=0x%x, portnum=%d, payloadlen=%d", name, mp.from, mp.id, p.portnum, p.payload.size);
|
||||||
|
|
||||||
T scratch;
|
T scratch;
|
||||||
T *decoded = NULL;
|
T *decoded = NULL;
|
||||||
@@ -91,7 +91,7 @@ template <class T> class ProtobufModule : protected SinglePortModule
|
|||||||
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) {
|
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) {
|
||||||
decoded = &scratch;
|
decoded = &scratch;
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("Error decoding protobuf module!\n");
|
LOG_ERROR("Error decoding protobuf module!");
|
||||||
// if we can't decode it, nobody can process it!
|
// if we can't decode it, nobody can process it!
|
||||||
return ProcessMessage::STOP;
|
return ProcessMessage::STOP;
|
||||||
}
|
}
|
||||||
@@ -112,7 +112,7 @@ template <class T> class ProtobufModule : protected SinglePortModule
|
|||||||
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) {
|
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) {
|
||||||
decoded = &scratch;
|
decoded = &scratch;
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("Error decoding protobuf module!\n");
|
LOG_ERROR("Error decoding protobuf module!");
|
||||||
// if we can't decode it, nobody can process it!
|
// if we can't decode it, nobody can process it!
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||