mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-21 18:22:32 +00:00
Compare commits
298 Commits
v2.0.0.18a
...
v2.0.5.65e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65e8209d51 | ||
|
|
aae5247caa | ||
|
|
2fedb6b774 | ||
|
|
02d18d4831 | ||
|
|
b70c2d088d | ||
|
|
b3c396683e | ||
|
|
f08874dd37 | ||
|
|
648054da9b | ||
|
|
70bf7c490c | ||
|
|
0f4261d02f | ||
|
|
8edbba2180 | ||
|
|
5417671332 | ||
|
|
35d7e11678 | ||
|
|
7a63ba827b | ||
|
|
71c163a8ee | ||
|
|
5d8e661807 | ||
|
|
24244e8474 | ||
|
|
fb4f9bdc40 | ||
|
|
668c46e0cf | ||
|
|
abf8fdb661 | ||
|
|
a28a04b7a0 | ||
|
|
cd9671650b | ||
|
|
00bc762bf1 | ||
|
|
9a065bce03 | ||
|
|
3b2b0bdc97 | ||
|
|
53cd6bdf15 | ||
|
|
6a24ef2263 | ||
|
|
50ba523fb4 | ||
|
|
a33325f90f | ||
|
|
a173b7159a | ||
|
|
9c1c04a8db | ||
|
|
51d0d0d779 | ||
|
|
9cdf627ae3 | ||
|
|
4b9c482384 | ||
|
|
b1ba807ec9 | ||
|
|
c844f153e1 | ||
|
|
4a2b02347f | ||
|
|
e8a05d1874 | ||
|
|
08c4e3fbd6 | ||
|
|
1c5292ac86 | ||
|
|
aa553ea5d8 | ||
|
|
f02c6c49ee | ||
|
|
e54e37a600 | ||
|
|
b95103cab0 | ||
|
|
9b43e49116 | ||
|
|
457538c8f6 | ||
|
|
da48f0704b | ||
|
|
cf8d953bba | ||
|
|
5f2b859e38 | ||
|
|
3187b5abda | ||
|
|
ce16b50d5f | ||
|
|
4295720770 | ||
|
|
4392df0676 | ||
|
|
4ec3b025f0 | ||
|
|
f4704181e9 | ||
|
|
0e04bea39e | ||
|
|
b54044fd00 | ||
|
|
08c69c09c8 | ||
|
|
681ea420c1 | ||
|
|
48ea54748f | ||
|
|
4b7627595a | ||
|
|
6299e5483b | ||
|
|
6118a966a6 | ||
|
|
1fac9ee1f2 | ||
|
|
1e06b2d51e | ||
|
|
f3a6ed9d61 | ||
|
|
f71cbb6f6e | ||
|
|
23ea22c741 | ||
|
|
8be65bb0ab | ||
|
|
57e2e75d24 | ||
|
|
29cd7568f5 | ||
|
|
581076a5a1 | ||
|
|
27401bb9b8 | ||
|
|
10837ce549 | ||
|
|
1dcd411d00 | ||
|
|
0533fd9227 | ||
|
|
5ce7ffc888 | ||
|
|
9e914de995 | ||
|
|
0cc653263e | ||
|
|
d2d2f278cf | ||
|
|
eb34a95ab7 | ||
|
|
eb1f6c0de6 | ||
|
|
8de79e8fb6 | ||
|
|
fe00f0c369 | ||
|
|
f9ee8583b0 | ||
|
|
a4d5f8c717 | ||
|
|
35c50f074b | ||
|
|
dcfa226509 | ||
|
|
a9fde30a58 | ||
|
|
7ceb52103e | ||
|
|
95cc328b5c | ||
|
|
990c0119a7 | ||
|
|
144afee29e | ||
|
|
9665c08b59 | ||
|
|
20ee6a509d | ||
|
|
70d44b8838 | ||
|
|
b260c8b058 | ||
|
|
5991b59ba3 | ||
|
|
bc1fed0fb4 | ||
|
|
b23c364fc0 | ||
|
|
28b428c5a0 | ||
|
|
5bfc58ed64 | ||
|
|
e9a34fca7b | ||
|
|
6ce9734ddd | ||
|
|
d42797ffeb | ||
|
|
b5ebfa9cc3 | ||
|
|
79eff42c3c | ||
|
|
7022807fa3 | ||
|
|
50a301899e | ||
|
|
351db5f6ef | ||
|
|
09fe616ac5 | ||
|
|
2d7ff39ecc | ||
|
|
6e856efd0e | ||
|
|
c3c899bc85 | ||
|
|
916f3cac41 | ||
|
|
9b5f358823 | ||
|
|
22119c272d | ||
|
|
8d4c526d16 | ||
|
|
83aebb7a00 | ||
|
|
33cd5ce6c1 | ||
|
|
f22c2e768e | ||
|
|
3d7dea0606 | ||
|
|
263a421c4a | ||
|
|
401b92bdbb | ||
|
|
6a696af8f6 | ||
|
|
037d6c253b | ||
|
|
b6de79b21a | ||
|
|
52cf530356 | ||
|
|
861ded37db | ||
|
|
7a67388a97 | ||
|
|
4f60fad3f6 | ||
|
|
67efd8172a | ||
|
|
60fdf9fcb2 | ||
|
|
a606e9b7b5 | ||
|
|
65197a8e48 | ||
|
|
43f769ebac | ||
|
|
dff6eeb90e | ||
|
|
61ebdb3367 | ||
|
|
cd95d0865f | ||
|
|
b68a026627 | ||
|
|
68ccebafbf | ||
|
|
3737252d39 | ||
|
|
888a8d05c4 | ||
|
|
f25f902c20 | ||
|
|
a6ea5496b4 | ||
|
|
222424a80c | ||
|
|
74f31d7d68 | ||
|
|
5c59c8d701 | ||
|
|
30a87e3145 | ||
|
|
87f7a60f71 | ||
|
|
f7d8885257 | ||
|
|
77410dc3c3 | ||
|
|
d1acf02ee8 | ||
|
|
de0954f307 | ||
|
|
7da1e5c3e8 | ||
|
|
3c11e87197 | ||
|
|
b004706eff | ||
|
|
2247e71a52 | ||
|
|
8146e84200 | ||
|
|
1213ec2d57 | ||
|
|
30b6cca366 | ||
|
|
4dd140a887 | ||
|
|
87c555bde3 | ||
|
|
c4951b1236 | ||
|
|
0249eb1307 | ||
|
|
f0279e7f92 | ||
|
|
1a50181ace | ||
|
|
d77bc239c1 | ||
|
|
cb283f4c57 | ||
|
|
803858ab0a | ||
|
|
728fc8cbad | ||
|
|
ad05b91f89 | ||
|
|
671e6cde44 | ||
|
|
7a3ad0afba | ||
|
|
d9f1704e36 | ||
|
|
32223a818c | ||
|
|
31e13d4de3 | ||
|
|
815bd6321b | ||
|
|
9f9bd40343 | ||
|
|
2331226bb6 | ||
|
|
80ff118f0f | ||
|
|
d6eeda7136 | ||
|
|
fb92e498f0 | ||
|
|
bf8d8886fd | ||
|
|
a695726f2a | ||
|
|
6dc4172110 | ||
|
|
25a9ee8eb6 | ||
|
|
e122232761 | ||
|
|
b13eaee6b3 | ||
|
|
f0f5107a5d | ||
|
|
0832cc50a8 | ||
|
|
962a3d0c55 | ||
|
|
6934e0bce7 | ||
|
|
3492d64177 | ||
|
|
057109dcac | ||
|
|
12fa08007d | ||
|
|
3562d34555 | ||
|
|
3ca6f645d4 | ||
|
|
6694d31d07 | ||
|
|
d15edf1955 | ||
|
|
e1ce037550 | ||
|
|
f9c376a524 | ||
|
|
26a907444c | ||
|
|
5c214bf4d8 | ||
|
|
5151a5641e | ||
|
|
9513209b70 | ||
|
|
f1416ac9f7 | ||
|
|
631db56a44 | ||
|
|
7b378d36cc | ||
|
|
8ab269e1b3 | ||
|
|
7652253b8d | ||
|
|
9805319940 | ||
|
|
e1e607cba3 | ||
|
|
d74bcd3583 | ||
|
|
9c0483975c | ||
|
|
2fb85dc129 | ||
|
|
d641adc0fc | ||
|
|
a7a020f431 | ||
|
|
a08ac5a47e | ||
|
|
30e5706eaa | ||
|
|
16444c190d | ||
|
|
3d9633a56c | ||
|
|
c0e630522c | ||
|
|
9422d31f55 | ||
|
|
087c7c19af | ||
|
|
3476b35fca | ||
|
|
950d5defda | ||
|
|
c6f060a24f | ||
|
|
1716c4d6f9 | ||
|
|
cda7a60734 | ||
|
|
ed26ab801c | ||
|
|
8874a6e488 | ||
|
|
657ae44b6f | ||
|
|
01381057c5 | ||
|
|
3dc6ed5672 | ||
|
|
764b48e04a | ||
|
|
4c931967c7 | ||
|
|
a547a791ba | ||
|
|
176072801b | ||
|
|
b941c51cf7 | ||
|
|
8a9fd6846e | ||
|
|
a49355133c | ||
|
|
09cdc20440 | ||
|
|
1c0dfe47c8 | ||
|
|
66623693eb | ||
|
|
7c692444e5 | ||
|
|
4ccb4393c5 | ||
|
|
b2e540b114 | ||
|
|
a5d1165c54 | ||
|
|
aa321e06dd | ||
|
|
8b84ac8a6c | ||
|
|
6c07fbfc12 | ||
|
|
04a478a5ad | ||
|
|
acfa186d44 | ||
|
|
3db504c470 | ||
|
|
3e5955be44 | ||
|
|
f1afbf2c0f | ||
|
|
20c559382d | ||
|
|
a3f1c02347 | ||
|
|
f5945d429e | ||
|
|
a3eced53bb | ||
|
|
20686cc66a | ||
|
|
5608fa32f7 | ||
|
|
a0c5defda6 | ||
|
|
25a3a09d5f | ||
|
|
593301146e | ||
|
|
5715ddc361 | ||
|
|
09ddde177c | ||
|
|
ef18b173cd | ||
|
|
ac4e88e0d2 | ||
|
|
3e82cd7dd4 | ||
|
|
b1f2025558 | ||
|
|
57ca5fea81 | ||
|
|
0ce018cf97 | ||
|
|
15a8710e69 | ||
|
|
cae75dcb6d | ||
|
|
d5e2b70b71 | ||
|
|
05b9fd04c6 | ||
|
|
4650989774 | ||
|
|
bcc77efb88 | ||
|
|
39c1637030 | ||
|
|
6d3028f213 | ||
|
|
b2969b2faf | ||
|
|
d07350e4a4 | ||
|
|
12df55c3d4 | ||
|
|
85b541bfd9 | ||
|
|
a9c6d6a80c | ||
|
|
32ad8aaa4e | ||
|
|
3d8e6aead2 | ||
|
|
2747600a3a | ||
|
|
b7ef63230b | ||
|
|
b4d6c8f37b | ||
|
|
6a907348b4 | ||
|
|
760d463bf5 | ||
|
|
8fa71afb72 | ||
|
|
309a3d5396 | ||
|
|
da2279c295 | ||
|
|
13e635b74e |
41
.github/actions/setup-base/action.yml
vendored
Normal file
41
.github/actions/setup-base/action.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
name: 'Setup Build Base Composite Action'
|
||||
description: 'Base build actions for Meshtastic Platform IO steps'
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: "recursive"
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Install cppcheck
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get install -y cppcheck
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v3
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip
|
||||
|
||||
- name: Upgrade python tools
|
||||
shell: bash
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U platformio adafruit-nrfutil
|
||||
pip install -U meshtastic --pre
|
||||
|
||||
- name: Upgrade platformio
|
||||
shell: bash
|
||||
run: |
|
||||
pio upgrade
|
||||
54
.github/workflows/build_esp32.yml
vendored
Normal file
54
.github/workflows/build_esp32.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
name: Build ESP32
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
board:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build-esp32:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Build base
|
||||
id: base
|
||||
uses: ./.github/actions/setup-base
|
||||
|
||||
- name: Pull web ui
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
with:
|
||||
repo: "meshtastic/web"
|
||||
file: "build.tar"
|
||||
target: "build.tar"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Unpack web ui
|
||||
run: |
|
||||
tar -xf build.tar -C data/static
|
||||
rm build.tar
|
||||
|
||||
- name: Build ESP32
|
||||
run: bin/build-esp32.sh ${{ inputs.board }}
|
||||
|
||||
- name: Pull OTA Firmware
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
with:
|
||||
repo: "meshtastic/firmware-ota"
|
||||
file: "firmware.bin"
|
||||
target: "release/bleota.bin"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Get release version string
|
||||
shell: bash
|
||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
|
||||
path: |
|
||||
release/*.bin
|
||||
release/*.elf
|
||||
33
.github/workflows/build_nrf52.yml
vendored
Normal file
33
.github/workflows/build_nrf52.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
name: Build NRF52
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
board:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build-nrf52:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Build base
|
||||
id: base
|
||||
uses: ./.github/actions/setup-base
|
||||
|
||||
- name: Build NRF52
|
||||
run: bin/build-nrf52.sh ${{ inputs.board }}
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
|
||||
path: |
|
||||
release/*.uf2
|
||||
release/*.elf
|
||||
release/*.zip
|
||||
32
.github/workflows/build_rpi2040.yml
vendored
Normal file
32
.github/workflows/build_rpi2040.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
name: Build RPI2040
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
board:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build-rpi2040:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Build base
|
||||
id: base
|
||||
uses: ./.github/actions/setup-base
|
||||
|
||||
- name: Build Raspberry Pi 2040
|
||||
run: ./bin/build-rpi2040.sh ${{ inputs.board }}
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
|
||||
path: |
|
||||
release/*.uf2
|
||||
release/*.elf
|
||||
279
.github/workflows/main_matrix.yml
vendored
279
.github/workflows/main_matrix.yml
vendored
@@ -2,14 +2,14 @@ name: CI
|
||||
on:
|
||||
# # Triggers the workflow on push but only for the master branch
|
||||
push:
|
||||
branches: [master]
|
||||
branches: [master, develop]
|
||||
paths-ignore:
|
||||
- "**.md"
|
||||
- "version.properties"
|
||||
|
||||
# Note: This is different from "pull_request". Need to specify ref when doing checkouts.
|
||||
pull_request_target:
|
||||
branches: [master]
|
||||
branches: [master, develop]
|
||||
paths-ignore:
|
||||
- "**.md"
|
||||
#- "**.yml"
|
||||
@@ -23,60 +23,22 @@ jobs:
|
||||
matrix:
|
||||
include:
|
||||
- board: rak11200
|
||||
- board: tlora-v2
|
||||
- board: tlora-v1
|
||||
- board: tlora_v1_3
|
||||
- board: tlora-v2-1-1.6
|
||||
- board: tbeam
|
||||
- board: heltec-v1
|
||||
- board: heltec-v2.0
|
||||
- board: heltec-v2.1
|
||||
- board: tbeam0.7
|
||||
- board: meshtastic-diy-v1
|
||||
- board: meshtastic-dr-dev
|
||||
- board: rak4631
|
||||
- board: rak4631_eink
|
||||
- board: t-echo
|
||||
- board: nano-g1
|
||||
- board: station-g1
|
||||
- board: m5stack-core
|
||||
- board: m5stack-coreink
|
||||
- board: tbeam-s3-core
|
||||
# - board: pico
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: "recursive"
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Install cppcheck
|
||||
run: |
|
||||
sudo apt-get install -y cppcheck
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v3
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip
|
||||
|
||||
- name: Upgrade python tools and install platformio
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U platformio
|
||||
|
||||
- name: Upgrade platformio
|
||||
run: |
|
||||
pio upgrade
|
||||
- uses: actions/checkout@v3
|
||||
- name: Build base
|
||||
id: base
|
||||
uses: ./.github/actions/setup-base
|
||||
|
||||
- name: Check ${{ matrix.board }}
|
||||
run: bin/check-all.sh ${{ matrix.board }}
|
||||
@@ -95,6 +57,8 @@ jobs:
|
||||
- board: heltec-v1
|
||||
- board: heltec-v2.0
|
||||
- board: heltec-v2.1
|
||||
- board: heltec-v3
|
||||
- board: heltec-wsl-v3
|
||||
- board: tbeam0.7
|
||||
- board: meshtastic-diy-v1
|
||||
- board: meshtastic-dr-dev
|
||||
@@ -103,73 +67,9 @@ jobs:
|
||||
- board: m5stack-core
|
||||
- board: m5stack-coreink
|
||||
- board: tbeam-s3-core
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: "recursive"
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v3
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip
|
||||
|
||||
- name: Upgrade python tools
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U platformio adafruit-nrfutil
|
||||
|
||||
- name: Upgrade platformio
|
||||
run: |
|
||||
pio upgrade
|
||||
|
||||
- name: Pull web ui
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
with:
|
||||
repo: "meshtastic/web"
|
||||
file: "build.tar"
|
||||
target: "build.tar"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Unpack web ui
|
||||
run: |
|
||||
tar -xf build.tar -C data/static
|
||||
rm build.tar
|
||||
|
||||
- name: Build ESP32
|
||||
run: bin/build-esp32.sh ${{ matrix.board }}
|
||||
|
||||
- name: Pull OTA Firmware
|
||||
uses: dsaltares/fetch-gh-release-asset@master
|
||||
with:
|
||||
repo: "meshtastic/Meshtastic-OTA"
|
||||
file: "firmware.bin"
|
||||
target: "release/bleota.bin"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip
|
||||
path: |
|
||||
release/*.bin
|
||||
release/*.elf
|
||||
retention-days: 90
|
||||
uses: ./.github/workflows/build_esp32.yml
|
||||
with:
|
||||
board: ${{ matrix.board }}
|
||||
|
||||
build-nrf52:
|
||||
strategy:
|
||||
@@ -181,53 +81,10 @@ jobs:
|
||||
- board: rak4631_eink
|
||||
- board: t-echo
|
||||
- board: pca10059_diy_eink
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: "recursive"
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v3
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip
|
||||
|
||||
- name: Upgrade python tools
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U platformio adafruit-nrfutil
|
||||
|
||||
- name: Upgrade platformio
|
||||
run: |
|
||||
pio upgrade
|
||||
|
||||
- name: Build NRF52
|
||||
run: bin/build-nrf52.sh ${{ matrix.board }}
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip
|
||||
path: |
|
||||
release/*.uf2
|
||||
release/*.elf
|
||||
release/*.zip
|
||||
retention-days: 90
|
||||
- board: feather_diy
|
||||
uses: ./.github/workflows/build_nrf52.yml
|
||||
with:
|
||||
board: ${{ matrix.board }}
|
||||
|
||||
build-rpi2040:
|
||||
strategy:
|
||||
@@ -236,84 +93,17 @@ jobs:
|
||||
matrix:
|
||||
include:
|
||||
- board: pico
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: "recursive"
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v3
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip
|
||||
|
||||
- name: Upgrade python tools
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U platformio adafruit-nrfutil
|
||||
|
||||
- name: Upgrade platformio
|
||||
run: |
|
||||
pio upgrade
|
||||
|
||||
- name: Build Raspberry Pi 2040
|
||||
run: ./bin/build-rpi2040.sh ${{ matrix.board }}
|
||||
|
||||
- name: Get release version string
|
||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||
id: version
|
||||
|
||||
- name: Store binaries as an artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: firmware-${{ matrix.board }}-${{ steps.version.outputs.version }}.zip
|
||||
path: |
|
||||
release/*.uf2
|
||||
release/*.elf
|
||||
retention-days: 90
|
||||
uses: ./.github/workflows/build_rpi2040.yml
|
||||
with:
|
||||
board: ${{ matrix.board }}
|
||||
|
||||
build-native:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: "recursive"
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Cache python libs
|
||||
uses: actions/cache@v3
|
||||
id: cache-pip # needed in if test
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip
|
||||
|
||||
- name: Upgrade python tools
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -U platformio adafruit-nrfutil
|
||||
pip install -U meshtastic --pre
|
||||
|
||||
- name: Upgrade platformio
|
||||
run: |
|
||||
pio upgrade
|
||||
- uses: actions/checkout@v3
|
||||
- name: Build base
|
||||
id: base
|
||||
uses: ./.github/actions/setup-base
|
||||
|
||||
# We now run integration test before other build steps (to quickly see runtime failures)
|
||||
- name: Build for native
|
||||
@@ -340,8 +130,27 @@ jobs:
|
||||
release/meshtasticd_linux_amd64
|
||||
release/device-*.sh
|
||||
release/device-*.bat
|
||||
retention-days: 90
|
||||
|
||||
- name: Docker login
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: meshtastic
|
||||
password: ${{ secrets.DOCKER_TOKEN }}
|
||||
|
||||
- name: Docker setup
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Docker build and push
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
push: true
|
||||
tags: meshtastic/device-simulator:latest
|
||||
|
||||
after-checks:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [check]
|
||||
@@ -408,7 +217,7 @@ jobs:
|
||||
with:
|
||||
name: debug-elfs-${{ steps.version.outputs.version }}.zip
|
||||
path: ./*.elf
|
||||
retention-days: 90
|
||||
retention-days: 30
|
||||
|
||||
- name: Create request artifacts
|
||||
if: ${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request' }}
|
||||
@@ -470,7 +279,7 @@ jobs:
|
||||
with:
|
||||
draft: true
|
||||
prerelease: true
|
||||
release_name: Meshtastic Device ${{ steps.version.outputs.version }} Alpha
|
||||
release_name: Meshtastic Firmware ${{ steps.version.outputs.version }}
|
||||
tag_name: v${{ steps.version.outputs.version }}
|
||||
body: |
|
||||
Autogenerated by github action, developer should edit as required before publishing...
|
||||
|
||||
40
.github/workflows/sec_sast_flawfinder.yml
vendored
Normal file
40
.github/workflows/sec_sast_flawfinder.yml
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
name: Flawfinder Scan
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master, develop]
|
||||
paths-ignore:
|
||||
- "**.md"
|
||||
- "version.properties"
|
||||
|
||||
jobs:
|
||||
flawfinder:
|
||||
runs-on: ubuntu-latest
|
||||
name: Flawfinder
|
||||
|
||||
steps:
|
||||
# step 1
|
||||
- name: clone application source code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# step 2
|
||||
- name: flawfinder_scan
|
||||
uses: david-a-wheeler/flawfinder@2.0.19
|
||||
with:
|
||||
arguments: '--sarif ./'
|
||||
output: 'flawfinder_report.sarif'
|
||||
|
||||
# step 3
|
||||
- name: save report as pipeline artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: flawfinder_report.sarif
|
||||
path: flawfinder_report.sarif
|
||||
|
||||
# step 4
|
||||
- name: publish code scanning alerts
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
sarif_file: flawfinder_report.sarif
|
||||
category: flawfinder
|
||||
44
.github/workflows/sec_sast_semgrep_cron.yml
vendored
Normal file
44
.github/workflows/sec_sast_semgrep_cron.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
name: Semgrep Full Scan
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
branches:
|
||||
- master
|
||||
schedule:
|
||||
- cron: '0 1 * * 6'
|
||||
|
||||
jobs:
|
||||
|
||||
semgrep-full:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: returntocorp/semgrep
|
||||
|
||||
steps:
|
||||
|
||||
# step 1
|
||||
- name: clone application source code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# step 2
|
||||
- name: full scan
|
||||
run: |
|
||||
semgrep \
|
||||
--sarif --output report.sarif \
|
||||
--metrics=off \
|
||||
--config="p/default"
|
||||
|
||||
# step 3
|
||||
- name: save report as pipeline artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: report.sarif
|
||||
path: report.sarif
|
||||
|
||||
# step 4
|
||||
- name: publish code scanning alerts
|
||||
uses: github/codeql-action/upload-sarif@v2
|
||||
with:
|
||||
sarif_file: report.sarif
|
||||
category: semgrep
|
||||
28
.github/workflows/sec_sast_semgrep_pull.yml
vendored
Normal file
28
.github/workflows/sec_sast_semgrep_pull.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
name: Semgrep Differential Scan
|
||||
on:
|
||||
pull_request
|
||||
|
||||
jobs:
|
||||
|
||||
semgrep-diff:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: returntocorp/semgrep
|
||||
|
||||
steps:
|
||||
|
||||
# step 1
|
||||
- name: clone application source code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# step 2
|
||||
- name: differential scan
|
||||
run: |
|
||||
semgrep scan \
|
||||
--error \
|
||||
--metrics=off \
|
||||
--baseline-commit ${{ github.event.pull_request.base.sha }} \
|
||||
--config="p/default"
|
||||
1
.gitmodules
vendored
1
.gitmodules
vendored
@@ -1,3 +1,4 @@
|
||||
[submodule "protobufs"]
|
||||
path = protobufs
|
||||
url = https://github.com/meshtastic/protobufs.git
|
||||
branch = develop
|
||||
|
||||
2
.semgrepignore
Normal file
2
.semgrepignore
Normal file
@@ -0,0 +1,2 @@
|
||||
.github/workflows/main_matrix.yml
|
||||
src/mesh/compression/unishox2.c
|
||||
41
Dockerfile
Normal file
41
Dockerfile
Normal file
@@ -0,0 +1,41 @@
|
||||
FROM debian:bullseye-slim AS builder
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV TZ=Etc/UTC
|
||||
|
||||
# http://bugs.python.org/issue19846
|
||||
# > At the moment, setting "LANG=C" on a Linux system *fundamentally breaks Python 3*, and that's not OK.
|
||||
ENV LANG C.UTF-8
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
|
||||
# Install build deps
|
||||
USER root
|
||||
RUN apt-get update && \
|
||||
apt-get -y install wget python3 g++ zip python3-venv git vim ca-certificates
|
||||
|
||||
# create a non-priveleged user & group
|
||||
RUN groupadd -g 1000 mesh && useradd -ml -u 1000 -g 1000 mesh
|
||||
|
||||
USER mesh
|
||||
RUN wget https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py -qO /tmp/get-platformio.py && \
|
||||
chmod +x /tmp/get-platformio.py && \
|
||||
python3 /tmp/get-platformio.py && \
|
||||
git clone https://github.com/meshtastic/firmware --recurse-submodules /tmp/firmware && \
|
||||
cd /tmp/firmware && \
|
||||
chmod +x /tmp/firmware/bin/build-native.sh && \
|
||||
source ~/.platformio/penv/bin/activate && \
|
||||
./bin/build-native.sh
|
||||
|
||||
FROM frolvlad/alpine-glibc
|
||||
|
||||
RUN apk --update add --no-cache g++ shadow && \
|
||||
groupadd -g 1000 mesh && useradd -ml -u 1000 -g 1000 mesh
|
||||
|
||||
COPY --from=builder /tmp/firmware/release/meshtasticd_linux_amd64 /home/mesh/
|
||||
|
||||
USER mesh
|
||||
WORKDIR /home/mesh
|
||||
CMD sh -cx "./meshtasticd_linux_amd64 --hwid '$RANDOM'"
|
||||
|
||||
HEALTHCHECK NONE
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
This repository contains the device firmware for the Meshtastic project.
|
||||
|
||||
**[Building Instructions](https://meshtastic.org/docs/developers/Firmware/build)**
|
||||
**[Building Instructions](https://meshtastic.org/docs/development/firmware/build)**
|
||||
**[Flashing Instructions](https://meshtastic.org/docs/getting-started/flashing-firmware/)**
|
||||
|
||||
## Stats
|
||||
|
||||
@@ -31,7 +31,7 @@ lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
${networking_base.lib_deps}
|
||||
${environmental_base.lib_deps}
|
||||
https://github.com/meshtastic/esp32_https_server.git#657509856ce97e9dddeffb89a559f544faefd5cd
|
||||
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
|
||||
h2zero/NimBLE-Arduino@^1.4.0
|
||||
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ lib_deps =
|
||||
${arduino_base.lib_deps}
|
||||
${networking_base.lib_deps}
|
||||
${environmental_base.lib_deps}
|
||||
https://github.com/meshtastic/esp32_https_server.git#657509856ce97e9dddeffb89a559f544faefd5cd
|
||||
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
|
||||
h2zero/NimBLE-Arduino@^1.4.0
|
||||
https://github.com/lewisxhe/XPowersLib.git#84b7373faea3118b6c37954d52f98b8a337148d6
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
|
||||
[portduino_base]
|
||||
platform = https://github.com/meshtastic/platform-native.git#develop
|
||||
framework = arduino
|
||||
build_src_filter =
|
||||
${env.build_src_filter}
|
||||
-<platform/esp32/>
|
||||
@@ -16,5 +18,6 @@ lib_deps =
|
||||
${env.lib_deps}
|
||||
${networking_base.lib_deps}
|
||||
rweather/Crypto@^0.4.0
|
||||
https://github.com/meshtastic/RadioLib.git#5582ac30578ff3f53f20630a00b2a8a4b8f92c74
|
||||
; jgromes/RadioLib@5.4.1
|
||||
https://github.com/jgromes/RadioLib.git#63208f1e89d4dac6eedaafbe234bf90f1fd5402b ; 5.4.1 with some fixes, remove when 5.4.2 is released
|
||||
build_flags = ${arduino_base.build_flags} -Isrc/platform/portduino
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
VERSION=`bin/buildinfo.py long`
|
||||
SHORT_VERSION=`bin/buildinfo.py short`
|
||||
|
||||
BOARDS_ESP32="rak11200 tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1 nano-g1 station-g1 m5stack-core m5stack-coreink"
|
||||
#BOARDS_ESP32=tbeam
|
||||
|
||||
# FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine
|
||||
BOARDS_NRF52="rak4631 rak4631_eink t-echo pca10059_diy_eink"
|
||||
#BOARDS_NRF52=""
|
||||
|
||||
OUTDIR=release/latest
|
||||
|
||||
# We keep all old builds (and their map files in the archive dir)
|
||||
ARCHIVEDIR=release/archive
|
||||
|
||||
rm -f $OUTDIR/firmware*
|
||||
|
||||
mkdir -p $OUTDIR/bins $ARCHIVEDIR
|
||||
rm -r $OUTDIR/bins/* || true
|
||||
mkdir -p $OUTDIR/bins/universal $OUTDIR/elfs/universal
|
||||
|
||||
# build the named environment and copy the bins to the release directory
|
||||
function do_build() {
|
||||
BOARD=$1
|
||||
isNrf=$3
|
||||
|
||||
echo "Building for $BOARD ($isNrf) with $PLATFORMIO_BUILD_FLAGS"
|
||||
rm -f .pio/build/$BOARD/firmware.*
|
||||
|
||||
# The shell vars the build tool expects to find
|
||||
export APP_VERSION=$VERSION
|
||||
|
||||
basename=universal/firmware-$BOARD-$VERSION
|
||||
|
||||
pio run --environment $BOARD # -v
|
||||
SRCELF=.pio/build/$BOARD/firmware.elf
|
||||
cp $SRCELF $OUTDIR/elfs/$basename.elf
|
||||
|
||||
if [ "$isNrf" = "false" ]
|
||||
then
|
||||
echo "Copying ESP32 bin file"
|
||||
SRCBIN=.pio/build/$BOARD/firmware.bin
|
||||
cp $SRCBIN $OUTDIR/bins/$basename.bin
|
||||
else
|
||||
echo "Generating NRF52 uf2 file"
|
||||
SRCHEX=.pio/build/$BOARD/firmware.hex
|
||||
bin/uf2conv.py $SRCHEX -c -o $OUTDIR/bins/$basename.uf2 -f 0xADA52840
|
||||
fi
|
||||
}
|
||||
|
||||
function do_boards() {
|
||||
declare boards=$1
|
||||
declare isNrf=$2
|
||||
for board in $boards; do
|
||||
# Build universal
|
||||
echo "about to build $board $isNrf"
|
||||
do_build $board "" "$isNrf"
|
||||
done
|
||||
}
|
||||
|
||||
# Make sure our submodules are current
|
||||
git submodule update
|
||||
|
||||
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
||||
platformio lib update
|
||||
|
||||
do_boards "$BOARDS_ESP32" "false"
|
||||
do_boards "$BOARDS_NRF52" "true"
|
||||
|
||||
pio run --environment native
|
||||
cp .pio/build/native/program $OUTDIR/bins/universal/meshtasticd_linux_amd64
|
||||
|
||||
echo "Building Filesystem for ESP32 targets"
|
||||
pio run --environment tbeam -t buildfs
|
||||
cp .pio/build/tbeam/spiffs.bin $OUTDIR/bins/universal/littlefs-$VERSION.bin
|
||||
|
||||
# keep the bins in archive also
|
||||
cp $OUTDIR/bins/universal/littlefs* $OUTDIR/bins/universal/firmware* $OUTDIR/elfs/universal/firmware* $ARCHIVEDIR
|
||||
|
||||
echo Updating android bins $OUTDIR/forandroid
|
||||
rm -rf $OUTDIR/forandroid
|
||||
mkdir -p $OUTDIR/forandroid
|
||||
cp -a $OUTDIR/bins/universal/*.bin $OUTDIR/forandroid/
|
||||
|
||||
cat >$OUTDIR/curfirmwareversion.xml <<XML
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- This file is kept in source control because it reflects the last stable
|
||||
release. It is used by the android app for forcing software updates. Do not edit.
|
||||
Generated by bin/buildall.sh -->
|
||||
|
||||
<resources>
|
||||
<string name="cur_firmware_version" translatable="false">$VERSION</string>
|
||||
<string name="short_firmware_version" translatable="false">$SHORT_VERSION</string>
|
||||
</resources>
|
||||
XML
|
||||
|
||||
echo Generating $ARCHIVEDIR/firmware-$VERSION.zip
|
||||
rm -f $ARCHIVEDIR/firmware-$VERSION.zip
|
||||
zip --junk-paths $ARCHIVEDIR/firmware-$VERSION.zip $ARCHIVEDIR/littlefs-$VERSION.bin $OUTDIR/bins/universal/firmware-*-$VERSION.* $OUTDIR/bins/universal/meshtasticd* images/system-info.bin bin/device-install.* bin/device-update.*
|
||||
echo Generating $ARCHIVEDIR/elfs-$VERSION.zip
|
||||
rm -f $ARCHIVEDIR/elfs-$VERSION.zip
|
||||
zip --junk-paths $ARCHIVEDIR/elfs-$VERSION.zip $OUTDIR/elfs/universal/firmware-*-$VERSION.*
|
||||
|
||||
echo BUILT ALL
|
||||
@@ -10,11 +10,8 @@ OUTDIR=release/
|
||||
rm -f $OUTDIR/firmware*
|
||||
rm -r $OUTDIR/* || true
|
||||
|
||||
# Make sure our submodules are current
|
||||
git submodule update
|
||||
|
||||
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
||||
platformio lib update
|
||||
platformio pkg update
|
||||
|
||||
echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS"
|
||||
rm -f .pio/build/$1/firmware.*
|
||||
|
||||
@@ -12,11 +12,8 @@ rm -f $OUTDIR/firmware*
|
||||
mkdir -p $OUTDIR/
|
||||
rm -r $OUTDIR/* || true
|
||||
|
||||
# Make sure our submodules are current
|
||||
git submodule update
|
||||
|
||||
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
||||
platformio lib update
|
||||
platformio pkg update
|
||||
|
||||
pio run --environment native
|
||||
cp .pio/build/native/program $OUTDIR/meshtasticd_linux_amd64
|
||||
|
||||
@@ -10,11 +10,8 @@ OUTDIR=release/
|
||||
rm -f $OUTDIR/firmware*
|
||||
rm -r $OUTDIR/* || true
|
||||
|
||||
# Make sure our submodules are current
|
||||
git submodule update
|
||||
|
||||
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
||||
platformio lib update
|
||||
platformio pkg update
|
||||
|
||||
echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS"
|
||||
rm -f .pio/build/$1/firmware.*
|
||||
|
||||
@@ -10,11 +10,8 @@ OUTDIR=release/
|
||||
rm -f $OUTDIR/firmware*
|
||||
rm -r $OUTDIR/* || true
|
||||
|
||||
# Make sure our submodules are current
|
||||
git submodule update
|
||||
|
||||
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
||||
platformio lib update
|
||||
platformio pkg update
|
||||
|
||||
echo "Building for $1 with $PLATFORMIO_BUILD_FLAGS"
|
||||
rm -f .pio/build/$1/firmware.*
|
||||
|
||||
13
docker-compose.yml
Normal file
13
docker-compose.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
version: "3.7"
|
||||
|
||||
services:
|
||||
meshtastic-node:
|
||||
build: .
|
||||
deploy:
|
||||
mode: replicated
|
||||
replicas: 4
|
||||
networks:
|
||||
- mesh
|
||||
|
||||
networks:
|
||||
mesh:
|
||||
@@ -37,12 +37,24 @@ extra_scripts = bin/platformio-custom.py
|
||||
; note: TINYGPS_OPTION_NO_CUSTOM_FIELDS is VERY important. We don't use custom fields and somewhere in that pile
|
||||
; of code is a heap corruption bug!
|
||||
; FIXME: fix lib/BluetoothOTA dependency back on src/ so we can remove -Isrc
|
||||
; The Radiolib stuff will speed up building considerably. Exclud all the stuff we dont need.
|
||||
build_flags = -Wno-missing-field-initializers
|
||||
-Wno-format
|
||||
-Isrc -Isrc/mesh -Isrc/gps -Isrc/buzz -Wl,-Map,.pio/build/output.map
|
||||
-DUSE_THREAD_NAMES
|
||||
-DTINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||
; -DTINYGPS_OPTION_NO_CUSTOM_FIELDS // this should work now...
|
||||
-DPB_ENABLE_MALLOC=1
|
||||
-DRADIOLIB_EXCLUDE_CC1101
|
||||
-DRADIOLIB_EXCLUDE_NRF24
|
||||
-DRADIOLIB_EXCLUDE_RF69
|
||||
-DRADIOLIB_EXCLUDE_SX1231
|
||||
-DRADIOLIB_EXCLUDE_SI443X
|
||||
-DRADIOLIB_EXCLUDE_RFM2X
|
||||
-DRADIOLIB_EXCLUDE_AFSK
|
||||
-DRADIOLIB_EXCLUDE_HELLSCHREIBER
|
||||
-DRADIOLIB_EXCLUDE_MORSE
|
||||
-DRADIOLIB_EXCLUDE_RTTY
|
||||
-DRADIOLIB_EXCLUDE_SSTV
|
||||
|
||||
monitor_speed = 115200
|
||||
|
||||
@@ -50,7 +62,7 @@ lib_deps =
|
||||
https://github.com/meshtastic/esp8266-oled-ssd1306.git#53580644255b48ebb7a737343c6b4e71c7e11cf2 ; ESP8266_SSD1306
|
||||
mathertel/OneButton@^2.0.3 ; OneButton library for non-blocking button debounce
|
||||
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
||||
https://github.com/meshtastic/TinyGPSPlus.git#2f0d0528d737000043e949f4c3bdfb623cf0b902
|
||||
https://github.com/meshtastic/TinyGPSPlus.git#127ad674ef85f0201cb68a065879653ed94792c4
|
||||
https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
|
||||
nanopb/Nanopb@^0.4.6
|
||||
erriez/ErriezCRC32@^1.0.1
|
||||
@@ -59,8 +71,8 @@ lib_deps =
|
||||
check_tool = cppcheck
|
||||
check_skip_packages = yes
|
||||
check_flags =
|
||||
--common-flag
|
||||
cppcheck: --enable=--inline-suppr
|
||||
-DAPP_VERSION=1.0.0
|
||||
--suppressions-list=suppressions.txt
|
||||
|
||||
; Common settings for conventional (non Portduino) Arduino targets
|
||||
[arduino_base]
|
||||
@@ -69,6 +81,7 @@ lib_deps =
|
||||
${env.lib_deps}
|
||||
; Portduino is using meshtastic fork for now
|
||||
jgromes/RadioLib@5.4.1
|
||||
mprograms/QMC5883LCompass@^1.1.1
|
||||
https://github.com/meshtastic/SparkFun_ATECCX08a_Arduino_Library.git#52b5282639d08a8cbd4b748363089eed6102dc76
|
||||
|
||||
build_flags = ${env.build_flags} -Os
|
||||
|
||||
Submodule protobufs updated: ed9f2499d6...24874086e3
@@ -1,6 +1,18 @@
|
||||
#include "configuration.h"
|
||||
#include "FSCommon.h"
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
#include <SPI.h>
|
||||
#include <SD.h>
|
||||
|
||||
|
||||
#ifdef SDCARD_USE_SPI1
|
||||
SPIClass SPI1(HSPI);
|
||||
#define SDHandler SPI1
|
||||
#endif
|
||||
|
||||
|
||||
#endif //HAS_SDCARD
|
||||
|
||||
bool copyFile(const char* from, const char* to)
|
||||
{
|
||||
@@ -169,3 +181,39 @@ void fsInit()
|
||||
listDir("/", 10);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void setupSDCard()
|
||||
{
|
||||
#ifdef HAS_SDCARD
|
||||
SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
|
||||
|
||||
if (!SD.begin(SDCARD_CS, SDHandler)) {
|
||||
DEBUG_MSG("No SD_MMC card detected\n");
|
||||
return ;
|
||||
}
|
||||
uint8_t cardType = SD.cardType();
|
||||
if (cardType == CARD_NONE) {
|
||||
DEBUG_MSG("No SD_MMC card attached\n");
|
||||
return ;
|
||||
}
|
||||
DEBUG_MSG("SD_MMC Card Type: ");
|
||||
if (cardType == CARD_MMC) {
|
||||
DEBUG_MSG("MMC\n");
|
||||
} else if (cardType == CARD_SD) {
|
||||
DEBUG_MSG("SDSC\n");
|
||||
} else if (cardType == CARD_SDHC) {
|
||||
DEBUG_MSG("SDHC\n");
|
||||
} else {
|
||||
DEBUG_MSG("UNKNOWN\n");
|
||||
}
|
||||
|
||||
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
|
||||
DEBUG_MSG("SD Card Size: %lluMB\n", cardSize);
|
||||
DEBUG_MSG("Total space: %llu MB\n", SD.totalBytes() / (1024 * 1024));
|
||||
DEBUG_MSG("Used space: %llu MB\n", SD.usedBytes() / (1024 * 1024));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -44,3 +44,4 @@ bool copyFile(const char* from, const char* to);
|
||||
bool renameFile(const char* pathFrom, const char* pathTo);
|
||||
void listDir(const char * dirname, uint8_t levels, boolean del);
|
||||
void rmDir(const char * dirname);
|
||||
void setupSDCard();
|
||||
@@ -25,22 +25,6 @@ class GPSStatus : public Status
|
||||
public:
|
||||
GPSStatus() { statusType = STATUS_TYPE_GPS; }
|
||||
|
||||
// // proposed for deprecation
|
||||
// GPSStatus(bool hasLock, bool isConnected, int32_t latitude, int32_t longitude, int32_t altitude, uint32_t dop,
|
||||
// uint32_t heading, uint32_t numSatellites)
|
||||
// : Status()
|
||||
// {
|
||||
// this->hasLock = hasLock;
|
||||
// this->isConnected = isConnected;
|
||||
|
||||
// this->p.latitude_i = latitude;
|
||||
// this->p.longitude_i = longitude;
|
||||
// this->p.altitude = altitude;
|
||||
// this->p.PDOP = dop;
|
||||
// this->p.ground_track = heading;
|
||||
// this->p.sats_in_view = numSatellites;
|
||||
// }
|
||||
|
||||
// preferred method
|
||||
GPSStatus(bool hasLock, bool isConnected, const Position &pos) : Status()
|
||||
{
|
||||
|
||||
@@ -110,6 +110,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define INA_ADDR_ALTERNATE 0x41
|
||||
#define QMC6310_ADDR 0x1C
|
||||
#define QMI8658_ADDR 0x6B
|
||||
#define QMC5883L_ADDR 0x1E
|
||||
#define SHTC3_ADDR 0x70
|
||||
#define LPS22HB_ADDR 0x5C
|
||||
#define LPS22HB_ADDR_ALT 0x5D
|
||||
|
||||
@@ -90,7 +90,7 @@ uint8_t oled_probe(byte addr)
|
||||
return o_probe;
|
||||
}
|
||||
|
||||
void scanI2Cdevice(void)
|
||||
void scanI2Cdevice()
|
||||
{
|
||||
byte err, addr;
|
||||
uint16_t registerValue = 0x00;
|
||||
@@ -106,16 +106,16 @@ void scanI2Cdevice(void)
|
||||
if (addr == SSD1306_ADDRESS) {
|
||||
screen_found = addr;
|
||||
screen_model = oled_probe(addr);
|
||||
if (screen_model == 1){
|
||||
if (screen_model == 1) {
|
||||
DEBUG_MSG("ssd1306 display found\n");
|
||||
} else if (screen_model == 2){
|
||||
} else if (screen_model == 2) {
|
||||
DEBUG_MSG("sh1106 display found\n");
|
||||
} else {
|
||||
DEBUG_MSG("unknown display found\n");
|
||||
}
|
||||
}
|
||||
#ifndef ARCH_PORTDUINO
|
||||
if (addr == ATECC608B_ADDR){
|
||||
if (addr == ATECC608B_ADDR) {
|
||||
keystore_found = addr;
|
||||
if (atecc.begin(keystore_found) == true) {
|
||||
DEBUG_MSG("ATECC608B initialized\n");
|
||||
@@ -163,50 +163,56 @@ void scanI2Cdevice(void)
|
||||
DEBUG_MSG("axp192/axp2101 PMU found\n");
|
||||
}
|
||||
#endif
|
||||
if (addr == BME_ADDR || addr == BME_ADDR_ALTERNATE) {
|
||||
registerValue = getRegisterValue(addr, 0xD0, 1); // GET_ID
|
||||
if (registerValue == 0x61) {
|
||||
DEBUG_MSG("BME-680 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_BME680] = addr;
|
||||
} else if (registerValue == 0x60) {
|
||||
DEBUG_MSG("BME-280 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_BME280] = addr;
|
||||
} else {
|
||||
DEBUG_MSG("BMP-280 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_BMP280] = addr;
|
||||
if (addr == BME_ADDR || addr == BME_ADDR_ALTERNATE) {
|
||||
registerValue = getRegisterValue(addr, 0xD0, 1); // GET_ID
|
||||
if (registerValue == 0x61) {
|
||||
DEBUG_MSG("BME-680 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_BME680] = addr;
|
||||
} else if (registerValue == 0x60) {
|
||||
DEBUG_MSG("BME-280 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_BME280] = addr;
|
||||
} else {
|
||||
DEBUG_MSG("BMP-280 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_BMP280] = addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (addr == INA_ADDR || addr == INA_ADDR_ALTERNATE) {
|
||||
registerValue = getRegisterValue(addr, 0xFE, 2);
|
||||
DEBUG_MSG("Register MFG_UID: 0x%x\n", registerValue);
|
||||
if (registerValue == 0x5449) {
|
||||
DEBUG_MSG("INA260 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_INA260] = addr;
|
||||
} else { // Assume INA219 if INA260 ID is not found
|
||||
DEBUG_MSG("INA219 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_INA219] = addr;
|
||||
if (addr == INA_ADDR || addr == INA_ADDR_ALTERNATE) {
|
||||
registerValue = getRegisterValue(addr, 0xFE, 2);
|
||||
DEBUG_MSG("Register MFG_UID: 0x%x\n", registerValue);
|
||||
if (registerValue == 0x5449) {
|
||||
DEBUG_MSG("INA260 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_INA260] = addr;
|
||||
} else { // Assume INA219 if INA260 ID is not found
|
||||
DEBUG_MSG("INA219 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_INA219] = addr;
|
||||
}
|
||||
}
|
||||
if (addr == MCP9808_ADDR) {
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_MCP9808] = addr;
|
||||
DEBUG_MSG("MCP9808 sensor found\n");
|
||||
}
|
||||
if (addr == SHTC3_ADDR) {
|
||||
DEBUG_MSG("SHTC3 sensor found\n");
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_SHTC3] = addr;
|
||||
}
|
||||
if (addr == LPS22HB_ADDR || addr == LPS22HB_ADDR_ALT) {
|
||||
DEBUG_MSG("LPS22HB sensor found\n");
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_LPS22] = addr;
|
||||
}
|
||||
|
||||
// High rate sensors, will be processed internally
|
||||
if (addr == QMC6310_ADDR) {
|
||||
DEBUG_MSG("QMC6310 Highrate 3-Axis magnetic sensor found\n");
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_QMC6310] = addr;
|
||||
}
|
||||
if (addr == QMI8658_ADDR) {
|
||||
DEBUG_MSG("QMI8658 Highrate 6-Axis inertial measurement sensor found\n");
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658] = addr;
|
||||
}
|
||||
if (addr == QMC5883L_ADDR) {
|
||||
DEBUG_MSG("QMC5883L Highrate 3-Axis magnetic sensor found\n");
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_QMC5883L] = addr;
|
||||
}
|
||||
}
|
||||
if (addr == MCP9808_ADDR) {
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_MCP9808] = addr;
|
||||
DEBUG_MSG("MCP9808 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
}
|
||||
if (addr == QMC6310_ADDR) {
|
||||
DEBUG_MSG("QMC6310 3-Axis magnetic sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_QMC6310] = addr;
|
||||
}
|
||||
if (addr == QMI8658_ADDR) {
|
||||
DEBUG_MSG("QMI8658 6-Axis inertial measurement sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658] = addr;
|
||||
}
|
||||
if (addr == SHTC3_ADDR) {
|
||||
DEBUG_MSG("SHTC3 sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_SHTC3] = addr;
|
||||
}
|
||||
if (addr == LPS22HB_ADDR || addr == LPS22HB_ADDR_ALT) {
|
||||
DEBUG_MSG("LPS22HB sensor found at address 0x%x\n", (uint8_t)addr);
|
||||
nodeTelemetrySensorsMap[TelemetrySensorType_LPS22] = addr;
|
||||
}
|
||||
} else if (err == 4) {
|
||||
DEBUG_MSG("Unknow error at address 0x%x\n", addr);
|
||||
}
|
||||
@@ -218,5 +224,5 @@ void scanI2Cdevice(void)
|
||||
DEBUG_MSG("%i I2C devices found\n",nDevices);
|
||||
}
|
||||
#else
|
||||
void scanI2Cdevice(void) {}
|
||||
void scanI2Cdevice() {}
|
||||
#endif
|
||||
|
||||
@@ -109,7 +109,7 @@ bool NMEAGPS::lookForLocation()
|
||||
|
||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||
fixType = atoi(gsafixtype.value()); // will set to zero if no data
|
||||
DEBUG_MSG("FIX QUAL=%d, TYPE=%d\n", fixQual, fixType);
|
||||
// DEBUG_MSG("FIX QUAL=%d, TYPE=%d\n", fixQual, fixType);
|
||||
#endif
|
||||
|
||||
// check if GPS has an acceptable lock
|
||||
@@ -168,7 +168,7 @@ bool NMEAGPS::lookForLocation()
|
||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||
p.HDOP = reader.hdop.value();
|
||||
p.PDOP = TinyGPSPlus::parseDecimal(gsapdop.value());
|
||||
DEBUG_MSG("PDOP=%d, HDOP=%d\n", dop, reader.hdop.value());
|
||||
// DEBUG_MSG("PDOP=%d, HDOP=%d\n", p.PDOP, p.HDOP);
|
||||
#else
|
||||
// FIXME! naive PDOP emulation (assumes VDOP==HDOP)
|
||||
// correct formula is PDOP = SQRT(HDOP^2 + VDOP^2)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "NMEAWPL.h"
|
||||
#include "GeoCoord.h"
|
||||
|
||||
/* -------------------------------------------
|
||||
* 1 2 3 4 5 6
|
||||
@@ -15,11 +16,19 @@
|
||||
* -------------------------------------------
|
||||
*/
|
||||
|
||||
uint printWPL(char *buf, const Position &pos, const char *name)
|
||||
uint32_t printWPL(char *buf, const Position &pos, const char *name)
|
||||
{
|
||||
uint len = sprintf(buf, "$GNWPL,%07.2f,%c,%08.2f,%c,%s", pos.latitude_i * 1e-5, pos.latitude_i < 0 ? 'S' : 'N', pos.longitude_i * 1e-5, pos.longitude_i < 0 ? 'W' : 'E', name);
|
||||
uint chk = 0;
|
||||
for (uint i = 1; i < len; i++) {
|
||||
GeoCoord geoCoord(pos.latitude_i,pos.longitude_i,pos.altitude);
|
||||
uint32_t len = sprintf(buf, "$GNWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s",
|
||||
geoCoord.getDMSLatDeg(),
|
||||
(abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6,
|
||||
geoCoord.getDMSLatCP(),
|
||||
geoCoord.getDMSLonDeg(),
|
||||
(abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
|
||||
geoCoord.getDMSLonCP(),
|
||||
name);
|
||||
uint32_t chk = 0;
|
||||
for (uint32_t i = 1; i < len; i++) {
|
||||
chk ^= buf[i];
|
||||
}
|
||||
len += sprintf(buf + len, "*%02X\r\n", chk);
|
||||
@@ -50,25 +59,30 @@ uint printWPL(char *buf, const Position &pos, const char *name)
|
||||
* -------------------------------------------
|
||||
*/
|
||||
|
||||
uint printGGA(char *buf, const Position &pos)
|
||||
uint32_t printGGA(char *buf, const Position &pos)
|
||||
{
|
||||
uint len = sprintf(buf, "$GNGGA,%06u.%03u,%07.2f,%c,%08.2f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d",
|
||||
GeoCoord geoCoord(pos.latitude_i,pos.longitude_i,pos.altitude);
|
||||
uint32_t len = sprintf(buf, "$GNGGA,%06u.%03u,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d",
|
||||
pos.time / 1000,
|
||||
pos.time % 1000,
|
||||
pos.latitude_i * 1e-5, pos.latitude_i < 0 ? 'S' : 'N',
|
||||
pos.longitude_i * 1e-5, pos.longitude_i < 0 ? 'W' : 'E',
|
||||
geoCoord.getDMSLatDeg(),
|
||||
(abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6,
|
||||
geoCoord.getDMSLatCP(),
|
||||
geoCoord.getDMSLonDeg(),
|
||||
(abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
|
||||
geoCoord.getDMSLonCP(),
|
||||
pos.fix_type,
|
||||
pos.sats_in_view,
|
||||
pos.HDOP,
|
||||
pos.altitude,
|
||||
geoCoord.getAltitude(),
|
||||
'M',
|
||||
pos.altitude_geoidal_separation,
|
||||
'M',
|
||||
0,
|
||||
0);
|
||||
|
||||
uint chk = 0;
|
||||
for (uint i = 1; i < len; i++) {
|
||||
uint32_t chk = 0;
|
||||
for (uint32_t i = 1; i < len; i++) {
|
||||
chk ^= buf[i];
|
||||
}
|
||||
len += sprintf(buf + len, "*%02X\r\n", chk);
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
#include <Arduino.h>
|
||||
#include "main.h"
|
||||
|
||||
uint printWPL(char *buf, const Position &pos, const char *name);
|
||||
uint printGGA(char *buf, const Position &pos);
|
||||
uint32_t printWPL(char *buf, const Position &pos, const char *name);
|
||||
uint32_t printGGA(char *buf, const Position &pos);
|
||||
|
||||
@@ -44,7 +44,11 @@ void readFromRTC()
|
||||
if(rtc_found == PCF8563_RTC) {
|
||||
uint32_t now = millis();
|
||||
PCF8563_Class rtc;
|
||||
#ifdef RTC_USE_WIRE1
|
||||
rtc.begin(Wire1);
|
||||
#else
|
||||
rtc.begin();
|
||||
#endif
|
||||
auto tc = rtc.getDateTime();
|
||||
tm t;
|
||||
t.tm_year = tc.year - 1900;
|
||||
@@ -110,7 +114,11 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
|
||||
#elif defined(PCF8563_RTC)
|
||||
if(rtc_found == PCF8563_RTC) {
|
||||
PCF8563_Class rtc;
|
||||
rtc.begin();
|
||||
#ifdef RTC_USE_WIRE1
|
||||
rtc.begin(Wire1);
|
||||
#else
|
||||
rtc.begin();
|
||||
#endif
|
||||
tm *t = localtime(&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);
|
||||
DEBUG_MSG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
|
||||
|
||||
@@ -50,8 +50,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using namespace meshtastic; /** @todo remove */
|
||||
|
||||
extern bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct);
|
||||
|
||||
namespace graphics
|
||||
{
|
||||
|
||||
@@ -67,6 +65,8 @@ namespace graphics
|
||||
static FrameCallback normalFrames[MAX_NUM_NODES + NUM_EXTRA_FRAMES];
|
||||
static uint32_t targetFramerate = IDLE_FRAMERATE;
|
||||
static char btPIN[16] = "888888";
|
||||
|
||||
uint32_t logo_timeout = 5000; // 4 seconds for EACH logo
|
||||
|
||||
// This image definition is here instead of images.h because it's modified dynamically by the drawBattery function
|
||||
uint8_t imgBattery[16] = {0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xE7, 0x3C};
|
||||
@@ -538,9 +538,10 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const
|
||||
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
|
||||
} else {
|
||||
|
||||
geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude()));
|
||||
|
||||
if (gpsFormat != Config_DisplayConfig_GpsCoordinateFormat_DMS) {
|
||||
char coordinateLine[22];
|
||||
geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude()));
|
||||
if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_DEC) { // Decimal Degrees
|
||||
sprintf(coordinateLine, "%f %f", geoCoord.getLatitude() * 1e-7, geoCoord.getLongitude() * 1e-7);
|
||||
} else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_UTM) { // Universal Transverse Mercator
|
||||
@@ -944,6 +945,9 @@ void Screen::setup()
|
||||
// Set the utf8 conversion function
|
||||
dispdev.setFontTableLookupFunction(customFontTableLookup);
|
||||
|
||||
if (strlen(oemStore.oem_text) > 0)
|
||||
logo_timeout *= 2;
|
||||
|
||||
// Add frames.
|
||||
static FrameCallback bootFrames[] = {drawBootScreen};
|
||||
static const int bootFrameCount = sizeof(bootFrames) / sizeof(bootFrames[0]);
|
||||
@@ -1012,26 +1016,28 @@ int32_t Screen::runOnce()
|
||||
return RUN_SAME;
|
||||
}
|
||||
|
||||
// Show boot screen for first 5 seconds, then switch to normal operation.
|
||||
// Show boot screen for first logo_timeout seconds, then switch to normal operation.
|
||||
// serialSinceMsec adjusts for additional serial wait time during nRF52 bootup
|
||||
static bool showingBootScreen = true;
|
||||
if (showingBootScreen && (millis() > (5000 + serialSinceMsec))) {
|
||||
if (showingBootScreen && (millis() > (logo_timeout + serialSinceMsec))) {
|
||||
DEBUG_MSG("Done with boot screen...\n");
|
||||
stopBootScreen();
|
||||
showingBootScreen = false;
|
||||
}
|
||||
|
||||
// If we have an OEM Boot screen, toggle after 2,5 seconds
|
||||
// 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() > (2500 + serialSinceMsec))) {
|
||||
if (showingOEMBootScreen && (millis() > ((logo_timeout / 2) + serialSinceMsec))) {
|
||||
DEBUG_MSG("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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace graphics
|
||||
class Screen
|
||||
{
|
||||
public:
|
||||
Screen(char){}
|
||||
explicit Screen(char){}
|
||||
void onPress() {}
|
||||
void setup() {}
|
||||
void setOn(bool) {}
|
||||
|
||||
57
src/main.cpp
57
src/main.cpp
@@ -37,7 +37,7 @@
|
||||
#include "nimble/NimbleBluetooth.h"
|
||||
#endif
|
||||
|
||||
#if HAS_WIFI || defined(ARCH_PORTDUINO)
|
||||
#if HAS_WIFI
|
||||
#include "mesh/wifi/WiFiServerAPI.h"
|
||||
#include "mqtt/MQTT.h"
|
||||
#endif
|
||||
@@ -51,7 +51,7 @@
|
||||
#include "RF95Interface.h"
|
||||
#include "SX1262Interface.h"
|
||||
#include "SX1268Interface.h"
|
||||
#include "SX1281Interface.h"
|
||||
#include "SX1280Interface.h"
|
||||
#if !HAS_RADIO && defined(ARCH_PORTDUINO)
|
||||
#include "platform/portduino/SimRadio.h"
|
||||
#endif
|
||||
@@ -87,8 +87,6 @@ uint8_t kb_model;
|
||||
// The I2C address of the RTC Module (if found)
|
||||
uint8_t rtc_found;
|
||||
|
||||
bool rIf_wide_lora = false;
|
||||
|
||||
// Keystore Chips
|
||||
uint8_t keystore_found;
|
||||
#ifndef ARCH_PORTDUINO
|
||||
@@ -102,7 +100,7 @@ uint32_t serialSinceMsec;
|
||||
bool pmu_found;
|
||||
|
||||
// Array map of sensor types (as array index) and i2c address as value we'll find in the i2c scan
|
||||
uint8_t nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
uint8_t nodeTelemetrySensorsMap[_TelemetrySensorType_MAX + 1] = { 0 }; // one is enough, missing elements will be initialized to 0 anyway.
|
||||
|
||||
Router *router = NULL; // Users of router don't care what sort of subclass implements that API
|
||||
|
||||
@@ -246,8 +244,32 @@ void setup()
|
||||
digitalWrite(PIN_3V3_EN, 1);
|
||||
#endif
|
||||
|
||||
|
||||
// Currently only the tbeam has a PMU
|
||||
// PMU initialization needs to be placed before scanI2Cdevice
|
||||
power = new Power();
|
||||
power->setStatusHandler(powerStatus);
|
||||
powerStatus->observe(&power->newStatus);
|
||||
power->setup(); // Must be after status handler is installed, so that handler gets notified of the initial configuration
|
||||
|
||||
|
||||
#ifdef LILYGO_TBEAM_S3_CORE
|
||||
// In T-Beam-S3-core, the I2C device cannot be scanned before power initialization, otherwise the device will be stuck
|
||||
// PCF8563 RTC in tbeam-s3 uses Wire1 to share I2C bus
|
||||
Wire1.beginTransmission(PCF8563_RTC);
|
||||
if (Wire1.endTransmission() == 0){
|
||||
rtc_found = PCF8563_RTC;
|
||||
DEBUG_MSG("PCF8563 RTC found\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
// We need to scan here to decide if we have a screen for nodeDB.init()
|
||||
scanI2Cdevice();
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
setupSDCard();
|
||||
#endif
|
||||
|
||||
#ifdef RAK4630
|
||||
// scanEInkDevice();
|
||||
#endif
|
||||
@@ -281,18 +303,10 @@ void setup()
|
||||
nodeDB.init();
|
||||
|
||||
playStartMelody();
|
||||
|
||||
// Currently only the tbeam has a PMU
|
||||
power = new Power();
|
||||
power->setStatusHandler(powerStatus);
|
||||
powerStatus->observe(&power->newStatus);
|
||||
power->setup(); // Must be after status handler is installed, so that handler gets notified of the initial configuration
|
||||
|
||||
/*
|
||||
* Repeat the scanning for I2C devices after power initialization or look for 'latecomers'.
|
||||
* Boards with an PMU need to be powered on to correctly scan to the device address, such as t-beam-s3-core
|
||||
*/
|
||||
scanI2Cdevice();
|
||||
|
||||
// fixed screen override?
|
||||
if (config.display.oled != Config_DisplayConfig_OledType_OLED_AUTO)
|
||||
screen_model = config.display.oled;
|
||||
|
||||
// Init our SPI controller (must be before screen and lora)
|
||||
initSPI();
|
||||
@@ -372,16 +386,15 @@ void setup()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_SX1281) && !defined(ARCH_PORTDUINO)
|
||||
#if defined(USE_SX1280) && !defined(ARCH_PORTDUINO)
|
||||
if (!rIf) {
|
||||
rIf = new SX1281Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI);
|
||||
rIf = new SX1280Interface(SX128X_CS, SX128X_DIO1, SX128X_RESET, SX128X_BUSY, SPI);
|
||||
if (!rIf->init()) {
|
||||
DEBUG_MSG("Warning: Failed to find SX1281 radio\n");
|
||||
DEBUG_MSG("Warning: Failed to find SX1280 radio\n");
|
||||
delete rIf;
|
||||
rIf = NULL;
|
||||
} else {
|
||||
DEBUG_MSG("SX1281 Radio init succeeded, using SX1281 radio\n");
|
||||
rIf_wide_lora = true;
|
||||
DEBUG_MSG("SX1280 Radio init succeeded, using SX1280 radio\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -17,7 +17,6 @@ extern uint8_t kb_model;
|
||||
extern uint8_t rtc_found;
|
||||
extern uint8_t keystore_found;
|
||||
|
||||
extern bool rIf_wide_lora;
|
||||
extern bool eink_found;
|
||||
extern bool pmu_found;
|
||||
extern bool isCharging;
|
||||
@@ -27,7 +26,7 @@ extern bool isUSBPowered;
|
||||
extern ATECCX08A atecc;
|
||||
#endif
|
||||
|
||||
extern uint8_t nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658+1];
|
||||
extern uint8_t nodeTelemetrySensorsMap[_TelemetrySensorType_MAX + 1];
|
||||
|
||||
extern int TCPPort; // set by Portduino
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@ bool FloodingRouter::shouldFilterReceived(MeshPacket *p)
|
||||
|
||||
void FloodingRouter::sniffReceived(const MeshPacket *p, const Routing *c)
|
||||
{
|
||||
PacketId ackId = ((c && c->error_reason == Routing_Error_NONE) || !c) ? p->decoded.request_id : 0;
|
||||
if (ackId && p->to != getNodeNum()) {
|
||||
bool isAck = ((c && c->error_reason == Routing_Error_NONE)); // consider only ROUTING_APP message without error as ACK
|
||||
if (isAck && p->to != getNodeNum()) {
|
||||
// do not flood direct message that is ACKed
|
||||
DEBUG_MSG("Receiving an ACK not for me, but don't need to rebroadcast this direct message anymore.\n");
|
||||
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM
|
||||
|
||||
@@ -8,6 +8,6 @@ template class SX126xInterface<SX1262>;
|
||||
template class SX126xInterface<SX1268>;
|
||||
template class SX126xInterface<LLCC68>;
|
||||
|
||||
#if !defined(ARCH_PORTDUINO)
|
||||
template class SX128xInterface<SX1281>;
|
||||
#if defined(RADIOLIB_GODMODE)
|
||||
template class SX128xInterface<SX1280>;
|
||||
#endif
|
||||
@@ -109,10 +109,7 @@ void MeshModule::callPlugins(const MeshPacket &mp, RxSource src)
|
||||
/// Also: if a packet comes in on the local PC interface, we don't check for bound channels, because it is TRUSTED and it needs to
|
||||
/// to be able to fetch the initial admin packets without yet knowing any channels.
|
||||
|
||||
bool rxChannelOk = !pi.boundChannel || (mp.from == 0) ||
|
||||
!ch ||
|
||||
strlen(ch->settings.name) > 0 ||
|
||||
(strcasecmp(ch->settings.name, pi.boundChannel) == 0);
|
||||
bool rxChannelOk = !pi.boundChannel || (mp.from == 0) || (strcasecmp(ch->settings.name, pi.boundChannel) == 0);
|
||||
|
||||
if (!rxChannelOk) {
|
||||
// no one should have already replied!
|
||||
|
||||
@@ -104,16 +104,17 @@ bool MeshService::reloadConfig(int saveWhat)
|
||||
}
|
||||
|
||||
/// The owner User record just got updated, update our node DB and broadcast the info into the mesh
|
||||
void MeshService::reloadOwner()
|
||||
void MeshService::reloadOwner(bool shouldSave)
|
||||
{
|
||||
// DEBUG_MSG("reloadOwner()\n");
|
||||
// update our local data directly
|
||||
nodeDB.updateUser(nodeDB.getNodeNum(), owner);
|
||||
assert(nodeInfoModule);
|
||||
// update everyone else
|
||||
if (nodeInfoModule)
|
||||
// update everyone else and save to disk
|
||||
if (nodeInfoModule && shouldSave) {
|
||||
nodeInfoModule->sendOurNodeInfo();
|
||||
nodeDB.saveToDisk(SEGMENT_DEVICESTATE);
|
||||
nodeDB.saveToDisk(SEGMENT_DEVICESTATE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -69,7 +69,7 @@ class MeshService
|
||||
bool reloadConfig(int saveWhat=SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
|
||||
|
||||
/// The owner User record just got updated, update our node DB and broadcast the info into the mesh
|
||||
void reloadOwner();
|
||||
void reloadOwner(bool shouldSave = true);
|
||||
|
||||
/// Called when the user wakes up our GUI, normally sends our latest location to the mesh (if we have it), otherwise at least
|
||||
/// sends our owner
|
||||
|
||||
@@ -204,6 +204,7 @@ void NodeDB::installDefaultModuleConfig()
|
||||
{
|
||||
DEBUG_MSG("Installing default ModuleConfig\n");
|
||||
memset(&moduleConfig, 0, sizeof(ModuleConfig));
|
||||
|
||||
moduleConfig.version = DEVICESTATE_CUR_VER;
|
||||
moduleConfig.has_mqtt = true;
|
||||
moduleConfig.has_range_test = true;
|
||||
@@ -213,6 +214,10 @@ void NodeDB::installDefaultModuleConfig()
|
||||
moduleConfig.has_external_notification = true;
|
||||
moduleConfig.has_canned_message = true;
|
||||
|
||||
strncpy(moduleConfig.mqtt.address, default_mqtt_address, sizeof(default_mqtt_address));
|
||||
strncpy(moduleConfig.mqtt.username, default_mqtt_username, sizeof(default_mqtt_username));
|
||||
strncpy(moduleConfig.mqtt.password, default_mqtt_password, sizeof(default_mqtt_password));
|
||||
|
||||
initModuleConfigIntervals();
|
||||
}
|
||||
|
||||
@@ -741,9 +746,9 @@ void recordCriticalError(CriticalErrorCode code, uint32_t address, const char *f
|
||||
String lcd = String("Critical error ") + code + "!\n";
|
||||
screen->print(lcd.c_str());
|
||||
if (filename)
|
||||
DEBUG_MSG("NOTE! Recording critical error %d at %s:%lx\n", code, filename, address);
|
||||
DEBUG_MSG("NOTE! Recording critical error %d at %s:%lu\n", code, filename, address);
|
||||
else
|
||||
DEBUG_MSG("NOTE! Recording critical error %d, address=%lx\n", code, address);
|
||||
DEBUG_MSG("NOTE! Recording critical error %d, address=0x%lx\n", code, address);
|
||||
|
||||
// Record error to DB
|
||||
myNodeInfo.error_code = code;
|
||||
|
||||
@@ -58,7 +58,7 @@ class NodeDB
|
||||
void init();
|
||||
|
||||
/// write to flash
|
||||
void saveToDisk(int saveWhat=SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS), saveChannelsToDisk(), saveDeviceStateToDisk();
|
||||
void saveToDisk(int saveWhat = SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS), saveChannelsToDisk(), saveDeviceStateToDisk();
|
||||
|
||||
/** Reinit radio config if needed, because either:
|
||||
* a) sometimes a buggy android app might send us bogus settings or
|
||||
@@ -194,6 +194,10 @@ extern NodeDB nodeDB;
|
||||
#define default_min_wake_secs 10
|
||||
#define default_screen_on_secs 60 * 10
|
||||
|
||||
#define default_mqtt_address "mqtt.meshtastic.org"
|
||||
#define default_mqtt_username "meshdev"
|
||||
#define default_mqtt_password "large4cats"
|
||||
|
||||
inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval)
|
||||
{
|
||||
if (configuredInterval > 0) return configuredInterval * 1000;
|
||||
|
||||
@@ -249,11 +249,15 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_canned_message_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.canned_message = moduleConfig.canned_message;
|
||||
break;
|
||||
case ModuleConfig_audio_tag:
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_audio_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.audio = moduleConfig.audio;
|
||||
break;
|
||||
}
|
||||
|
||||
config_state++;
|
||||
// Advance when we have sent all of our ModuleConfig objects
|
||||
if (config_state > ModuleConfig_canned_message_tag) {
|
||||
if (config_state > ModuleConfig_audio_tag) {
|
||||
state = STATE_SEND_COMPLETE_ID;
|
||||
config_state = 0;
|
||||
}
|
||||
|
||||
@@ -129,6 +129,7 @@ bool RF95Interface::reconfigure()
|
||||
|
||||
if (power > MAX_POWER) // This chip has lower power limits than some
|
||||
power = MAX_POWER;
|
||||
|
||||
err = lora->setOutputPower(power);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
@@ -89,7 +89,7 @@ const RegionInfo regions[] = {
|
||||
https://rrf.rsm.govt.nz/smart-web/smart/page/-smart/domain/licence/LicenceSummary.wdk?id=219752
|
||||
https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf
|
||||
*/
|
||||
RDEF(NZ_865, 864.0f, 868.0f, 100, 0, 0, true, false, false),
|
||||
RDEF(NZ_865, 864.0f, 868.0f, 100, 0, 36, true, false, false),
|
||||
|
||||
/*
|
||||
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
|
||||
@@ -365,37 +365,37 @@ void RadioInterface::applyModemConfig()
|
||||
|
||||
switch (loraConfig.modem_preset) {
|
||||
case Config_LoRaConfig_ModemPreset_SHORT_FAST:
|
||||
bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
|
||||
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||
cr = 8;
|
||||
sf = 7;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_SHORT_SLOW:
|
||||
bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
|
||||
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||
cr = 8;
|
||||
sf = 8;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
|
||||
bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
|
||||
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||
cr = 8;
|
||||
sf = 9;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
|
||||
bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
|
||||
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||
cr = 8;
|
||||
sf = 10;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_LONG_FAST:
|
||||
bw = (myRegion->wideLora && rIf_wide_lora) ? 800 : 250;
|
||||
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||
cr = 8;
|
||||
sf = 11;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_LONG_SLOW:
|
||||
bw = (myRegion->wideLora && rIf_wide_lora) ? 400 : 125;
|
||||
bw = (myRegion->wideLora) ? 406.25 : 125;
|
||||
cr = 8;
|
||||
sf = 12;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
|
||||
bw = (myRegion->wideLora && rIf_wide_lora) ? 200 : 31.25;
|
||||
bw = (myRegion->wideLora) ? 203.125 : 31.25;
|
||||
cr = 8;
|
||||
sf = 12;
|
||||
break;
|
||||
@@ -411,12 +411,20 @@ void RadioInterface::applyModemConfig()
|
||||
bw = 31.25;
|
||||
if (bw == 62) // Fix for 62.5Khz bandwidth
|
||||
bw = 62.5;
|
||||
if (bw == 200)
|
||||
bw = 203.125;
|
||||
if (bw == 400)
|
||||
bw = 406.25;
|
||||
if (bw == 800)
|
||||
bw = 812.5;
|
||||
if (bw == 1600)
|
||||
bw = 1625.0;
|
||||
}
|
||||
|
||||
power = loraConfig.tx_power;
|
||||
assert(myRegion); // Should have been found in init
|
||||
|
||||
if ((power == 0) || (power > myRegion->powerLimit))
|
||||
if ((power == 0) || ((power > myRegion->powerLimit) && !devicestate.owner.is_licensed))
|
||||
power = myRegion->powerLimit;
|
||||
|
||||
if (power == 0)
|
||||
@@ -443,7 +451,7 @@ void RadioInterface::applyModemConfig()
|
||||
|
||||
DEBUG_MSG("Set radio: region=%s, name=%s, config=%u, ch=%d, power=%d\n", myRegion->name, channelName, loraConfig.modem_preset, channel_num, power);
|
||||
DEBUG_MSG("Radio myRegion->freqStart / myRegion->freqEnd: %f -> %f (%f mhz)\n", myRegion->freqStart, myRegion->freqEnd, myRegion->freqEnd - myRegion->freqStart);
|
||||
DEBUG_MSG("Radio myRegion->numChannels: %d\n", numChannels);
|
||||
DEBUG_MSG("Radio myRegion->numChannels: %d x %.3fkHz\n", numChannels, bw);
|
||||
DEBUG_MSG("Radio channel_num: %d\n", channel_num);
|
||||
DEBUG_MSG("Radio frequency: %f\n", getFreq());
|
||||
DEBUG_MSG("Slot time: %u msec\n", slotTimeMsec);
|
||||
@@ -460,7 +468,7 @@ void RadioInterface::limitPower()
|
||||
if (myRegion->powerLimit)
|
||||
maxPower = myRegion->powerLimit;
|
||||
|
||||
if (power > maxPower) {
|
||||
if ((power > maxPower) && !devicestate.owner.is_licensed) {
|
||||
DEBUG_MSG("Lowering transmit power because of regulatory limits\n");
|
||||
power = maxPower;
|
||||
}
|
||||
|
||||
@@ -11,17 +11,6 @@
|
||||
// FIXME, we default to 4MHz SPI, SPI mode 0, check if the datasheet says it can really do that
|
||||
static SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0);
|
||||
|
||||
#ifdef ARCH_PORTDUINO
|
||||
|
||||
void LockingModule::SPItransfer(uint8_t cmd, uint8_t reg, uint8_t *dataOut, uint8_t *dataIn, uint8_t numBytes)
|
||||
{
|
||||
concurrency::LockGuard g(spiLock);
|
||||
|
||||
Module::SPItransfer(cmd, reg, dataOut, dataIn, numBytes);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void LockingModule::SPIbeginTransaction()
|
||||
{
|
||||
spiLock->lock();
|
||||
@@ -36,8 +25,6 @@ void LockingModule::SPIendTransaction()
|
||||
Module::SPIendTransaction();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
RadioLibInterface::RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
||||
SPIClass &spi, PhysicalLayer *_iface)
|
||||
: NotifiedWorkerThread("RadioIf"), module(cs, irq, rst, busy, spi, spiSettings), iface(_iface)
|
||||
@@ -317,7 +304,13 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
|
||||
void RadioLibInterface::handleReceiveInterrupt()
|
||||
{
|
||||
uint32_t xmitMsec;
|
||||
assert(isReceiving);
|
||||
|
||||
// when this is called, we should be in receive mode - if we are not, just jump out instead of bombing. Possible Race Condition?
|
||||
if (!isReceiving) {
|
||||
DEBUG_MSG("*** WAS_ASSERT *** handleReceiveInterrupt called when not in receive mode\n");
|
||||
return;
|
||||
}
|
||||
|
||||
isReceiving = false;
|
||||
|
||||
// read the number of actually received bytes
|
||||
|
||||
@@ -41,12 +41,8 @@ class LockingModule : public Module
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef ARCH_PORTDUINO
|
||||
void SPItransfer(uint8_t cmd, uint8_t reg, uint8_t *dataOut, uint8_t *dataIn, uint8_t numBytes) override;
|
||||
#else
|
||||
void SPIbeginTransaction() override;
|
||||
void SPIendTransaction() override;
|
||||
#endif
|
||||
};
|
||||
|
||||
class RadioLibInterface : public RadioInterface, protected concurrency::NotifiedWorkerThread
|
||||
|
||||
@@ -96,7 +96,11 @@ void ReliableRouter::sniffReceived(const MeshPacket *p, const Routing *c)
|
||||
if (MeshModule::currentReply)
|
||||
DEBUG_MSG("Some other module has replied to this message, no need for a 2nd ack\n");
|
||||
else
|
||||
sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel);
|
||||
if (p->which_payload_variant == MeshPacket_decoded_tag)
|
||||
sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel);
|
||||
else
|
||||
// Send a 'NO_CHANNEL' error on the primary channel if want_ack packet destined for us cannot be decoded
|
||||
sendAckNak(Routing_Error_NO_CHANNEL, getFrom(p), p->id, channels.getPrimaryIndex());
|
||||
}
|
||||
|
||||
// We consider an ack to be either a !routing packet with a request ID or a routing packet with !error
|
||||
|
||||
@@ -11,7 +11,7 @@ extern "C" {
|
||||
#include "mesh/compression/unishox2.h"
|
||||
}
|
||||
|
||||
#if HAS_WIFI
|
||||
#if HAS_WIFI || HAS_ETHERNET
|
||||
#include "mqtt/MQTT.h"
|
||||
#endif
|
||||
|
||||
@@ -209,7 +209,7 @@ ErrorCode Router::send(MeshPacket *p)
|
||||
if (p->which_payload_variant == MeshPacket_decoded_tag) {
|
||||
ChannelIndex chIndex = p->channel; // keep as a local because we are about to change it
|
||||
|
||||
#if HAS_WIFI
|
||||
#if HAS_WIFI || HAS_ETHERNET
|
||||
// check if we should send decrypted packets to mqtt
|
||||
|
||||
// truth table:
|
||||
@@ -240,7 +240,7 @@ ErrorCode Router::send(MeshPacket *p)
|
||||
return encodeResult; // FIXME - this isn't a valid ErrorCode
|
||||
}
|
||||
|
||||
#if HAS_WIFI
|
||||
#if HAS_WIFI || HAS_ETHERNET
|
||||
// the packet is now encrypted.
|
||||
// check if we should send encrypted packets to mqtt
|
||||
if (mqtt && shouldActuallyEncrypt)
|
||||
|
||||
@@ -25,11 +25,11 @@ bool SX126xInterface<T>::init()
|
||||
pinMode(SX126X_POWER_EN, OUTPUT);
|
||||
#endif
|
||||
|
||||
#ifdef SX126X_RXEN // set not rx or tx mode
|
||||
#if defined(SX126X_RXEN) && (SX126X_RXEN != RADIOLIB_NC) // set not rx or tx mode
|
||||
digitalWrite(SX126X_RXEN, LOW); // Set low before becoming an output
|
||||
pinMode(SX126X_RXEN, OUTPUT);
|
||||
#endif
|
||||
#ifdef SX126X_TXEN
|
||||
#if defined(SX126X_TXEN) && (SX126X_TXEN != RADIOLIB_NC)
|
||||
digitalWrite(SX126X_TXEN, LOW);
|
||||
pinMode(SX126X_TXEN, OUTPUT);
|
||||
#endif
|
||||
@@ -66,7 +66,7 @@ bool SX126xInterface<T>::init()
|
||||
DEBUG_MSG("Current limit set to %f\n", currentLimit);
|
||||
DEBUG_MSG("Current limit set result %d\n", res);
|
||||
|
||||
#ifdef SX126X_TXEN
|
||||
#if defined(SX126X_TXEN) && (SX126X_TXEN != RADIOLIB_NC)
|
||||
// lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX
|
||||
if (res == RADIOLIB_ERR_NONE)
|
||||
res = lora.setDio2AsRfSwitch(true);
|
||||
@@ -144,8 +144,9 @@ bool SX126xInterface<T>::reconfigure()
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
if (power > 22) // This chip has lower power limits than some
|
||||
power = 22;
|
||||
if (power > SX126X_MAX_POWER) // This chip has lower power limits than some
|
||||
power = SX126X_MAX_POWER;
|
||||
|
||||
err = lora.setOutputPower(power);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
@@ -166,12 +167,16 @@ void SX126xInterface<T>::setStandby()
|
||||
checkNotification(); // handle any pending interrupts before we force standby
|
||||
|
||||
int err = lora.standby();
|
||||
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
DEBUG_MSG("SX126x standby failed with error %d\n", err);
|
||||
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
#ifdef SX126X_RXEN // we have RXEN/TXEN control - turn off RX and TX power
|
||||
#if defined(SX126X_RXEN) && (SX126X_RXEN != RADIOLIB_NC) // we have RXEN/TXEN control - turn off RX and TX power
|
||||
digitalWrite(SX126X_RXEN, LOW);
|
||||
#endif
|
||||
#ifdef SX126X_TXEN
|
||||
#if defined(SX126X_TXEN) && (SX126X_TXEN != RADIOLIB_NC)
|
||||
digitalWrite(SX126X_TXEN, LOW);
|
||||
#endif
|
||||
|
||||
@@ -196,10 +201,10 @@ void SX126xInterface<T>::addReceiveMetadata(MeshPacket *mp)
|
||||
template<typename T>
|
||||
void SX126xInterface<T>::configHardwareForSend()
|
||||
{
|
||||
#ifdef SX126X_TXEN // we have RXEN/TXEN control - turn on TX power / off RX power
|
||||
#if defined(SX126X_TXEN) && (SX126X_TXEN != RADIOLIB_NC) // we have RXEN/TXEN control - turn on TX power / off RX power
|
||||
digitalWrite(SX126X_TXEN, HIGH);
|
||||
#endif
|
||||
#ifdef SX126X_RXEN
|
||||
#if defined(SX126X_RXEN) && (SX126X_RXEN != RADIOLIB_NC)
|
||||
digitalWrite(SX126X_RXEN, LOW);
|
||||
#endif
|
||||
|
||||
@@ -218,10 +223,10 @@ void SX126xInterface<T>::startReceive()
|
||||
|
||||
setStandby();
|
||||
|
||||
#ifdef SX126X_RXEN // we have RXEN/TXEN control - turn on RX power / off TX power
|
||||
#if defined(SX126X_RXEN) && (SX126X_RXEN != RADIOLIB_NC) // we have RXEN/TXEN control - turn on RX power / off TX power
|
||||
digitalWrite(SX126X_RXEN, HIGH);
|
||||
#endif
|
||||
#ifdef SX126X_TXEN
|
||||
#if defined(SX126X_TXEN) && (SX126X_TXEN != RADIOLIB_NC)
|
||||
digitalWrite(SX126X_TXEN, LOW);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#include "configuration.h"
|
||||
#include "SX1281Interface.h"
|
||||
#include "SX1280Interface.h"
|
||||
#include "error.h"
|
||||
|
||||
#if !defined(ARCH_PORTDUINO)
|
||||
#if defined(RADIOLIB_GODMODE)
|
||||
|
||||
SX1281Interface::SX1281Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
||||
SX1280Interface::SX1280Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
||||
SPIClass &spi)
|
||||
: SX128xInterface(cs, irq, rst, busy, spi)
|
||||
{
|
||||
17
src/mesh/SX1280Interface.h
Normal file
17
src/mesh/SX1280Interface.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "SX128xInterface.h"
|
||||
|
||||
/**
|
||||
* Our adapter for SX1280 radios
|
||||
*/
|
||||
|
||||
#if defined(RADIOLIB_GODMODE)
|
||||
|
||||
class SX1280Interface : public SX128xInterface<SX1280>
|
||||
{
|
||||
public:
|
||||
SX1280Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "SX128xInterface.h"
|
||||
|
||||
/**
|
||||
* Our adapter for SX1281 radios
|
||||
*/
|
||||
|
||||
#if !defined(ARCH_PORTDUINO)
|
||||
|
||||
class SX1281Interface : public SX128xInterface<SX1281>
|
||||
{
|
||||
public:
|
||||
SX1281Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -2,11 +2,11 @@
|
||||
#include "SX128xInterface.h"
|
||||
#include "error.h"
|
||||
|
||||
#if !defined(ARCH_PORTDUINO)
|
||||
#if defined(RADIOLIB_GODMODE)
|
||||
|
||||
// Particular boards might define a different max power based on what their hardware can do
|
||||
#ifndef SX128X_MAX_POWER
|
||||
#define SX128X_MAX_POWER 22
|
||||
#define SX128X_MAX_POWER 13
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
@@ -61,7 +61,7 @@ bool SX128xInterface<T>::init()
|
||||
#endif
|
||||
|
||||
if (res == RADIOLIB_ERR_NONE)
|
||||
res = lora.setCRC(RADIOLIB_SX128X_LORA_CRC_ON);
|
||||
res = lora.setCRC(2);
|
||||
|
||||
if (res == RADIOLIB_ERR_NONE)
|
||||
startReceive(); // start receiving
|
||||
@@ -105,8 +105,9 @@ bool SX128xInterface<T>::reconfigure()
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
RECORD_CRITICALERROR(CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
if (power > 22) // This chip has lower power limits than some
|
||||
power = 22;
|
||||
if (power > SX128X_MAX_POWER) // This chip has lower power limits than some
|
||||
power = SX128X_MAX_POWER;
|
||||
|
||||
err = lora.setOutputPower(power);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
@@ -218,7 +219,11 @@ bool SX128xInterface<T>::isChannelActive()
|
||||
template<typename T>
|
||||
bool SX128xInterface<T>::isActivelyReceiving()
|
||||
{
|
||||
return isChannelActive();
|
||||
// return isChannelActive();
|
||||
|
||||
uint16_t irq = lora.getIrqStatus();
|
||||
bool hasPreamble = (irq & RADIOLIB_SX128X_IRQ_HEADER_VALID);
|
||||
return hasPreamble;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#if !defined(ARCH_PORTDUINO)
|
||||
#if defined(RADIOLIB_GODMODE)
|
||||
|
||||
#include "RadioLibInterface.h"
|
||||
|
||||
/**
|
||||
* \brief Adapter for SX128x radio family. Implements common logic for child classes.
|
||||
* \tparam T RadioLib module type for SX128x: SX1281.
|
||||
* \tparam T RadioLib module type for SX128x: SX1280.
|
||||
*/
|
||||
template<class T>
|
||||
class SX128xInterface : public RadioLibInterface
|
||||
|
||||
@@ -32,7 +32,8 @@ typedef enum _AdminMessage_ModuleConfigType {
|
||||
AdminMessage_ModuleConfigType_STOREFORWARD_CONFIG = 3,
|
||||
AdminMessage_ModuleConfigType_RANGETEST_CONFIG = 4,
|
||||
AdminMessage_ModuleConfigType_TELEMETRY_CONFIG = 5,
|
||||
AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG = 6
|
||||
AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG = 6,
|
||||
AdminMessage_ModuleConfigType_AUDIO_CONFIG = 7
|
||||
} AdminMessage_ModuleConfigType;
|
||||
|
||||
/* Struct definitions */
|
||||
@@ -81,10 +82,11 @@ typedef struct _AdminMessage {
|
||||
ModuleConfig set_module_config;
|
||||
/* Set the Canned Message Module messages text. */
|
||||
char set_canned_message_module_messages[201];
|
||||
/* Sent immediatly after a config change has been sent to ensure comms, if this is not recieved, the config will be reverted after 10 mins */
|
||||
bool confirm_set_config;
|
||||
/* Sent immediatly after a config change has been sent to ensure comms, if this is not recieved, the config will be reverted after 10 mins */
|
||||
bool confirm_set_module_config;
|
||||
/* Begins an edit transaction for config, module config, owner, and channel settings changes
|
||||
This will delay the standard *implicit* save to the file system and subsequent reboot behavior until committed (commit_edit_settings) */
|
||||
bool begin_edit_settings;
|
||||
/* Commits an open transaction for any edits made to config, module config, owner, and channel settings */
|
||||
bool commit_edit_settings;
|
||||
/* Setting channels/radio config remotely carries the risk that you might send an invalid config and the radio never talks to your mesh again.
|
||||
Therefore if setting either of these properties remotely, you must send a confirm_xxx message within 10 minutes.
|
||||
If you fail to do so, the radio will assume loss of comms and revert your changes.
|
||||
@@ -116,8 +118,8 @@ typedef struct _AdminMessage {
|
||||
#define _AdminMessage_ConfigType_ARRAYSIZE ((AdminMessage_ConfigType)(AdminMessage_ConfigType_BLUETOOTH_CONFIG+1))
|
||||
|
||||
#define _AdminMessage_ModuleConfigType_MIN AdminMessage_ModuleConfigType_MQTT_CONFIG
|
||||
#define _AdminMessage_ModuleConfigType_MAX AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG
|
||||
#define _AdminMessage_ModuleConfigType_ARRAYSIZE ((AdminMessage_ModuleConfigType)(AdminMessage_ModuleConfigType_CANNEDMSG_CONFIG+1))
|
||||
#define _AdminMessage_ModuleConfigType_MAX AdminMessage_ModuleConfigType_AUDIO_CONFIG
|
||||
#define _AdminMessage_ModuleConfigType_ARRAYSIZE ((AdminMessage_ModuleConfigType)(AdminMessage_ModuleConfigType_AUDIO_CONFIG+1))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -146,8 +148,8 @@ extern "C" {
|
||||
#define AdminMessage_set_config_tag 34
|
||||
#define AdminMessage_set_module_config_tag 35
|
||||
#define AdminMessage_set_canned_message_module_messages_tag 36
|
||||
#define AdminMessage_confirm_set_config_tag 64
|
||||
#define AdminMessage_confirm_set_module_config_tag 65
|
||||
#define AdminMessage_begin_edit_settings_tag 64
|
||||
#define AdminMessage_commit_edit_settings_tag 65
|
||||
#define AdminMessage_confirm_set_channel_tag 66
|
||||
#define AdminMessage_confirm_set_radio_tag 67
|
||||
#define AdminMessage_reboot_ota_seconds_tag 95
|
||||
@@ -176,8 +178,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_channel,set_channel), 3
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_config,set_config), 34) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,set_module_config,set_module_config), 35) \
|
||||
X(a, STATIC, ONEOF, STRING, (payload_variant,set_canned_message_module_messages,set_canned_message_module_messages), 36) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_config,confirm_set_config), 64) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_module_config,confirm_set_module_config), 65) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,begin_edit_settings,begin_edit_settings), 64) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,commit_edit_settings,commit_edit_settings), 65) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_channel,confirm_set_channel), 66) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_radio,confirm_set_radio), 67) \
|
||||
X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_ota_seconds,reboot_ota_seconds), 95) \
|
||||
|
||||
@@ -31,12 +31,6 @@ typedef enum _Config_PositionConfig_PositionFlags {
|
||||
Config_PositionConfig_PositionFlags_SPEED = 512
|
||||
} Config_PositionConfig_PositionFlags;
|
||||
|
||||
typedef enum _Config_NetworkConfig_WiFiMode {
|
||||
Config_NetworkConfig_WiFiMode_CLIENT = 0,
|
||||
Config_NetworkConfig_WiFiMode_ACCESS_POINT = 1,
|
||||
Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN = 2
|
||||
} Config_NetworkConfig_WiFiMode;
|
||||
|
||||
typedef enum _Config_NetworkConfig_EthMode {
|
||||
Config_NetworkConfig_EthMode_DHCP = 0,
|
||||
Config_NetworkConfig_EthMode_STATIC = 1
|
||||
@@ -56,6 +50,12 @@ typedef enum _Config_DisplayConfig_DisplayUnits {
|
||||
Config_DisplayConfig_DisplayUnits_IMPERIAL = 1
|
||||
} Config_DisplayConfig_DisplayUnits;
|
||||
|
||||
typedef enum _Config_DisplayConfig_OledType {
|
||||
Config_DisplayConfig_OledType_OLED_AUTO = 0,
|
||||
Config_DisplayConfig_OledType_OLED_SSD1306 = 1,
|
||||
Config_DisplayConfig_OledType_OLED_SH1106 = 2
|
||||
} Config_DisplayConfig_OledType;
|
||||
|
||||
typedef enum _Config_LoRaConfig_RegionCode {
|
||||
Config_LoRaConfig_RegionCode_UNSET = 0,
|
||||
Config_LoRaConfig_RegionCode_US = 1,
|
||||
@@ -109,6 +109,7 @@ typedef struct _Config_DisplayConfig {
|
||||
bool compass_north_top;
|
||||
bool flip_screen;
|
||||
Config_DisplayConfig_DisplayUnits units;
|
||||
Config_DisplayConfig_OledType oled;
|
||||
} Config_DisplayConfig;
|
||||
|
||||
typedef struct _Config_LoRaConfig {
|
||||
@@ -189,10 +190,6 @@ typedef struct _Config {
|
||||
#define _Config_PositionConfig_PositionFlags_MAX Config_PositionConfig_PositionFlags_SPEED
|
||||
#define _Config_PositionConfig_PositionFlags_ARRAYSIZE ((Config_PositionConfig_PositionFlags)(Config_PositionConfig_PositionFlags_SPEED+1))
|
||||
|
||||
#define _Config_NetworkConfig_WiFiMode_MIN Config_NetworkConfig_WiFiMode_CLIENT
|
||||
#define _Config_NetworkConfig_WiFiMode_MAX Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN
|
||||
#define _Config_NetworkConfig_WiFiMode_ARRAYSIZE ((Config_NetworkConfig_WiFiMode)(Config_NetworkConfig_WiFiMode_ACCESS_POINT_HIDDEN+1))
|
||||
|
||||
#define _Config_NetworkConfig_EthMode_MIN Config_NetworkConfig_EthMode_DHCP
|
||||
#define _Config_NetworkConfig_EthMode_MAX Config_NetworkConfig_EthMode_STATIC
|
||||
#define _Config_NetworkConfig_EthMode_ARRAYSIZE ((Config_NetworkConfig_EthMode)(Config_NetworkConfig_EthMode_STATIC+1))
|
||||
@@ -205,6 +202,10 @@ typedef struct _Config {
|
||||
#define _Config_DisplayConfig_DisplayUnits_MAX Config_DisplayConfig_DisplayUnits_IMPERIAL
|
||||
#define _Config_DisplayConfig_DisplayUnits_ARRAYSIZE ((Config_DisplayConfig_DisplayUnits)(Config_DisplayConfig_DisplayUnits_IMPERIAL+1))
|
||||
|
||||
#define _Config_DisplayConfig_OledType_MIN Config_DisplayConfig_OledType_OLED_AUTO
|
||||
#define _Config_DisplayConfig_OledType_MAX Config_DisplayConfig_OledType_OLED_SH1106
|
||||
#define _Config_DisplayConfig_OledType_ARRAYSIZE ((Config_DisplayConfig_OledType)(Config_DisplayConfig_OledType_OLED_SH1106+1))
|
||||
|
||||
#define _Config_LoRaConfig_RegionCode_MIN Config_LoRaConfig_RegionCode_UNSET
|
||||
#define _Config_LoRaConfig_RegionCode_MAX Config_LoRaConfig_RegionCode_LORA_24
|
||||
#define _Config_LoRaConfig_RegionCode_ARRAYSIZE ((Config_LoRaConfig_RegionCode)(Config_LoRaConfig_RegionCode_LORA_24+1))
|
||||
@@ -229,7 +230,7 @@ extern "C" {
|
||||
#define Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define Config_NetworkConfig_init_default {0, "", "", "", 0, _Config_NetworkConfig_EthMode_MIN, false, Config_NetworkConfig_IpV4Config_init_default}
|
||||
#define Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0}
|
||||
#define Config_DisplayConfig_init_default {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _Config_DisplayConfig_DisplayUnits_MIN}
|
||||
#define Config_DisplayConfig_init_default {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _Config_DisplayConfig_DisplayUnits_MIN, _Config_DisplayConfig_OledType_MIN}
|
||||
#define Config_LoRaConfig_init_default {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, {0, 0, 0}}
|
||||
#define Config_BluetoothConfig_init_default {0, _Config_BluetoothConfig_PairingMode_MIN, 0}
|
||||
#define Config_init_zero {0, {Config_DeviceConfig_init_zero}}
|
||||
@@ -238,7 +239,7 @@ extern "C" {
|
||||
#define Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define Config_NetworkConfig_init_zero {0, "", "", "", 0, _Config_NetworkConfig_EthMode_MIN, false, Config_NetworkConfig_IpV4Config_init_zero}
|
||||
#define Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0}
|
||||
#define Config_DisplayConfig_init_zero {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _Config_DisplayConfig_DisplayUnits_MIN}
|
||||
#define Config_DisplayConfig_init_zero {0, _Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _Config_DisplayConfig_DisplayUnits_MIN, _Config_DisplayConfig_OledType_MIN}
|
||||
#define Config_LoRaConfig_init_zero {0, _Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, {0, 0, 0}}
|
||||
#define Config_BluetoothConfig_init_zero {0, _Config_BluetoothConfig_PairingMode_MIN, 0}
|
||||
|
||||
@@ -255,6 +256,7 @@ extern "C" {
|
||||
#define Config_DisplayConfig_compass_north_top_tag 4
|
||||
#define Config_DisplayConfig_flip_screen_tag 5
|
||||
#define Config_DisplayConfig_units_tag 6
|
||||
#define Config_DisplayConfig_oled_tag 7
|
||||
#define Config_LoRaConfig_use_preset_tag 1
|
||||
#define Config_LoRaConfig_modem_preset_tag 2
|
||||
#define Config_LoRaConfig_bandwidth_tag 3
|
||||
@@ -376,7 +378,8 @@ X(a, STATIC, SINGULAR, UENUM, gps_format, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT32, auto_screen_carousel_secs, 3) \
|
||||
X(a, STATIC, SINGULAR, BOOL, compass_north_top, 4) \
|
||||
X(a, STATIC, SINGULAR, BOOL, flip_screen, 5) \
|
||||
X(a, STATIC, SINGULAR, UENUM, units, 6)
|
||||
X(a, STATIC, SINGULAR, UENUM, units, 6) \
|
||||
X(a, STATIC, SINGULAR, UENUM, oled, 7)
|
||||
#define Config_DisplayConfig_CALLBACK NULL
|
||||
#define Config_DisplayConfig_DEFAULT NULL
|
||||
|
||||
@@ -427,7 +430,7 @@ extern const pb_msgdesc_t Config_BluetoothConfig_msg;
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define Config_BluetoothConfig_size 10
|
||||
#define Config_DeviceConfig_size 6
|
||||
#define Config_DisplayConfig_size 20
|
||||
#define Config_DisplayConfig_size 22
|
||||
#define Config_LoRaConfig_size 68
|
||||
#define Config_NetworkConfig_IpV4Config_size 20
|
||||
#define Config_NetworkConfig_size 161
|
||||
|
||||
@@ -66,6 +66,9 @@ typedef struct _LocalModuleConfig {
|
||||
incompatible changes This integer is set at build time and is private to
|
||||
NodeDB.cpp in the device code. */
|
||||
uint32_t version;
|
||||
/* The part of the config that is specific to the Audio module */
|
||||
bool has_audio;
|
||||
ModuleConfig_AudioConfig audio;
|
||||
} LocalModuleConfig;
|
||||
|
||||
|
||||
@@ -75,9 +78,9 @@ extern "C" {
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define LocalConfig_init_default {false, Config_DeviceConfig_init_default, false, Config_PositionConfig_init_default, false, Config_PowerConfig_init_default, false, Config_NetworkConfig_init_default, false, Config_DisplayConfig_init_default, false, Config_LoRaConfig_init_default, false, Config_BluetoothConfig_init_default, 0}
|
||||
#define LocalModuleConfig_init_default {false, ModuleConfig_MQTTConfig_init_default, false, ModuleConfig_SerialConfig_init_default, false, ModuleConfig_ExternalNotificationConfig_init_default, false, ModuleConfig_StoreForwardConfig_init_default, false, ModuleConfig_RangeTestConfig_init_default, false, ModuleConfig_TelemetryConfig_init_default, false, ModuleConfig_CannedMessageConfig_init_default, 0}
|
||||
#define LocalModuleConfig_init_default {false, ModuleConfig_MQTTConfig_init_default, false, ModuleConfig_SerialConfig_init_default, false, ModuleConfig_ExternalNotificationConfig_init_default, false, ModuleConfig_StoreForwardConfig_init_default, false, ModuleConfig_RangeTestConfig_init_default, false, ModuleConfig_TelemetryConfig_init_default, false, ModuleConfig_CannedMessageConfig_init_default, 0, false, ModuleConfig_AudioConfig_init_default}
|
||||
#define LocalConfig_init_zero {false, Config_DeviceConfig_init_zero, false, Config_PositionConfig_init_zero, false, Config_PowerConfig_init_zero, false, Config_NetworkConfig_init_zero, false, Config_DisplayConfig_init_zero, false, Config_LoRaConfig_init_zero, false, Config_BluetoothConfig_init_zero, 0}
|
||||
#define LocalModuleConfig_init_zero {false, ModuleConfig_MQTTConfig_init_zero, false, ModuleConfig_SerialConfig_init_zero, false, ModuleConfig_ExternalNotificationConfig_init_zero, false, ModuleConfig_StoreForwardConfig_init_zero, false, ModuleConfig_RangeTestConfig_init_zero, false, ModuleConfig_TelemetryConfig_init_zero, false, ModuleConfig_CannedMessageConfig_init_zero, 0}
|
||||
#define LocalModuleConfig_init_zero {false, ModuleConfig_MQTTConfig_init_zero, false, ModuleConfig_SerialConfig_init_zero, false, ModuleConfig_ExternalNotificationConfig_init_zero, false, ModuleConfig_StoreForwardConfig_init_zero, false, ModuleConfig_RangeTestConfig_init_zero, false, ModuleConfig_TelemetryConfig_init_zero, false, ModuleConfig_CannedMessageConfig_init_zero, 0, false, ModuleConfig_AudioConfig_init_zero}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define LocalConfig_device_tag 1
|
||||
@@ -96,6 +99,7 @@ extern "C" {
|
||||
#define LocalModuleConfig_telemetry_tag 6
|
||||
#define LocalModuleConfig_canned_message_tag 7
|
||||
#define LocalModuleConfig_version_tag 8
|
||||
#define LocalModuleConfig_audio_tag 9
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define LocalConfig_FIELDLIST(X, a) \
|
||||
@@ -125,7 +129,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, store_forward, 4) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, range_test, 5) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, telemetry, 6) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, canned_message, 7) \
|
||||
X(a, STATIC, SINGULAR, UINT32, version, 8)
|
||||
X(a, STATIC, SINGULAR, UINT32, version, 8) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, audio, 9)
|
||||
#define LocalModuleConfig_CALLBACK NULL
|
||||
#define LocalModuleConfig_DEFAULT NULL
|
||||
#define LocalModuleConfig_mqtt_MSGTYPE ModuleConfig_MQTTConfig
|
||||
@@ -135,6 +140,7 @@ X(a, STATIC, SINGULAR, UINT32, version, 8)
|
||||
#define LocalModuleConfig_range_test_MSGTYPE ModuleConfig_RangeTestConfig
|
||||
#define LocalModuleConfig_telemetry_MSGTYPE ModuleConfig_TelemetryConfig
|
||||
#define LocalModuleConfig_canned_message_MSGTYPE ModuleConfig_CannedMessageConfig
|
||||
#define LocalModuleConfig_audio_MSGTYPE ModuleConfig_AudioConfig
|
||||
|
||||
extern const pb_msgdesc_t LocalConfig_msg;
|
||||
extern const pb_msgdesc_t LocalModuleConfig_msg;
|
||||
@@ -144,8 +150,8 @@ extern const pb_msgdesc_t LocalModuleConfig_msg;
|
||||
#define LocalModuleConfig_fields &LocalModuleConfig_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define LocalConfig_size 359
|
||||
#define LocalModuleConfig_size 270
|
||||
#define LocalConfig_size 361
|
||||
#define LocalModuleConfig_size 294
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -52,6 +52,8 @@ typedef enum _HardwareModel {
|
||||
HardwareModel_RAK11200 = 13,
|
||||
/* B&Q Consulting Nano Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:nano */
|
||||
HardwareModel_NANO_G1 = 14,
|
||||
/* TODO: REPLACE */
|
||||
HardwareModel_TLORA_V2_1_1P8 = 15,
|
||||
/* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */
|
||||
HardwareModel_STATION_G1 = 25,
|
||||
/* Less common/prototype boards listed here (needs one more byte over the air) */
|
||||
@@ -76,6 +78,10 @@ typedef enum _HardwareModel {
|
||||
HardwareModel_DR_DEV = 41,
|
||||
/* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/ */
|
||||
HardwareModel_M5STACK = 42,
|
||||
/* New Heltec LoRA32 with ESP32-S3 CPU */
|
||||
HardwareModel_HELTEC_V3 = 43,
|
||||
/* New Heltec Wireless Stick Lite with ESP32-S3 CPU */
|
||||
HardwareModel_HELTEC_WSL_V3 = 44,
|
||||
/* Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. */
|
||||
HardwareModel_PRIVATE_HW = 255
|
||||
} HardwareModel;
|
||||
@@ -499,7 +505,7 @@ typedef PB_BYTES_ARRAY_T(256) MeshPacket_encrypted_t;
|
||||
typedef struct _MeshPacket {
|
||||
/* The sending node number.
|
||||
Note: Our crypto implementation uses this field as well.
|
||||
See [crypto](/docs/developers/firmware/encryption) for details.
|
||||
See [crypto](/docs/overview/encryption) for details.
|
||||
FIXME - really should be fixed32 instead, this encoding only hurts the ble link though. */
|
||||
uint32_t from;
|
||||
/* The (immediatSee Priority description for more details.y should be fixed32 instead, this encoding only
|
||||
@@ -527,7 +533,7 @@ typedef struct _MeshPacket {
|
||||
needs to be unique for a few minutes (long enough to last for the length of
|
||||
any ACK or the completion of a mesh broadcast flood).
|
||||
Note: Our crypto implementation uses this id as well.
|
||||
See [crypto](/docs/developers/firmware/encryption) for details.
|
||||
See [crypto](/docs/overview/encryption) for details.
|
||||
FIXME - really should be fixed32 instead, this encoding only
|
||||
hurts the ble link though. */
|
||||
uint32_t id;
|
||||
|
||||
@@ -12,6 +12,9 @@ PB_BIND(ModuleConfig, ModuleConfig, AUTO)
|
||||
PB_BIND(ModuleConfig_MQTTConfig, ModuleConfig_MQTTConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(ModuleConfig_AudioConfig, ModuleConfig_AudioConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(ModuleConfig_SerialConfig, ModuleConfig_SerialConfig, AUTO)
|
||||
|
||||
|
||||
@@ -34,3 +37,4 @@ PB_BIND(ModuleConfig_CannedMessageConfig, ModuleConfig_CannedMessageConfig, AUTO
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,18 @@
|
||||
#endif
|
||||
|
||||
/* Enum definitions */
|
||||
typedef enum _ModuleConfig_AudioConfig_Audio_Baud {
|
||||
ModuleConfig_AudioConfig_Audio_Baud_CODEC2_DEFAULT = 0,
|
||||
ModuleConfig_AudioConfig_Audio_Baud_CODEC2_3200 = 1,
|
||||
ModuleConfig_AudioConfig_Audio_Baud_CODEC2_2400 = 2,
|
||||
ModuleConfig_AudioConfig_Audio_Baud_CODEC2_1600 = 3,
|
||||
ModuleConfig_AudioConfig_Audio_Baud_CODEC2_1400 = 4,
|
||||
ModuleConfig_AudioConfig_Audio_Baud_CODEC2_1300 = 5,
|
||||
ModuleConfig_AudioConfig_Audio_Baud_CODEC2_1200 = 6,
|
||||
ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700 = 7,
|
||||
ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700B = 8
|
||||
} ModuleConfig_AudioConfig_Audio_Baud;
|
||||
|
||||
typedef enum _ModuleConfig_SerialConfig_Serial_Baud {
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_DEFAULT = 0,
|
||||
ModuleConfig_SerialConfig_Serial_Baud_BAUD_110 = 1,
|
||||
@@ -49,6 +61,14 @@ typedef enum _ModuleConfig_CannedMessageConfig_InputEventChar {
|
||||
} ModuleConfig_CannedMessageConfig_InputEventChar;
|
||||
|
||||
/* Struct definitions */
|
||||
typedef struct _ModuleConfig_AudioConfig {
|
||||
bool codec2_enabled;
|
||||
uint32_t mic_chan;
|
||||
uint32_t amp_pin;
|
||||
uint32_t ptt_pin;
|
||||
ModuleConfig_AudioConfig_Audio_Baud bitrate;
|
||||
} ModuleConfig_AudioConfig;
|
||||
|
||||
typedef struct _ModuleConfig_CannedMessageConfig {
|
||||
bool rotary1_enabled;
|
||||
uint32_t inputbroker_pin_a;
|
||||
@@ -131,11 +151,17 @@ typedef struct _ModuleConfig {
|
||||
ModuleConfig_TelemetryConfig telemetry;
|
||||
/* TODO: REPLACE */
|
||||
ModuleConfig_CannedMessageConfig canned_message;
|
||||
/* TODO: REPLACE */
|
||||
ModuleConfig_AudioConfig audio;
|
||||
} payload_variant;
|
||||
} ModuleConfig;
|
||||
|
||||
|
||||
/* Helper constants for enums */
|
||||
#define _ModuleConfig_AudioConfig_Audio_Baud_MIN ModuleConfig_AudioConfig_Audio_Baud_CODEC2_DEFAULT
|
||||
#define _ModuleConfig_AudioConfig_Audio_Baud_MAX ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700B
|
||||
#define _ModuleConfig_AudioConfig_Audio_Baud_ARRAYSIZE ((ModuleConfig_AudioConfig_Audio_Baud)(ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700B+1))
|
||||
|
||||
#define _ModuleConfig_SerialConfig_Serial_Baud_MIN ModuleConfig_SerialConfig_Serial_Baud_BAUD_DEFAULT
|
||||
#define _ModuleConfig_SerialConfig_Serial_Baud_MAX ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600
|
||||
#define _ModuleConfig_SerialConfig_Serial_Baud_ARRAYSIZE ((ModuleConfig_SerialConfig_Serial_Baud)(ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600+1))
|
||||
@@ -156,6 +182,7 @@ extern "C" {
|
||||
/* Initializer values for message structs */
|
||||
#define ModuleConfig_init_default {0, {ModuleConfig_MQTTConfig_init_default}}
|
||||
#define ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0}
|
||||
#define ModuleConfig_AudioConfig_init_default {0, 0, 0, 0, _ModuleConfig_AudioConfig_Audio_Baud_MIN}
|
||||
#define ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _ModuleConfig_SerialConfig_Serial_Mode_MIN}
|
||||
#define ModuleConfig_ExternalNotificationConfig_init_default {0, 0, 0, 0, 0, 0}
|
||||
#define ModuleConfig_StoreForwardConfig_init_default {0, 0, 0, 0, 0}
|
||||
@@ -164,6 +191,7 @@ extern "C" {
|
||||
#define ModuleConfig_CannedMessageConfig_init_default {0, 0, 0, 0, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
|
||||
#define ModuleConfig_init_zero {0, {ModuleConfig_MQTTConfig_init_zero}}
|
||||
#define ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0}
|
||||
#define ModuleConfig_AudioConfig_init_zero {0, 0, 0, 0, _ModuleConfig_AudioConfig_Audio_Baud_MIN}
|
||||
#define ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _ModuleConfig_SerialConfig_Serial_Mode_MIN}
|
||||
#define ModuleConfig_ExternalNotificationConfig_init_zero {0, 0, 0, 0, 0, 0}
|
||||
#define ModuleConfig_StoreForwardConfig_init_zero {0, 0, 0, 0, 0}
|
||||
@@ -172,6 +200,11 @@ extern "C" {
|
||||
#define ModuleConfig_CannedMessageConfig_init_zero {0, 0, 0, 0, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define ModuleConfig_AudioConfig_codec2_enabled_tag 1
|
||||
#define ModuleConfig_AudioConfig_mic_chan_tag 2
|
||||
#define ModuleConfig_AudioConfig_amp_pin_tag 3
|
||||
#define ModuleConfig_AudioConfig_ptt_pin_tag 4
|
||||
#define ModuleConfig_AudioConfig_bitrate_tag 5
|
||||
#define ModuleConfig_CannedMessageConfig_rotary1_enabled_tag 1
|
||||
#define ModuleConfig_CannedMessageConfig_inputbroker_pin_a_tag 2
|
||||
#define ModuleConfig_CannedMessageConfig_inputbroker_pin_b_tag 3
|
||||
@@ -222,6 +255,7 @@ extern "C" {
|
||||
#define ModuleConfig_range_test_tag 5
|
||||
#define ModuleConfig_telemetry_tag 6
|
||||
#define ModuleConfig_canned_message_tag 7
|
||||
#define ModuleConfig_audio_tag 8
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define ModuleConfig_FIELDLIST(X, a) \
|
||||
@@ -231,7 +265,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,external_notification,payloa
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,store_forward,payload_variant.store_forward), 4) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,range_test,payload_variant.range_test), 5) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,telemetry,payload_variant.telemetry), 6) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,canned_message,payload_variant.canned_message), 7)
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,canned_message,payload_variant.canned_message), 7) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,audio,payload_variant.audio), 8)
|
||||
#define ModuleConfig_CALLBACK NULL
|
||||
#define ModuleConfig_DEFAULT NULL
|
||||
#define ModuleConfig_payload_variant_mqtt_MSGTYPE ModuleConfig_MQTTConfig
|
||||
@@ -241,6 +276,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,canned_message,payload_varia
|
||||
#define ModuleConfig_payload_variant_range_test_MSGTYPE ModuleConfig_RangeTestConfig
|
||||
#define ModuleConfig_payload_variant_telemetry_MSGTYPE ModuleConfig_TelemetryConfig
|
||||
#define ModuleConfig_payload_variant_canned_message_MSGTYPE ModuleConfig_CannedMessageConfig
|
||||
#define ModuleConfig_payload_variant_audio_MSGTYPE ModuleConfig_AudioConfig
|
||||
|
||||
#define ModuleConfig_MQTTConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
|
||||
@@ -252,6 +288,15 @@ X(a, STATIC, SINGULAR, BOOL, json_enabled, 6)
|
||||
#define ModuleConfig_MQTTConfig_CALLBACK NULL
|
||||
#define ModuleConfig_MQTTConfig_DEFAULT NULL
|
||||
|
||||
#define ModuleConfig_AudioConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, BOOL, codec2_enabled, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, mic_chan, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT32, amp_pin, 3) \
|
||||
X(a, STATIC, SINGULAR, UINT32, ptt_pin, 4) \
|
||||
X(a, STATIC, SINGULAR, UENUM, bitrate, 5)
|
||||
#define ModuleConfig_AudioConfig_CALLBACK NULL
|
||||
#define ModuleConfig_AudioConfig_DEFAULT NULL
|
||||
|
||||
#define ModuleConfig_SerialConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
|
||||
X(a, STATIC, SINGULAR, BOOL, echo, 2) \
|
||||
@@ -315,6 +360,7 @@ X(a, STATIC, SINGULAR, BOOL, send_bell, 11)
|
||||
|
||||
extern const pb_msgdesc_t ModuleConfig_msg;
|
||||
extern const pb_msgdesc_t ModuleConfig_MQTTConfig_msg;
|
||||
extern const pb_msgdesc_t ModuleConfig_AudioConfig_msg;
|
||||
extern const pb_msgdesc_t ModuleConfig_SerialConfig_msg;
|
||||
extern const pb_msgdesc_t ModuleConfig_ExternalNotificationConfig_msg;
|
||||
extern const pb_msgdesc_t ModuleConfig_StoreForwardConfig_msg;
|
||||
@@ -325,6 +371,7 @@ extern const pb_msgdesc_t ModuleConfig_CannedMessageConfig_msg;
|
||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||
#define ModuleConfig_fields &ModuleConfig_msg
|
||||
#define ModuleConfig_MQTTConfig_fields &ModuleConfig_MQTTConfig_msg
|
||||
#define ModuleConfig_AudioConfig_fields &ModuleConfig_AudioConfig_msg
|
||||
#define ModuleConfig_SerialConfig_fields &ModuleConfig_SerialConfig_msg
|
||||
#define ModuleConfig_ExternalNotificationConfig_fields &ModuleConfig_ExternalNotificationConfig_msg
|
||||
#define ModuleConfig_StoreForwardConfig_fields &ModuleConfig_StoreForwardConfig_msg
|
||||
@@ -333,6 +380,7 @@ extern const pb_msgdesc_t ModuleConfig_CannedMessageConfig_msg;
|
||||
#define ModuleConfig_CannedMessageConfig_fields &ModuleConfig_CannedMessageConfig_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define ModuleConfig_AudioConfig_size 22
|
||||
#define ModuleConfig_CannedMessageConfig_size 49
|
||||
#define ModuleConfig_ExternalNotificationConfig_size 20
|
||||
#define ModuleConfig_MQTTConfig_size 105
|
||||
|
||||
@@ -51,6 +51,9 @@ typedef enum _PortNum {
|
||||
/* Waypoint payloads.
|
||||
Payload is a [Waypoint](/docs/developers/protobufs/api#waypoint) message */
|
||||
PortNum_WAYPOINT_APP = 8,
|
||||
/* Audio Payloads.
|
||||
Encapsulated codec2 packets. On 2.4 GHZ Bandwidths only for now */
|
||||
PortNum_AUDIO_APP = 9,
|
||||
/* Provides a 'ping' service that replies to any packet it receives.
|
||||
Also serves as a small example module. */
|
||||
PortNum_REPLY_APP = 32,
|
||||
|
||||
@@ -33,7 +33,9 @@ typedef enum _TelemetrySensorType {
|
||||
/* 3-Axis magnetic sensor */
|
||||
TelemetrySensorType_QMC6310 = 9,
|
||||
/* 6-Axis inertial measurement sensor */
|
||||
TelemetrySensorType_QMI8658 = 10
|
||||
TelemetrySensorType_QMI8658 = 10,
|
||||
/* 3-Axis magnetic sensor */
|
||||
TelemetrySensorType_QMC5883L = 11
|
||||
} TelemetrySensorType;
|
||||
|
||||
/* Struct definitions */
|
||||
@@ -85,8 +87,8 @@ typedef struct _Telemetry {
|
||||
|
||||
/* Helper constants for enums */
|
||||
#define _TelemetrySensorType_MIN TelemetrySensorType_SENSOR_UNSET
|
||||
#define _TelemetrySensorType_MAX TelemetrySensorType_QMI8658
|
||||
#define _TelemetrySensorType_ARRAYSIZE ((TelemetrySensorType)(TelemetrySensorType_QMI8658+1))
|
||||
#define _TelemetrySensorType_MAX TelemetrySensorType_QMC5883L
|
||||
#define _TelemetrySensorType_ARRAYSIZE ((TelemetrySensorType)(TelemetrySensorType_QMC5883L+1))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -35,32 +35,34 @@ char ourHost[16];
|
||||
|
||||
bool APStartupComplete = 0;
|
||||
|
||||
unsigned long lastrun_ntp = 0;
|
||||
|
||||
static bool needReconnect = true; // If we create our reconnector, run it once at the beginning
|
||||
|
||||
static Periodic *wifiReconnect;
|
||||
|
||||
static int32_t reconnectWiFi()
|
||||
{
|
||||
const char *wifiName = config.network.wifi_ssid;
|
||||
const char *wifiPsw = config.network.wifi_psk;
|
||||
|
||||
if (config.network.wifi_enabled && needReconnect && !WiFi.isConnected()) {
|
||||
if (config.network.wifi_enabled && needReconnect) {
|
||||
|
||||
if (!*wifiPsw) // Treat empty password as no password
|
||||
wifiPsw = NULL;
|
||||
|
||||
if (*wifiName) {
|
||||
needReconnect = false;
|
||||
needReconnect = false;
|
||||
|
||||
// Make sure we clear old connection credentials
|
||||
WiFi.disconnect(false, true);
|
||||
// Make sure we clear old connection credentials
|
||||
WiFi.disconnect(false, true);
|
||||
|
||||
DEBUG_MSG("... Reconnecting to WiFi access point\n");
|
||||
WiFi.mode(WIFI_MODE_STA);
|
||||
WiFi.begin(wifiName, wifiPsw);
|
||||
}
|
||||
DEBUG_MSG("... Reconnecting to WiFi access point\n");
|
||||
WiFi.mode(WIFI_MODE_STA);
|
||||
WiFi.begin(wifiName, wifiPsw);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_NTP
|
||||
if (WiFi.isConnected()) {
|
||||
if (WiFi.isConnected() && ((millis() - lastrun_ntp) > 43200000)) { // every 12 hours
|
||||
DEBUG_MSG("Updating NTP time\n");
|
||||
if (timeClient.update()) {
|
||||
DEBUG_MSG("NTP Request Success - Setting RTCQualityNTP if needed\n");
|
||||
@@ -70,6 +72,7 @@ static int32_t reconnectWiFi()
|
||||
tv.tv_usec = 0;
|
||||
|
||||
perhapsSetRTC(RTCQualityNTP, &tv);
|
||||
lastrun_ntp = millis();
|
||||
|
||||
} else {
|
||||
DEBUG_MSG("NTP Update failed\n");
|
||||
@@ -77,11 +80,13 @@ static int32_t reconnectWiFi()
|
||||
}
|
||||
#endif
|
||||
|
||||
return 43200 * 1000; // every 12 hours
|
||||
if (config.network.wifi_enabled && !WiFi.isConnected()) {
|
||||
return 1000; // check once per second
|
||||
} else {
|
||||
return 300000; // every 5 minutes
|
||||
}
|
||||
}
|
||||
|
||||
static Periodic *wifiReconnect;
|
||||
|
||||
bool isWifiAvailable()
|
||||
{
|
||||
|
||||
@@ -95,20 +100,10 @@ bool isWifiAvailable()
|
||||
// Disable WiFi
|
||||
void deinitWifi()
|
||||
{
|
||||
/*
|
||||
Note from Jm (jm@casler.org - Sept 16, 2020):
|
||||
|
||||
A bug in the ESP32 SDK was introduced in Oct 2019 that keeps the WiFi radio from
|
||||
turning back on after it's shut off. See:
|
||||
https://github.com/espressif/arduino-esp32/issues/3522
|
||||
|
||||
Until then, WiFi should only be allowed when there's no power
|
||||
saving on the 2.4g transceiver.
|
||||
*/
|
||||
|
||||
DEBUG_MSG("WiFi deinit\n");
|
||||
|
||||
if (isWifiAvailable()) {
|
||||
WiFi.disconnect(true);
|
||||
WiFi.mode(WIFI_MODE_NULL);
|
||||
DEBUG_MSG("WiFi Turned Off\n");
|
||||
// WiFi.printDiag(Serial);
|
||||
@@ -169,6 +164,15 @@ bool initWifi()
|
||||
WiFi.mode(WIFI_MODE_STA);
|
||||
WiFi.setHostname(ourHost);
|
||||
WiFi.onEvent(WiFiEvent);
|
||||
WiFi.setAutoReconnect(false);
|
||||
WiFi.setSleep(false);
|
||||
if (config.network.eth_mode == Config_NetworkConfig_EthMode_STATIC && config.network.ipv4_config.ip != 0) {
|
||||
WiFi.config(config.network.ipv4_config.ip,
|
||||
config.network.ipv4_config.gateway,
|
||||
config.network.ipv4_config.subnet,
|
||||
config.network.ipv4_config.dns,
|
||||
config.network.ipv4_config.dns); // Wifi wants two DNS servers... set both to the same value
|
||||
}
|
||||
|
||||
// This is needed to improve performance.
|
||||
esp_wifi_set_ps(WIFI_PS_NONE); // Disable radio power saving
|
||||
@@ -222,9 +226,9 @@ static void WiFiEvent(WiFiEvent_t event)
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_DISCONNECTED:
|
||||
DEBUG_MSG("Disconnected from WiFi access point\n");
|
||||
// Event 5
|
||||
|
||||
WiFi.disconnect(false, true);
|
||||
needReconnect = true;
|
||||
wifiReconnect->setIntervalFromNow(1000);
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:
|
||||
DEBUG_MSG("Authentication mode of access point has changed\n");
|
||||
@@ -236,6 +240,9 @@ static void WiFiEvent(WiFiEvent_t event)
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_LOST_IP:
|
||||
DEBUG_MSG("Lost IP address and IP address is reset to 0\n");
|
||||
WiFi.disconnect(false, true);
|
||||
needReconnect = true;
|
||||
wifiReconnect->setIntervalFromNow(1000);
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_WPS_ER_SUCCESS:
|
||||
DEBUG_MSG("WiFi Protected Setup (WPS): succeeded in enrollee mode\n");
|
||||
@@ -251,8 +258,6 @@ static void WiFiEvent(WiFiEvent_t event)
|
||||
break;
|
||||
case SYSTEM_EVENT_AP_START:
|
||||
DEBUG_MSG("WiFi access point started\n");
|
||||
|
||||
onNetworkConnected();
|
||||
break;
|
||||
case SYSTEM_EVENT_AP_STOP:
|
||||
DEBUG_MSG("WiFi access point stopped\n");
|
||||
|
||||
@@ -13,7 +13,10 @@
|
||||
#include "unistd.h"
|
||||
#endif
|
||||
|
||||
#define DEFAULT_REBOOT_SECONDS 5
|
||||
|
||||
AdminModule *adminModule;
|
||||
bool hasOpenEditTransaction;
|
||||
|
||||
/// A special reserved string to indicate strings we can not share with external nodes. We will use this 'reserved' word instead.
|
||||
/// Also, to make setting work correctly, if someone tries to set a string to this reserved value we assume they don't really want
|
||||
@@ -133,13 +136,23 @@ bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
|
||||
case AdminMessage_factory_reset_tag: {
|
||||
DEBUG_MSG("Initiating factory reset\n");
|
||||
nodeDB.factoryReset();
|
||||
reboot(5);
|
||||
reboot(DEFAULT_REBOOT_SECONDS);
|
||||
break;
|
||||
}
|
||||
case AdminMessage_nodedb_reset_tag: {
|
||||
} case AdminMessage_nodedb_reset_tag: {
|
||||
DEBUG_MSG("Initiating node-db reset\n");
|
||||
nodeDB.resetNodes();
|
||||
reboot(5);
|
||||
reboot(DEFAULT_REBOOT_SECONDS);
|
||||
break;
|
||||
}
|
||||
case AdminMessage_begin_edit_settings_tag: {
|
||||
DEBUG_MSG("Beginning transaction for editing settings\n");
|
||||
hasOpenEditTransaction = true;
|
||||
break;
|
||||
}
|
||||
case AdminMessage_commit_edit_settings_tag: {
|
||||
DEBUG_MSG("Committing transaction for edited settings\n");
|
||||
hasOpenEditTransaction = false;
|
||||
saveChanges(SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
|
||||
break;
|
||||
}
|
||||
#ifdef ARCH_PORTDUINO
|
||||
@@ -192,9 +205,8 @@ void AdminModule::handleSetOwner(const User &o)
|
||||
}
|
||||
|
||||
if (changed) { // If nothing really changed, don't broadcast on the network or write to flash
|
||||
service.reloadOwner();
|
||||
DEBUG_MSG("Rebooting due to owner changes\n");
|
||||
reboot(5);
|
||||
service.reloadOwner(!hasOpenEditTransaction);
|
||||
saveChanges(SEGMENT_DEVICESTATE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,7 +232,7 @@ void AdminModule::handleSetConfig(const Config &c)
|
||||
config.has_position = true;
|
||||
config.position = c.payload_variant.position;
|
||||
// Save nodedb as well in case we got a fixed position packet
|
||||
nodeDB.saveToDisk(SEGMENT_DEVICESTATE);
|
||||
saveChanges(SEGMENT_DEVICESTATE, false);
|
||||
break;
|
||||
case Config_power_tag:
|
||||
DEBUG_MSG("Setting config: Power\n");
|
||||
@@ -252,9 +264,8 @@ void AdminModule::handleSetConfig(const Config &c)
|
||||
config.bluetooth = c.payload_variant.bluetooth;
|
||||
break;
|
||||
}
|
||||
|
||||
service.reloadConfig(SEGMENT_CONFIG);
|
||||
reboot(5);
|
||||
|
||||
saveChanges(SEGMENT_CONFIG);
|
||||
}
|
||||
|
||||
void AdminModule::handleSetModuleConfig(const ModuleConfig &c)
|
||||
@@ -295,17 +306,21 @@ void AdminModule::handleSetModuleConfig(const ModuleConfig &c)
|
||||
moduleConfig.has_canned_message = true;
|
||||
moduleConfig.canned_message = c.payload_variant.canned_message;
|
||||
break;
|
||||
case ModuleConfig_audio_tag:
|
||||
DEBUG_MSG("Setting module config: Audio\n");
|
||||
moduleConfig.has_audio = true;
|
||||
moduleConfig.audio = c.payload_variant.audio;
|
||||
break;
|
||||
}
|
||||
|
||||
service.reloadConfig(SEGMENT_MODULECONFIG);
|
||||
reboot(5);
|
||||
saveChanges(SEGMENT_MODULECONFIG);
|
||||
}
|
||||
|
||||
void AdminModule::handleSetChannel(const Channel &cc)
|
||||
{
|
||||
channels.setChannel(cc);
|
||||
channels.onConfigChanged(); // tell the radios about this change
|
||||
nodeDB.saveChannelsToDisk();
|
||||
saveChanges(SEGMENT_CHANNELS, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -421,6 +436,11 @@ void AdminModule::handleGetModuleConfig(const MeshPacket &req, const uint32_t co
|
||||
res.get_module_config_response.which_payload_variant = ModuleConfig_canned_message_tag;
|
||||
res.get_module_config_response.payload_variant.canned_message = moduleConfig.canned_message;
|
||||
break;
|
||||
case AdminMessage_ModuleConfigType_AUDIO_CONFIG:
|
||||
DEBUG_MSG("Getting module config: Audio\n");
|
||||
res.get_module_config_response.which_payload_variant = ModuleConfig_audio_tag;
|
||||
res.get_module_config_response.payload_variant.audio = moduleConfig.audio;
|
||||
break;
|
||||
}
|
||||
|
||||
// NOTE: The phone app needs to know the ls_secsvalue so it can properly expect sleep behavior.
|
||||
@@ -469,6 +489,20 @@ void AdminModule::reboot(int32_t seconds)
|
||||
rebootAtMsec = (seconds < 0) ? 0 : (millis() + seconds * 1000);
|
||||
}
|
||||
|
||||
void AdminModule::saveChanges(int saveWhat, bool shouldReboot)
|
||||
{
|
||||
if (!hasOpenEditTransaction) {
|
||||
DEBUG_MSG("Saving changes to disk\n");
|
||||
service.reloadConfig(saveWhat); // Calls saveToDisk among other things
|
||||
} else {
|
||||
DEBUG_MSG("Delaying save of changes to disk until the open transaction is committed\n");
|
||||
}
|
||||
if (shouldReboot)
|
||||
{
|
||||
reboot(DEFAULT_REBOOT_SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
AdminModule::AdminModule() : ProtobufModule("Admin", PortNum_ADMIN_APP, AdminMessage_fields)
|
||||
{
|
||||
// restrict to the admin channel for rx
|
||||
|
||||
@@ -20,6 +20,9 @@ class AdminModule : public ProtobufModule<AdminMessage>
|
||||
virtual bool handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *p) override;
|
||||
|
||||
private:
|
||||
bool hasOpenEditTransaction = false;
|
||||
|
||||
void saveChanges(int saveWhat, bool shouldReboot = true);
|
||||
/**
|
||||
* Getters
|
||||
*/
|
||||
|
||||
@@ -176,7 +176,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
||||
DEBUG_MSG("Canned message event Matrix key pressed\n");
|
||||
// this will send the text immediately on matrix press
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_SELECT;
|
||||
this->payload = event->kbchar;
|
||||
this->payload = MATRIXKEY;
|
||||
this->currentMessageIndex = event->kbchar -1;
|
||||
this->lastTouchMillis = millis();
|
||||
validEvent = true;
|
||||
@@ -246,7 +246,12 @@ int32_t CannedMessageModule::runOnce()
|
||||
}
|
||||
} else {
|
||||
if ((this->messagesCount > this->currentMessageIndex) && (strlen(this->messages[this->currentMessageIndex]) > 0)) {
|
||||
sendText(NODENUM_BROADCAST, this->messages[this->currentMessageIndex], true);
|
||||
if(strcmp (this->messages[this->currentMessageIndex], "~") == 0) {
|
||||
powerFSM.trigger(EVENT_PRESS);
|
||||
return INT32_MAX;
|
||||
} else {
|
||||
sendText(NODENUM_BROADCAST, this->messages[this->currentMessageIndex], true);
|
||||
}
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
|
||||
} else {
|
||||
DEBUG_MSG("Reset message is empty.\n");
|
||||
|
||||
@@ -116,9 +116,6 @@ ExternalNotificationModule::ExternalNotificationModule()
|
||||
: SinglePortModule("ExternalNotificationModule", PortNum_TEXT_MESSAGE_APP), concurrency::OSThread(
|
||||
"ExternalNotificationModule")
|
||||
{
|
||||
// restrict to the admin channel for rx
|
||||
boundChannel = Channels::gpioChannel;
|
||||
|
||||
/*
|
||||
Uncomment the preferences below if you want to use the module
|
||||
without having to configure it from the PythonAPI or WebUI.
|
||||
@@ -131,6 +128,11 @@ ExternalNotificationModule::ExternalNotificationModule()
|
||||
// moduleConfig.external_notification.alert_bell = 1;
|
||||
// moduleConfig.external_notification.output_ms = 1000;
|
||||
// moduleConfig.external_notification.output = 13;
|
||||
|
||||
if (moduleConfig.external_notification.alert_message) {
|
||||
// restrict to the gpio channel for rx
|
||||
boundChannel = Channels::gpioChannel;
|
||||
}
|
||||
|
||||
if (moduleConfig.external_notification.enabled) {
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
#ifdef ARCH_ESP32
|
||||
#include "modules/esp32/RangeTestModule.h"
|
||||
#include "modules/esp32/StoreForwardModule.h"
|
||||
#ifdef USE_SX1280
|
||||
#include "modules/esp32/AudioModule.h"
|
||||
#endif
|
||||
#endif
|
||||
#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
|
||||
#include "modules/ExternalNotificationModule.h"
|
||||
@@ -65,17 +68,16 @@ void setupModules()
|
||||
#endif
|
||||
#ifdef ARCH_ESP32
|
||||
// Only run on an esp32 based device.
|
||||
|
||||
/*
|
||||
Maintained by MC Hamster (Jm Casler) jm@casler.org
|
||||
*/
|
||||
#ifdef USE_SX1280
|
||||
new AudioModule();
|
||||
#endif
|
||||
new ExternalNotificationModule();
|
||||
|
||||
storeForwardModule = new StoreForwardModule();
|
||||
|
||||
new RangeTestModule();
|
||||
#elif defined(ARCH_NRF52)
|
||||
new ExternalNotificationModule();
|
||||
new ExternalNotificationModule();
|
||||
#endif
|
||||
|
||||
// NOTE! This module must be added LAST because it likes to check for replies from other modules and avoid sending extra acks
|
||||
|
||||
@@ -16,6 +16,14 @@ int32_t BME280Sensor::runOnce() {
|
||||
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||
}
|
||||
status = bme280.begin(nodeTelemetrySensorsMap[sensorType]);
|
||||
|
||||
bme280.setSampling( Adafruit_BME280::MODE_FORCED,
|
||||
Adafruit_BME280::SAMPLING_X1, // Temp. oversampling
|
||||
Adafruit_BME280::SAMPLING_X1, // Pressure oversampling
|
||||
Adafruit_BME280::SAMPLING_X1, // Humidity oversampling
|
||||
Adafruit_BME280::FILTER_OFF,
|
||||
Adafruit_BME280::STANDBY_MS_1000);
|
||||
|
||||
return initI2CSensor();
|
||||
}
|
||||
|
||||
@@ -23,6 +31,7 @@ void BME280Sensor::setup() { }
|
||||
|
||||
bool BME280Sensor::getMetrics(Telemetry *measurement) {
|
||||
DEBUG_MSG("BME280Sensor::getMetrics\n");
|
||||
bme280.takeForcedMeasurement();
|
||||
measurement->variant.environment_metrics.temperature = bme280.readTemperature();
|
||||
measurement->variant.environment_metrics.relative_humidity = bme280.readHumidity();
|
||||
measurement->variant.environment_metrics.barometric_pressure = bme280.readPressure() / 100.0F;
|
||||
|
||||
@@ -14,25 +14,19 @@ int32_t BME680Sensor::runOnce() {
|
||||
if (!hasSensor()) {
|
||||
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||
}
|
||||
status = bme680.begin(nodeTelemetrySensorsMap[sensorType]);
|
||||
status = bme680.begin(nodeTelemetrySensorsMap[sensorType]);
|
||||
|
||||
return initI2CSensor();
|
||||
}
|
||||
|
||||
void BME680Sensor::setup()
|
||||
{
|
||||
// Set up oversampling and filter initialization
|
||||
bme680.setTemperatureOversampling(BME680_OS_8X);
|
||||
bme680.setHumidityOversampling(BME680_OS_2X);
|
||||
bme680.setPressureOversampling(BME680_OS_4X);
|
||||
bme680.setIIRFilterSize(BME680_FILTER_SIZE_3);
|
||||
bme680.setGasHeater(320, 150); // 320*C for 150 ms
|
||||
}
|
||||
void BME680Sensor::setup() { }
|
||||
|
||||
bool BME680Sensor::getMetrics(Telemetry *measurement) {
|
||||
measurement->variant.environment_metrics.temperature = bme680.readTemperature();
|
||||
measurement->variant.environment_metrics.relative_humidity = bme680.readHumidity();
|
||||
measurement->variant.environment_metrics.barometric_pressure = bme680.readPressure() / 100.0F;
|
||||
measurement->variant.environment_metrics.gas_resistance = bme680.readGas() / 1000.0;
|
||||
bme680.performReading();
|
||||
measurement->variant.environment_metrics.temperature = bme680.temperature;
|
||||
measurement->variant.environment_metrics.relative_humidity = bme680.humidity;
|
||||
measurement->variant.environment_metrics.barometric_pressure = bme680.pressure / 100.0F;
|
||||
measurement->variant.environment_metrics.gas_resistance = bme680.gas_resistance / 1000.0;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -16,6 +16,13 @@ int32_t BMP280Sensor::runOnce() {
|
||||
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||
}
|
||||
status = bmp280.begin(nodeTelemetrySensorsMap[sensorType]);
|
||||
|
||||
bmp280.setSampling( Adafruit_BMP280::MODE_FORCED,
|
||||
Adafruit_BMP280::SAMPLING_X1, // Temp. oversampling
|
||||
Adafruit_BMP280::SAMPLING_X1, // Pressure oversampling
|
||||
Adafruit_BMP280::FILTER_OFF,
|
||||
Adafruit_BMP280::STANDBY_MS_1000);
|
||||
|
||||
return initI2CSensor();
|
||||
}
|
||||
|
||||
@@ -23,6 +30,7 @@ void BMP280Sensor::setup() { }
|
||||
|
||||
bool BMP280Sensor::getMetrics(Telemetry *measurement) {
|
||||
DEBUG_MSG("BMP280Sensor::getMetrics\n");
|
||||
bmp280.takeForcedMeasurement();
|
||||
measurement->variant.environment_metrics.temperature = bmp280.readTemperature();
|
||||
measurement->variant.environment_metrics.barometric_pressure = bmp280.readPressure() / 100.0F;
|
||||
|
||||
|
||||
241
src/modules/esp32/AudioModule.cpp
Normal file
241
src/modules/esp32/AudioModule.cpp
Normal file
@@ -0,0 +1,241 @@
|
||||
#include "configuration.h"
|
||||
#include "AudioModule.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "RTC.h"
|
||||
#include "Router.h"
|
||||
#include "FSCommon.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
AudioModule
|
||||
A interface to send raw codec2 audio data over the mesh network. Based on the example code from the ESP32_codec2 project.
|
||||
https://github.com/deulis/ESP32_Codec2
|
||||
|
||||
Codec 2 is a low-bitrate speech audio codec (speech coding)
|
||||
that is patent free and open source develop by David Grant Rowe.
|
||||
http://www.rowetel.com/ and https://github.com/drowe67/codec2
|
||||
|
||||
Basic Usage:
|
||||
1) Enable the module by setting audio.codec2_enabled to 1.
|
||||
2) Set the pins (audio.mic_pin / audio.amp_pin) for your preferred microphone and amplifier GPIO pins.
|
||||
On tbeam, recommend to use:
|
||||
audio.mic_chan 6 (GPIO 34)
|
||||
audio.amp_pin 14
|
||||
audio.ptt_pin 39
|
||||
3) Set audio.timeout to the amount of time to wait before we consider
|
||||
your voice stream as "done".
|
||||
4) Set audio.bitrate to the desired codec2 rate (CODEC2_3200, CODEC2_2400, CODEC2_1600, CODEC2_1400, CODEC2_1300, CODEC2_1200, CODEC2_700, CODEC2_700B)
|
||||
|
||||
KNOWN PROBLEMS
|
||||
* Until the module is initilized by the startup sequence, the amp_pin pin is in a floating
|
||||
state. This may produce a bit of "noise".
|
||||
* Will not work on NRF and the Linux device targets.
|
||||
*/
|
||||
|
||||
#define AMIC 6
|
||||
#define AAMP 14
|
||||
#define PTT_PIN 39
|
||||
|
||||
#define AUDIO_MODULE_RX_BUFFER 128
|
||||
#define AUDIO_MODULE_DATA_MAX Constants_DATA_PAYLOAD_LEN
|
||||
#define AUDIO_MODULE_MODE 7 // 700B
|
||||
#define AUDIO_MODULE_ACK 1
|
||||
|
||||
#if defined(ARCH_ESP32) && defined(USE_SX1280)
|
||||
|
||||
AudioModule *audioModule;
|
||||
|
||||
ButterworthFilter hp_filter(240, 8000, ButterworthFilter::ButterworthFilter::Highpass, 1);
|
||||
|
||||
//int16_t 1KHz sine test tone
|
||||
int16_t Sine1KHz[8] = { -21210 , -30000, -21210, 0 , 21210 , 30000 , 21210, 0 };
|
||||
int Sine1KHz_index = 0;
|
||||
|
||||
uint8_t rx_raw_audio_value = 127;
|
||||
|
||||
AudioModule::AudioModule() : SinglePortModule("AudioModule", PortNum_AUDIO_APP), concurrency::OSThread("AudioModule") {
|
||||
audio_fifo.init();
|
||||
}
|
||||
|
||||
void AudioModule::run_codec2()
|
||||
{
|
||||
if (state == State::tx)
|
||||
{
|
||||
for (int i = 0; i < ADC_BUFFER_SIZE; i++)
|
||||
speech[i] = (int16_t)hp_filter.Update((float)speech[i]);
|
||||
|
||||
codec2_encode(codec2_state, tx_encode_frame + tx_encode_frame_index, speech);
|
||||
|
||||
//increment the pointer where the encoded frame must be saved
|
||||
tx_encode_frame_index += 8;
|
||||
|
||||
//If it is the 5th time then we have a ready trasnmission frame
|
||||
if (tx_encode_frame_index == ENCODE_FRAME_SIZE)
|
||||
{
|
||||
tx_encode_frame_index = 0;
|
||||
//Transmit it
|
||||
sendPayload();
|
||||
}
|
||||
}
|
||||
if (state == State::rx) //Receiving
|
||||
{
|
||||
//Make a cycle to get each codec2 frame from the received frame
|
||||
for (int i = 0; i < ENCODE_FRAME_SIZE; i += 8)
|
||||
{
|
||||
//Decode the codec2 frame
|
||||
codec2_decode(codec2_state, output_buffer, rx_encode_frame + i);
|
||||
|
||||
// Add to the audio buffer the 320 samples resulting of the decode of the codec2 frame.
|
||||
for (int g = 0; g < ADC_BUFFER_SIZE; g++)
|
||||
audio_fifo.put(output_buffer[g]);
|
||||
}
|
||||
}
|
||||
state = State::standby;
|
||||
}
|
||||
|
||||
void AudioModule::handleInterrupt()
|
||||
{
|
||||
audioModule->onTimer();
|
||||
}
|
||||
|
||||
void AudioModule::onTimer()
|
||||
{
|
||||
if (state == State::tx) {
|
||||
adc_buffer[adc_buffer_index++] = (16 * adc1_get_raw(mic_chan)) - 32768;
|
||||
|
||||
//If you want to test with a 1KHz tone, comment the line above and descomment the three lines below
|
||||
|
||||
// adc_buffer[adc_buffer_index++] = Sine1KHz[Sine1KHz_index++];
|
||||
// if (Sine1KHz_index >= 8)
|
||||
// Sine1KHz_index = 0;
|
||||
|
||||
if (adc_buffer_index == ADC_BUFFER_SIZE) {
|
||||
adc_buffer_index = 0;
|
||||
memcpy((void*)speech, (void*)adc_buffer, 2 * ADC_BUFFER_SIZE);
|
||||
audioModule->setIntervalFromNow(0); // process buffer immediately
|
||||
}
|
||||
} else if (state == State::rx) {
|
||||
|
||||
int16_t v;
|
||||
|
||||
//Get a value from audio_fifo and convert it to 0 - 255 to play it in the ADC
|
||||
//If none value is available the DAC will play the last one that was read, that's
|
||||
//why the rx_raw_audio_value variable is a global one.
|
||||
if (audio_fifo.get(&v))
|
||||
rx_raw_audio_value = (uint8_t)((v + 32768) / 256);
|
||||
|
||||
//Play
|
||||
dacWrite(moduleConfig.audio.amp_pin ? moduleConfig.audio.amp_pin : AAMP, rx_raw_audio_value);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t AudioModule::runOnce()
|
||||
{
|
||||
if (moduleConfig.audio.codec2_enabled) {
|
||||
|
||||
if (firstTime) {
|
||||
|
||||
DEBUG_MSG("Initializing ADC on Channel %u\n", moduleConfig.audio.mic_chan ? moduleConfig.audio.mic_chan : AMIC);
|
||||
|
||||
mic_chan = moduleConfig.audio.mic_chan ? (adc1_channel_t)(int)moduleConfig.audio.mic_chan : (adc1_channel_t)AMIC;
|
||||
adc1_config_width(ADC_WIDTH_12Bit);
|
||||
adc1_config_channel_atten(mic_chan, ADC_ATTEN_DB_6);
|
||||
|
||||
// Start a timer at 8kHz to sample the ADC and play the audio on the DAC.
|
||||
uint32_t cpufreq = getCpuFrequencyMhz();
|
||||
switch (cpufreq){
|
||||
case 160:
|
||||
adcTimer = timerBegin(3, 1000, true); // 160 MHz / 1000 = 160KHz
|
||||
break;
|
||||
case 240:
|
||||
adcTimer = timerBegin(3, 1500, true); // 240 MHz / 1500 = 160KHz
|
||||
break;
|
||||
case 320:
|
||||
adcTimer = timerBegin(3, 2000, true); // 320 MHz / 2000 = 160KHz
|
||||
break;
|
||||
case 80:
|
||||
default:
|
||||
adcTimer = timerBegin(3, 500, true); // 80 MHz / 500 = 160KHz
|
||||
break;
|
||||
}
|
||||
timerAttachInterrupt(adcTimer, &AudioModule::handleInterrupt, true);
|
||||
timerAlarmWrite(adcTimer, 20, true); // Interrupts when counter == 20, 8.000 times a second
|
||||
timerAlarmEnable(adcTimer);
|
||||
|
||||
DEBUG_MSG("Initializing DAC on Pin %u\n", moduleConfig.audio.amp_pin ? moduleConfig.audio.amp_pin : AAMP);
|
||||
DEBUG_MSG("Initializing PTT on Pin %u\n", moduleConfig.audio.ptt_pin ? moduleConfig.audio.ptt_pin : PTT_PIN);
|
||||
|
||||
// Configure PTT input
|
||||
pinMode(moduleConfig.audio.ptt_pin ? moduleConfig.audio.ptt_pin : PTT_PIN, INPUT_PULLUP);
|
||||
|
||||
state = State::rx;
|
||||
|
||||
DEBUG_MSG("Setting up codec2 in mode %u\n", moduleConfig.audio.bitrate ? moduleConfig.audio.bitrate : AUDIO_MODULE_MODE);
|
||||
|
||||
codec2_state = codec2_create(moduleConfig.audio.bitrate ? moduleConfig.audio.bitrate : AUDIO_MODULE_MODE);
|
||||
codec2_set_lpc_post_filter(codec2_state, 1, 0, 0.8, 0.2);
|
||||
|
||||
firstTime = 0;
|
||||
} else {
|
||||
// Check if we have a PTT press
|
||||
if (digitalRead(moduleConfig.audio.ptt_pin ? moduleConfig.audio.ptt_pin : PTT_PIN) == LOW) {
|
||||
// PTT pressed, recording
|
||||
state = State::tx;
|
||||
}
|
||||
if (state != State::standby) {
|
||||
run_codec2();
|
||||
}
|
||||
}
|
||||
|
||||
return 100;
|
||||
} else {
|
||||
DEBUG_MSG("Audio Module Disabled\n");
|
||||
|
||||
return INT32_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
MeshPacket *AudioModule::allocReply()
|
||||
{
|
||||
|
||||
auto reply = allocDataPacket(); // Allocate a packet for sending
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
void AudioModule::sendPayload(NodeNum dest, bool wantReplies)
|
||||
{
|
||||
MeshPacket *p = allocReply();
|
||||
p->to = dest;
|
||||
p->decoded.want_response = wantReplies;
|
||||
|
||||
p->want_ack = AUDIO_MODULE_ACK;
|
||||
|
||||
p->decoded.payload.size = ENCODE_FRAME_SIZE;
|
||||
memcpy(p->decoded.payload.bytes, tx_encode_frame, p->decoded.payload.size);
|
||||
|
||||
service.sendToMesh(p);
|
||||
}
|
||||
|
||||
ProcessMessage AudioModule::handleReceived(const MeshPacket &mp)
|
||||
{
|
||||
if (moduleConfig.audio.codec2_enabled) {
|
||||
auto &p = mp.decoded;
|
||||
if (getFrom(&mp) != nodeDB.getNodeNum()) {
|
||||
if (p.payload.size == ENCODE_FRAME_SIZE) {
|
||||
memcpy(rx_encode_frame, p.payload.bytes, p.payload.size);
|
||||
state = State::rx;
|
||||
audioModule->setIntervalFromNow(0);
|
||||
run_codec2();
|
||||
} else {
|
||||
DEBUG_MSG("Invalid payload size %u != %u\n", p.payload.size, ENCODE_FRAME_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ProcessMessage::CONTINUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
68
src/modules/esp32/AudioModule.h
Normal file
68
src/modules/esp32/AudioModule.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include "SinglePortModule.h"
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "configuration.h"
|
||||
#include "NodeDB.h"
|
||||
#include <Arduino.h>
|
||||
#include <driver/adc.h>
|
||||
#include <functional>
|
||||
#if defined(ARCH_ESP32) && defined(USE_SX1280)
|
||||
#include <codec2.h>
|
||||
#include <ButterworthFilter.h>
|
||||
#include <FastAudioFIFO.h>
|
||||
#endif
|
||||
|
||||
#define ADC_BUFFER_SIZE 320 // 40ms of voice in 8KHz sampling frequency
|
||||
#define ENCODE_FRAME_SIZE 40 // 5 codec2 frames of 8 bytes each
|
||||
|
||||
class AudioModule : public SinglePortModule, private concurrency::OSThread
|
||||
{
|
||||
#if defined(ARCH_ESP32) && defined(USE_SX1280)
|
||||
bool firstTime = 1;
|
||||
hw_timer_t* adcTimer = NULL;
|
||||
uint16_t adc_buffer[ADC_BUFFER_SIZE] = {};
|
||||
int16_t speech[ADC_BUFFER_SIZE] = {};
|
||||
int16_t output_buffer[ADC_BUFFER_SIZE] = {};
|
||||
unsigned char rx_encode_frame[ENCODE_FRAME_SIZE] = {};
|
||||
unsigned char tx_encode_frame[ENCODE_FRAME_SIZE] = {};
|
||||
int tx_encode_frame_index = 0;
|
||||
FastAudioFIFO audio_fifo;
|
||||
uint16_t adc_buffer_index = 0;
|
||||
adc1_channel_t mic_chan = (adc1_channel_t)0;
|
||||
struct CODEC2* codec2_state = NULL;
|
||||
|
||||
enum State
|
||||
{
|
||||
standby, rx, tx
|
||||
};
|
||||
volatile State state = State::tx;
|
||||
|
||||
public:
|
||||
AudioModule();
|
||||
|
||||
/**
|
||||
* Send our payload into the mesh
|
||||
*/
|
||||
void sendPayload(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);
|
||||
|
||||
protected:
|
||||
virtual int32_t runOnce() override;
|
||||
|
||||
static void handleInterrupt();
|
||||
|
||||
void onTimer();
|
||||
|
||||
void run_codec2();
|
||||
|
||||
virtual MeshPacket *allocReply() override;
|
||||
|
||||
/** Called to handle a particular incoming message
|
||||
* @return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it
|
||||
*/
|
||||
virtual ProcessMessage handleReceived(const MeshPacket &mp) override;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern AudioModule *audioModule;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
//#include <assert.h>
|
||||
|
||||
/*
|
||||
As a sender, I can send packets every n-seonds. These packets include an incramented PacketID.
|
||||
As a sender, I can send packets every n seconds. These packets include an incremented PacketID.
|
||||
As a receiver, I can receive packets from multiple senders. These packets can be saved to the Filesystem.
|
||||
*/
|
||||
|
||||
@@ -36,12 +36,12 @@ int32_t RangeTestModule::runOnce()
|
||||
without having to configure it from the PythonAPI or WebUI.
|
||||
*/
|
||||
|
||||
//moduleConfig.range_test.enabled = 1;
|
||||
//moduleConfig.range_test.sender = 30;
|
||||
// moduleConfig.range_test.enabled = 1;
|
||||
// moduleConfig.range_test.sender = 30;
|
||||
// moduleConfig.range_test.save = 1;
|
||||
|
||||
// Fixed position is useful when testing indoors.
|
||||
// radioConfig.preferences.fixed_position = 1;
|
||||
// config.position.fixed_position = 1;
|
||||
|
||||
uint32_t senderHeartbeat = moduleConfig.range_test.sender * 1000;
|
||||
|
||||
@@ -57,7 +57,8 @@ int32_t RangeTestModule::runOnce()
|
||||
return (5000); // Sending first message 5 seconds after initilization.
|
||||
} else {
|
||||
DEBUG_MSG("Initializing Range Test Module -- Receiver\n");
|
||||
return (500);
|
||||
return (INT32_MAX);
|
||||
// This thread does not need to run as a receiver
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -70,8 +71,7 @@ int32_t RangeTestModule::runOnce()
|
||||
DEBUG_MSG("gpsStatus->getLongitude() %d\n", gpsStatus->getLongitude());
|
||||
DEBUG_MSG("gpsStatus->getHasLock() %d\n", gpsStatus->getHasLock());
|
||||
DEBUG_MSG("gpsStatus->getDOP() %d\n", gpsStatus->getDOP());
|
||||
DEBUG_MSG("gpsStatus->getHasLock() %d\n", gpsStatus->getHasLock());
|
||||
DEBUG_MSG("pref.fixed_position() %d\n", config.position.fixed_position);
|
||||
DEBUG_MSG("fixed_position() %d\n", config.position.fixed_position);
|
||||
|
||||
// Only send packets if the channel is less than 25% utilized.
|
||||
if (airTime->channelUtilizationPercent() < 25) {
|
||||
@@ -82,11 +82,11 @@ int32_t RangeTestModule::runOnce()
|
||||
|
||||
return (senderHeartbeat);
|
||||
} else {
|
||||
// Otherwise, we're a receiver.
|
||||
|
||||
return (500);
|
||||
return (INT32_MAX);
|
||||
// This thread does not need to run as a receiver
|
||||
}
|
||||
// TBD
|
||||
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -221,6 +221,8 @@ bool RangeTestModuleRadio::appendFile(const MeshPacket &mp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
FSCom.mkdir("/static");
|
||||
|
||||
// If the file doesn't exist, write the header.
|
||||
if (!FSCom.exists("/static/rangetest.csv")) {
|
||||
//--------- Write to file
|
||||
|
||||
@@ -69,22 +69,25 @@ void MQTT::onPublish(char *topic, byte *payload, unsigned int length)
|
||||
DEBUG_MSG("Invalid MQTT service envelope, topic %s, len %u!\n", topic, length);
|
||||
}
|
||||
} else {
|
||||
pb_decode_from_bytes(payload, length, ServiceEnvelope_fields, &e);
|
||||
if (strcmp(e.gateway_id, owner.id) == 0)
|
||||
DEBUG_MSG("Ignoring downlink message we originally sent.\n");
|
||||
else {
|
||||
if (e.packet) {
|
||||
DEBUG_MSG("Received MQTT topic %s, len=%u\n", topic, length);
|
||||
MeshPacket *p = packetPool.allocCopy(*e.packet);
|
||||
if (!pb_decode_from_bytes(payload, length, ServiceEnvelope_fields, &e)) {
|
||||
DEBUG_MSG("Invalid MQTT service envelope, topic %s, len %u!\n", topic, length);
|
||||
return;
|
||||
}else {
|
||||
if (strcmp(e.gateway_id, owner.id) == 0)
|
||||
DEBUG_MSG("Ignoring downlink message we originally sent.\n");
|
||||
else {
|
||||
if (e.packet) {
|
||||
DEBUG_MSG("Received MQTT topic %s, len=%u\n", topic, length);
|
||||
MeshPacket *p = packetPool.allocCopy(*e.packet);
|
||||
|
||||
// ignore messages sent by us or if we don't have the channel key
|
||||
if (router && p->from != nodeDB.getNodeNum() && perhapsDecode(p))
|
||||
router->enqueueReceivedMessage(p);
|
||||
else
|
||||
packetPool.release(p);
|
||||
// ignore messages sent by us or if we don't have the channel key
|
||||
if (router && p->from != nodeDB.getNodeNum() && perhapsDecode(p))
|
||||
router->enqueueReceivedMessage(p);
|
||||
else
|
||||
packetPool.release(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make sure to free both strings and the MeshPacket (passing in NULL is acceptable)
|
||||
free(e.channel_id);
|
||||
free(e.gateway_id);
|
||||
@@ -115,24 +118,16 @@ bool MQTT::connected()
|
||||
void MQTT::reconnect()
|
||||
{
|
||||
if (wantsLink()) {
|
||||
const char *serverAddr = "mqtt.meshtastic.org"; // default hostname
|
||||
int serverPort = 1883; // default server port
|
||||
const char *mqttUsername = "meshdev";
|
||||
const char *mqttPassword = "large4cats";
|
||||
// Defaults
|
||||
int serverPort = 1883;
|
||||
const char *serverAddr = default_mqtt_address;
|
||||
const char *mqttUsername = default_mqtt_username;
|
||||
const char *mqttPassword = default_mqtt_password;
|
||||
|
||||
if (*moduleConfig.mqtt.address) {
|
||||
serverAddr = moduleConfig.mqtt.address; // Override the default
|
||||
mqttUsername =
|
||||
moduleConfig.mqtt.username; // do not use the hardcoded credentials for a custom mqtt server
|
||||
serverAddr = moduleConfig.mqtt.address;
|
||||
mqttUsername = moduleConfig.mqtt.username;
|
||||
mqttPassword = moduleConfig.mqtt.password;
|
||||
} else {
|
||||
// we are using the default server. Use the hardcoded credentials by default, but allow overriding
|
||||
if (*moduleConfig.mqtt.username && moduleConfig.mqtt.username[0] != '\0') {
|
||||
mqttUsername = moduleConfig.mqtt.username;
|
||||
}
|
||||
if (*moduleConfig.mqtt.password && moduleConfig.mqtt.password[0] != '\0') {
|
||||
mqttPassword = moduleConfig.mqtt.password;
|
||||
}
|
||||
}
|
||||
|
||||
String server = String(serverAddr);
|
||||
@@ -145,8 +140,7 @@ void MQTT::reconnect()
|
||||
}
|
||||
pubSub.setServer(serverAddr, serverPort);
|
||||
|
||||
DEBUG_MSG("Connecting to MQTT server %s, port: %d, username: %s, password: %s\n", serverAddr, serverPort, mqttUsername,
|
||||
mqttPassword);
|
||||
DEBUG_MSG("Connecting to MQTT server %s, port: %d, username: %s, password: %s\n", serverAddr, serverPort, mqttUsername, mqttPassword);
|
||||
auto myStatus = (statusTopic + owner.id);
|
||||
bool connected = pubSub.connect(owner.id, mqttUsername, mqttPassword, myStatus.c_str(), 1, true, "offline");
|
||||
if (connected) {
|
||||
@@ -173,9 +167,11 @@ void MQTT::sendSubscriptions()
|
||||
String topic = cryptTopic + channels.getGlobalId(i) + "/#";
|
||||
DEBUG_MSG("Subscribing to %s\n", topic.c_str());
|
||||
pubSub.subscribe(topic.c_str(), 1); // FIXME, is QOS 1 right?
|
||||
String topicDecoded = jsonTopic + channels.getGlobalId(i) + "/#";
|
||||
DEBUG_MSG("Subscribing to %s\n", topicDecoded.c_str());
|
||||
pubSub.subscribe(topicDecoded.c_str(), 1); // FIXME, is QOS 1 right?
|
||||
if (moduleConfig.mqtt.json_enabled == true) {
|
||||
String topicDecoded = jsonTopic + channels.getGlobalId(i) + "/#";
|
||||
DEBUG_MSG("Subscribing to %s\n", topicDecoded.c_str());
|
||||
pubSub.subscribe(topicDecoded.c_str(), 1); // FIXME, is QOS 1 right?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,8 @@
|
||||
#define HW_VENDOR HardwareModel_TLORA_V1_1P3
|
||||
#elif defined(TLORA_V2_1_16)
|
||||
#define HW_VENDOR HardwareModel_TLORA_V2_1_1P6
|
||||
#elif defined(TLORA_V2_1_18)
|
||||
#define HW_VENDOR HardwareModel_TLORA_V2_1_1P8
|
||||
#elif defined(GENIEBLOCKS)
|
||||
#define HW_VENDOR HardwareModel_GENIEBLOCKS
|
||||
#elif defined(PRIVATE_HW)
|
||||
@@ -82,6 +84,10 @@
|
||||
#define HW_VENDOR HardwareModel_STATION_G1
|
||||
#elif defined(DR_DEV)
|
||||
#define HW_VENDOR HardwareModel_DR_DEV
|
||||
#elif defined(HELTEC_V3)
|
||||
#define HW_VENDOR HardwareModel_HELTEC_V3
|
||||
#elif defined(HELTEC_WSL_V3)
|
||||
#define HW_VENDOR HardwareModel_HELTEC_WSL_V3
|
||||
#endif
|
||||
|
||||
//
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <driver/rtc_io.h>
|
||||
#include <nvs.h>
|
||||
#include <nvs_flash.h>
|
||||
#include "soc/rtc.h"
|
||||
|
||||
NimbleBluetooth *nimbleBluetooth;
|
||||
|
||||
@@ -36,6 +37,44 @@ void setBluetoothEnable(bool on) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAS_32768HZ
|
||||
#define CALIBRATE_ONE(cali_clk) calibrate_one(cali_clk, #cali_clk)
|
||||
|
||||
static uint32_t calibrate_one(rtc_cal_sel_t cal_clk, const char *name)
|
||||
{
|
||||
const uint32_t cal_count = 1000;
|
||||
// const float factor = (1 << 19) * 1000.0f; unused var?
|
||||
uint32_t cali_val;
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
cali_val = rtc_clk_cal(cal_clk, cal_count);
|
||||
}
|
||||
return cali_val;
|
||||
}
|
||||
|
||||
void enableSlowCLK()
|
||||
{
|
||||
rtc_clk_32k_enable(true);
|
||||
|
||||
CALIBRATE_ONE(RTC_CAL_RTC_MUX);
|
||||
uint32_t cal_32k = CALIBRATE_ONE(RTC_CAL_32K_XTAL);
|
||||
|
||||
if (cal_32k == 0) {
|
||||
DEBUG_MSG("32K XTAL OSC has not started up\n");
|
||||
} else {
|
||||
rtc_clk_slow_freq_set(RTC_SLOW_FREQ_32K_XTAL);
|
||||
DEBUG_MSG("Switching RTC Source to 32.768Khz succeeded, using 32K XTAL\n");
|
||||
CALIBRATE_ONE(RTC_CAL_RTC_MUX);
|
||||
CALIBRATE_ONE(RTC_CAL_32K_XTAL);
|
||||
}
|
||||
CALIBRATE_ONE(RTC_CAL_RTC_MUX);
|
||||
CALIBRATE_ONE(RTC_CAL_32K_XTAL);
|
||||
if (rtc_clk_slow_freq_get() != RTC_SLOW_FREQ_32K_XTAL) {
|
||||
DEBUG_MSG("Warning: Failed to switch 32K XTAL RTC source to 32.768Khz !!! \n"); return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void esp32Setup()
|
||||
{
|
||||
uint32_t seed = esp_random();
|
||||
@@ -83,6 +122,10 @@ void esp32Setup()
|
||||
|
||||
res = esp_task_wdt_add(NULL);
|
||||
assert(res == ESP_OK);
|
||||
|
||||
#ifdef HAS_32768HZ
|
||||
enableSlowCLK();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
#define HW_VENDOR HardwareModel_T_ECHO
|
||||
#elif defined(NORDIC_PCA10059)
|
||||
#define HW_VENDOR HardwareModel_NRF52840_PCA10059
|
||||
#elif defined(PRIVATE_HW)
|
||||
#elif defined(PRIVATE_HW) || defined(FEATHER_DIY)
|
||||
#define HW_VENDOR HardwareModel_PRIVATE_HW
|
||||
#else
|
||||
#define HW_VENDOR HardwareModel_NRF52_UNKNOWN
|
||||
|
||||
@@ -13,7 +13,8 @@ void powerCommandsCheck()
|
||||
#elif defined(ARCH_NRF52)
|
||||
NVIC_SystemReset();
|
||||
#else
|
||||
DEBUG_MSG("FIXME implement reboot for this platform");
|
||||
rebootAtMsec = -1;
|
||||
DEBUG_MSG("FIXME implement reboot for this platform. Skipping for now.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -263,8 +263,8 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
|
||||
#ifdef BUTTON_PIN
|
||||
gpio_wakeup_enable((gpio_num_t)BUTTON_PIN, GPIO_INTR_LOW_LEVEL); // when user presses, this button goes low
|
||||
#endif
|
||||
#ifdef RF95_IRQ_GPIO
|
||||
gpio_wakeup_enable((gpio_num_t)RF95_IRQ_GPIO, GPIO_INTR_HIGH_LEVEL); // RF95 interrupt, active high
|
||||
#ifdef RF95_IRQ
|
||||
gpio_wakeup_enable((gpio_num_t)RF95_IRQ, GPIO_INTR_HIGH_LEVEL); // RF95 interrupt, active high
|
||||
#endif
|
||||
#ifdef PMU_IRQ
|
||||
// wake due to PMU can happen repeatedly if there is no battery installed or the battery fills
|
||||
|
||||
@@ -1,47 +1,55 @@
|
||||
// For OLED LCD
|
||||
#define I2C_SDA 21
|
||||
#define I2C_SCL 22
|
||||
// Initialize i2c bus on sd_dat and esp_led pins, respectively. We need a bus to not hang on boot
|
||||
#define HAS_SCREEN 0
|
||||
#define I2C_SDA 4
|
||||
#define I2C_SCL 5
|
||||
|
||||
// GPS
|
||||
#undef GPS_RX_PIN
|
||||
#define GPS_RX_PIN NOT_A_PIN
|
||||
#undef WANT_GPS
|
||||
#define HAS_GPS 0
|
||||
|
||||
#define BUTTON_PIN 2 // The middle button GPIO on the T-Beam
|
||||
#define BUTTON_PIN 13 // The middle button GPIO on the T-Beam
|
||||
#define BUTTON_NEED_PULLUP
|
||||
#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Module (#975).
|
||||
|
||||
#define LORA_DIO0 -1 // a No connect on the SX1262/SX1268 module
|
||||
#define LORA_RESET -1 // RST for SX1276, and for SX1262/SX1268
|
||||
#define LORA_DIO1 27 // IRQ for SX1262/SX1268 (IO26 FOR 22S)
|
||||
#define LORA_DIO2 NOT_A_PIN // BUSY for SX1262/SX1268
|
||||
#define LORA_DIO3 // Not connected on PCB, but internally on the SX1262/SX1268, if DIO3 is high the TXCO is enabled
|
||||
#define LORA_DIO0 NOT_A_PIN // a No connect on the SX1262/SX1268 module
|
||||
#define LORA_RESET NOT_A_PIN // RST for SX1276, and for SX1262/SX1268
|
||||
#define LORA_DIO3 NOT_A_PIN // Not connected on PCB, but internally on the SX1262/SX1268, if DIO3 is high the TXCO is enabled
|
||||
|
||||
// In transmitting, set TXEN as high communication level,RXEN pin is low level;
|
||||
// In receiving, set RXEN as high communication level, TXEN is lowlevel;
|
||||
// Before powering off, set TXEN、RXEN as low level.
|
||||
#define LORA_RXEN 17 // Input - RF switch RX control, connecting external MCU IO, valid in high level
|
||||
#define LORA_TXEN -1 // Input - RF switch TX control, connecting external MCU IO or DIO2, valid in high level
|
||||
/* --PINS FOR THE 900M22S
|
||||
|
||||
#undef RF95_SCK
|
||||
#define RF95_SCK 18
|
||||
#undef RF95_MISO
|
||||
#define RF95_MISO 19
|
||||
#undef RF95_MOSI
|
||||
#define RF95_MOSI 23
|
||||
|
||||
// PINS FOR THE 900M22S
|
||||
|
||||
#define LORA_DIO1 26 // IRQ for SX1262/SX1268
|
||||
#define LORA_DIO2 22 // BUSY for SX1262/SX1268
|
||||
#define LORA_TXEN NOT_A_PIN // Input - RF switch TX control, connecting external MCU IO or DIO2, valid in high level
|
||||
#define LORA_RXEN 17 // Input - RF switch RX control, connecting external MCU IO, valid in high level
|
||||
#undef RF95_NSS
|
||||
#define RF95_NSS 16
|
||||
*/
|
||||
#define SX126X_BUSY 22
|
||||
#define SX126X_CS 16
|
||||
|
||||
|
||||
// PINS FOR THE 900M30S
|
||||
#undef RF95_SCK
|
||||
#define RF95_SCK 18
|
||||
#undef RF95_MISO
|
||||
#define RF95_MISO 19
|
||||
#undef RF95_MOSI
|
||||
#define RF95_MOSI 23
|
||||
/*
|
||||
#define LORA_DIO1 27 // IRQ for SX1262/SX1268
|
||||
#define LORA_DIO2 35 // BUSY for SX1262/SX1268
|
||||
#define LORA_TXEN NOT_A_PIN // Input - RF switch TX control, connecting external MCU IO or DIO2, valid in high level
|
||||
#define LORA_RXEN 21 // Input - RF switch RX control, connecting external MCU IO, valid in high level
|
||||
#undef RF95_NSS
|
||||
#define RF95_NSS 33
|
||||
#define SX126X_BUSY 35
|
||||
#define SX126X_CS 33
|
||||
*/
|
||||
|
||||
// RX/TX for RFM95/SX127x
|
||||
#define RF95_RXEN LORA_RXEN
|
||||
@@ -49,21 +57,15 @@
|
||||
// #define RF95_TCXO <GPIO#>
|
||||
|
||||
// common pinouts for SX126X modules
|
||||
#define SX126X_CS 33
|
||||
|
||||
#define SX126X_DIO1 LORA_DIO1
|
||||
#define SX126X_BUSY 35
|
||||
#define SX126X_RESET LORA_RESET
|
||||
#define SX126X_RXEN LORA_RXEN
|
||||
#define SX126X_TXEN LORA_TXEN
|
||||
|
||||
// supported modules list
|
||||
#define USE_RF95 // RFM95/SX127x
|
||||
//#define USE_RF95 // RFM95/SX127x
|
||||
#define USE_SX1262
|
||||
#define USE_SX1268
|
||||
#define USE_LLCC68
|
||||
|
||||
#ifdef EBYTE_E22
|
||||
// Internally the TTGO module hooks the SX126x-DIO2 in to control the TX/RX switch
|
||||
// (which is the default for the sx1262interface code)
|
||||
//#define USE_SX1268
|
||||
//#define USE_LLCC68
|
||||
#define SX126X_E22
|
||||
#endif
|
||||
|
||||
11
variants/feather_diy/platformio.ini
Normal file
11
variants/feather_diy/platformio.ini
Normal file
@@ -0,0 +1,11 @@
|
||||
; The very slick RAK wireless RAK 4631 / 4630 board - Unified firmware for 5005/19003, with or without OLED RAK 1921
|
||||
[env:feather_diy]
|
||||
extends = nrf52840_base
|
||||
board = adafruit_feather_nrf52840
|
||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/feather_diy -Dfeather_diy
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/feather_diy>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
debug_tool = jlink
|
||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||
;upload_protocol = jlink
|
||||
24
variants/feather_diy/variant.cpp
Normal file
24
variants/feather_diy/variant.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
||||
Copyright (c) 2016 Sandeep Mistry All right reserved.
|
||||
Copyright (c) 2018, Adafruit Industries (adafruit.com)
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "variant.h"
|
||||
#include "nrf.h"
|
||||
#include "wiring_constants.h"
|
||||
#include "wiring_digital.h"
|
||||
119
variants/feather_diy/variant.h
Normal file
119
variants/feather_diy/variant.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
||||
Copyright (c) 2016 Sandeep Mistry All right reserved.
|
||||
Copyright (c) 2018, Adafruit Industries (adafruit.com)
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _VARIANT_FEATHER_DIY_
|
||||
#define _VARIANT_FEATHER_DIY_
|
||||
|
||||
/** Master clock frequency */
|
||||
#define VARIANT_MCK (64000000ul)
|
||||
|
||||
#define USE_LFXO // Board uses 32khz crystal for LF
|
||||
// define USE_LFRC // Board uses RC for LF
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WVariant.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
// Number of pins defined in PinDescription array
|
||||
#define PINS_COUNT (48)
|
||||
#define NUM_DIGITAL_PINS (48)
|
||||
#define NUM_ANALOG_INPUTS (6)
|
||||
#define NUM_ANALOG_OUTPUTS (0)
|
||||
|
||||
#define WIRE_INTERFACES_COUNT 1
|
||||
|
||||
#define PIN_WIRE_SDA (0 + 12) //P0.12 22
|
||||
#define PIN_WIRE_SCL (0 + 11) //P0.12 23
|
||||
|
||||
#define PIN_LED1 (32 + 15) //P1.15 3
|
||||
#define PIN_LED2 (32 + 10) //P1.10 4
|
||||
|
||||
#define LED_BUILTIN PIN_LED1
|
||||
|
||||
#define LED_GREEN PIN_LED2 // Actually red
|
||||
#define LED_BLUE PIN_LED1
|
||||
|
||||
#define LED_STATE_ON 1 // State when LED is litted
|
||||
|
||||
#define BUTTON_PIN (32 + 2) //P1.02 7
|
||||
|
||||
/*
|
||||
* Serial interfaces
|
||||
*/
|
||||
#define PIN_SERIAL1_RX (0 + 24) //P0.24 1
|
||||
#define PIN_SERIAL1_TX (0 + 25) //P0.25 0
|
||||
|
||||
#define PIN_SERIAL2_RX (-1)
|
||||
#define PIN_SERIAL2_TX (-1)
|
||||
|
||||
#define SPI_INTERFACES_COUNT 1
|
||||
|
||||
#define PIN_SPI_MISO (0 + 15) //P0.15 24
|
||||
#define PIN_SPI_MOSI (0 + 13) //P0.13 25
|
||||
#define PIN_SPI_SCK (0 + 14) //P0.14 26
|
||||
|
||||
#define SS 2
|
||||
|
||||
#define LORA_DIO0 -1 // a No connect on the SX1262/SX1268 module
|
||||
#define LORA_RESET (32 + 9) //P1.09 13 // RST for SX1276, and for SX1262/SX1268
|
||||
#define LORA_DIO1 (0 + 6) //P0.06 11 // IRQ for SX1262/SX1268
|
||||
#define LORA_DIO2 (0 + 8) //P0.08 12 // BUSY for SX1262/SX1268
|
||||
#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262/SX1268, if DIO3 is high the TXCO is enabled
|
||||
|
||||
#define RF95_SCK SCK
|
||||
#define RF95_MISO MI
|
||||
#define RF95_MOSI MO
|
||||
#define RF95_NSS SS
|
||||
|
||||
// enables 3.3V periphery like GPS or IO Module
|
||||
#define PIN_3V3_EN (-1)
|
||||
|
||||
#undef USE_EINK
|
||||
|
||||
// supported modules list
|
||||
#define USE_SX1262
|
||||
|
||||
// common pinouts for SX126X modules
|
||||
#define SX126X_CS RF95_NSS // NSS for SX126X
|
||||
#define SX126X_DIO1 LORA_DIO1
|
||||
#define SX126X_BUSY LORA_DIO2
|
||||
#define SX126X_RESET LORA_RESET
|
||||
#define SX126X_RXEN (0 + 27) //P0.27 10
|
||||
#define SX126X_TXEN (0 + 26) //P0.26 9
|
||||
|
||||
#ifdef EBYTE_E22
|
||||
// Internally the TTGO module hooks the SX126x-DIO2 in to control the TX/RX switch
|
||||
// (which is the default for the sx1262interface code)
|
||||
#define SX126X_E22
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Arduino objects - C++ only
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#endif
|
||||
9
variants/heltec_v3/platformio.ini
Normal file
9
variants/heltec_v3/platformio.ini
Normal file
@@ -0,0 +1,9 @@
|
||||
[env:heltec-v3]
|
||||
platform = https://github.com/Baptou88/platform-espressif32.git
|
||||
extends = esp32_base
|
||||
board = heltec_wifi_lora_32_V3
|
||||
# Temporary: https://community.platformio.org/t/heltec-esp32-lora-v3-board-support/30406/2
|
||||
platform_packages =
|
||||
framework-arduinoespressif32@https://github.com/Baptou88/arduino-esp32.git
|
||||
build_flags =
|
||||
${esp32s3_base.build_flags} -D HELTEC_V3 -I variants/heltec_v3
|
||||
32
variants/heltec_v3/variant.h
Normal file
32
variants/heltec_v3/variant.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#define LED_PIN LED
|
||||
|
||||
#define HAS_GPS 0
|
||||
|
||||
#define RESET_OLED RST_OLED
|
||||
#define I2C_SDA SDA_OLED // I2C pins for this board
|
||||
#define I2C_SCL SCL_OLED
|
||||
|
||||
#define VEXT_ENABLE Vext // active low, powers the oled display and the lora antenna boost
|
||||
#define BUTTON_PIN 0
|
||||
|
||||
#define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||
#define ADC_MULTIPLIER 5.22
|
||||
|
||||
#define USE_SX1262
|
||||
|
||||
#define LORA_DIO0 -1 // a No connect on the SX1262 module
|
||||
#define LORA_RESET 12
|
||||
#define LORA_DIO1 14 // SX1262 IRQ
|
||||
#define LORA_DIO2 13 // SX1262 BUSY
|
||||
#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TXCO is enabled
|
||||
|
||||
#define RF95_SCK 9
|
||||
#define RF95_MISO 11
|
||||
#define RF95_MOSI 10
|
||||
#define RF95_NSS 8
|
||||
|
||||
#define SX126X_CS RF95_NSS
|
||||
#define SX126X_DIO1 LORA_DIO1
|
||||
#define SX126X_BUSY LORA_DIO2
|
||||
#define SX126X_RESET LORA_RESET
|
||||
#define SX126X_E22
|
||||
9
variants/heltec_wsl_v3/platformio.ini
Normal file
9
variants/heltec_wsl_v3/platformio.ini
Normal file
@@ -0,0 +1,9 @@
|
||||
[env:heltec-wsl-v3]
|
||||
platform = https://github.com/Baptou88/platform-espressif32.git
|
||||
extends = esp32_base
|
||||
board = heltec_wifi_lora_32_V3
|
||||
# Temporary: https://community.platformio.org/t/heltec-esp32-lora-v3-board-support/30406/2
|
||||
platform_packages =
|
||||
framework-arduinoespressif32@https://github.com/Baptou88/arduino-esp32.git
|
||||
build_flags =
|
||||
${esp32s3_base.build_flags} -D HELTEC_WSL_V3 -I variants/heltec_wsl_v3
|
||||
29
variants/heltec_wsl_v3/variant.h
Normal file
29
variants/heltec_wsl_v3/variant.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#define LED_PIN LED
|
||||
|
||||
#define HAS_SCREEN 0
|
||||
#define HAS_GPS 0
|
||||
|
||||
#define VEXT_ENABLE Vext // active low, powers the oled display and the lora antenna boost
|
||||
#define BUTTON_PIN 0
|
||||
|
||||
#define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||
#define ADC_MULTIPLIER 5.22
|
||||
|
||||
#define USE_SX1262
|
||||
|
||||
#define LORA_DIO0 -1 // a No connect on the SX1262 module
|
||||
#define LORA_RESET 12
|
||||
#define LORA_DIO1 14 // SX1262 IRQ
|
||||
#define LORA_DIO2 13 // SX1262 BUSY
|
||||
#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TXCO is enabled
|
||||
|
||||
#define RF95_SCK 9
|
||||
#define RF95_MISO 11
|
||||
#define RF95_MOSI 10
|
||||
#define RF95_NSS 8
|
||||
|
||||
#define SX126X_CS RF95_NSS
|
||||
#define SX126X_DIO1 LORA_DIO1
|
||||
#define SX126X_BUSY LORA_DIO2
|
||||
#define SX126X_RESET LORA_RESET
|
||||
#define SX126X_E22
|
||||
33
variants/m5stack_coreink/Speaker.cpp
Normal file
33
variants/m5stack_coreink/Speaker.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "Speaker.h"
|
||||
|
||||
TONE::TONE(void) {
|
||||
_volume = 5;
|
||||
_begun = false;
|
||||
}
|
||||
|
||||
void TONE::begin() {
|
||||
_begun = true;
|
||||
ledcSetup(TONE_PIN_CHANNEL, 0, 13);
|
||||
ledcAttachPin(PIN_BUZZER, TONE_PIN_CHANNEL);
|
||||
}
|
||||
|
||||
void TONE::end() {
|
||||
mute();
|
||||
ledcDetachPin(PIN_BUZZER);
|
||||
_begun = false;
|
||||
}
|
||||
|
||||
void TONE::tone(uint16_t frequency) {
|
||||
if(!_begun) begin();
|
||||
ledcWriteTone(TONE_PIN_CHANNEL, frequency);
|
||||
ledcWrite(TONE_PIN_CHANNEL, 0x400 >> _volume);
|
||||
}
|
||||
|
||||
void TONE::setVolume(uint8_t volume) {
|
||||
_volume = 11 - volume;
|
||||
}
|
||||
|
||||
void TONE::mute() {
|
||||
ledcWriteTone(TONE_PIN_CHANNEL, 0);
|
||||
digitalWrite(PIN_BUZZER, 0);
|
||||
}
|
||||
30
variants/m5stack_coreink/Speaker.h
Normal file
30
variants/m5stack_coreink/Speaker.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef _SPEAKER_H_
|
||||
#define _SPEAKER_H_
|
||||
|
||||
#include "configuration.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
#include "esp32-hal-dac.h"
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
class TONE {
|
||||
public:
|
||||
TONE(void);
|
||||
|
||||
void begin();
|
||||
void end();
|
||||
void mute();
|
||||
void tone(uint16_t frequency);
|
||||
void setVolume(uint8_t volume);
|
||||
|
||||
private:
|
||||
uint8_t _volume;
|
||||
bool _begun;
|
||||
bool speaker_on;
|
||||
};
|
||||
#endif
|
||||
@@ -1,18 +1,26 @@
|
||||
[env:m5stack-coreink]
|
||||
extends = esp32_base
|
||||
board = m5stack-coreink
|
||||
build_src_filter =
|
||||
${esp32_base.build_src_filter}
|
||||
+<../variants/m5stack_coreink>
|
||||
build_flags =
|
||||
${esp32_base.build_flags} -D M5_COREINK -I variants/m5stack_coreink
|
||||
${esp32_base.build_flags} -I variants/m5stack_coreink
|
||||
;-D RADIOLIB_VERBOSE
|
||||
-Ofast
|
||||
-D__MCUXPRESSO
|
||||
-DEPD_HEIGHT=200
|
||||
-DEPD_WIDTH=200
|
||||
-DUSER_SETUP_LOADED
|
||||
-DM5_COREINK
|
||||
-DM5STACK
|
||||
lib_deps =
|
||||
${esp32_base.lib_deps}
|
||||
zinggjm/GxEPD2@^1.4.9
|
||||
lewisxhe/PCF8563_Library@^1.0.1
|
||||
lib_ignore =
|
||||
m5stack-coreink
|
||||
monitor_filters = esp32_exception_decoder
|
||||
board_build.f_cpu = 240000000L
|
||||
upload_protocol = esptool
|
||||
upload_port = /dev/ttyACM*
|
||||
upload_port = /dev/ttyACM0
|
||||
|
||||
@@ -1,34 +1,40 @@
|
||||
#define I2C_SDA 21 //-1
|
||||
#define I2C_SCL 22 //-1
|
||||
#define I2C_SDA 21
|
||||
#define I2C_SCL 22
|
||||
|
||||
//#define LED_PIN 10
|
||||
// LED?
|
||||
#define LED_INVERTED 0
|
||||
#define LED_PIN 10
|
||||
|
||||
#include "pcf8563.h"
|
||||
// PCF8563 RTC Module
|
||||
#define PCF8563_RTC 0x51
|
||||
|
||||
#define BUTTON_NEED_PULLUP
|
||||
#define BUTTON_PIN 5
|
||||
#define HAS_RTC 1
|
||||
|
||||
//Wheel
|
||||
// Down 37
|
||||
// Push 38
|
||||
// Up 39
|
||||
|
||||
// Top Physical Button 5
|
||||
|
||||
#define BUTTON_NEED_PULLUP
|
||||
#define BUTTON_PIN 5
|
||||
|
||||
//BUZZER
|
||||
#define PIN_BUZZER 2
|
||||
#define TONE_PIN_CHANNEL 0
|
||||
|
||||
#undef RF95_SCK
|
||||
#undef RF95_MISO
|
||||
#undef RF95_MOSI
|
||||
#undef RF95_NSS
|
||||
#define USE_RF95
|
||||
|
||||
#define RF95_SCK 18 //13
|
||||
#define RF95_MISO 34 //26
|
||||
#define RF95_MOSI 23 //25
|
||||
#define RF95_SCK 18
|
||||
#define RF95_MISO 34
|
||||
#define RF95_MOSI 23
|
||||
#define RF95_NSS 14
|
||||
#define LORA_DIO0 25 //32 now moved from ext port
|
||||
#define LORA_RESET 26 //33 now moved from ext port
|
||||
#define LORA_DIO0 25
|
||||
#define LORA_RESET 26
|
||||
#define LORA_DIO1 RADIOLIB_NC
|
||||
#define LORA_DIO2 RADIOLIB_NC
|
||||
|
||||
@@ -39,12 +45,10 @@
|
||||
#define USE_EINK
|
||||
//https://docs.m5stack.com/en/core/coreink
|
||||
//https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/schematic/Core/coreink/coreink_sch.pdf
|
||||
#define PIN_EINK_EN -1
|
||||
#define PIN_EINK_CS 9 // EPD_CS
|
||||
#define PIN_EINK_BUSY 4 // EPD_BUSY
|
||||
#define PIN_EINK_EN -1 // N/C
|
||||
#define PIN_EINK_CS 9 // EPD_CS
|
||||
#define PIN_EINK_BUSY 4 // EPD_BUSY
|
||||
#define PIN_EINK_DC 15 // EPD_D/C
|
||||
#define PIN_EINK_RES -1 // Connected to GPIO0 but no needed !!!! maybe causing issue ?
|
||||
#define PIN_EINK_SCLK 18 // EPD_SCLK
|
||||
#define PIN_EINK_RES -1 // Connected but not needed
|
||||
#define PIN_EINK_SCLK 18 // EPD_SCLK
|
||||
#define PIN_EINK_MOSI 23 // EPD_MOSI
|
||||
|
||||
#define HAS_RTC 1
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
[env:native]
|
||||
platform = https://github.com/meshtastic/platform-native.git
|
||||
extends = portduino_base
|
||||
build_flags = ${portduino_base.build_flags} -O0 -I variants/portduino
|
||||
framework = arduino
|
||||
board = cross_platform
|
||||
lib_deps = ${portduino_base.lib_deps}
|
||||
build_src_filter = ${portduino_base.build_src_filter}
|
||||
|
||||
; The Portduino based sim environment on top of a linux OS and touching linux hardware devices
|
||||
[env:linux]
|
||||
platform = https://github.com/meshtastic/platform-native.git
|
||||
extends = portduino_base
|
||||
build_flags = ${portduino_base.build_flags} -O0 -lgpiod -I variants/portduino
|
||||
framework = arduino
|
||||
board = linux_hardware
|
||||
lib_deps = ${portduino_base.lib_deps}
|
||||
build_src_filter = ${portduino_base.build_src_filter}
|
||||
|
||||
; The Portduino based sim environment on top of a linux OS and touching linux hardware devices
|
||||
[env:linux-arm]
|
||||
extends = portduino_base
|
||||
build_flags = ${portduino_base.build_flags} -O0 -lgpiod -I variants/portduino
|
||||
board = linux_arm
|
||||
lib_deps = ${portduino_base.lib_deps}
|
||||
build_src_filter = ${portduino_base.build_src_filter}
|
||||
|
||||
@@ -23,16 +23,3 @@
|
||||
// HOPE RFM90 does not have a TCXO therefore not SX126X_E22
|
||||
#endif
|
||||
|
||||
// Temporary shim for radio lib macros until we upgrade to upstream for portduino
|
||||
#define RADIOLIB_PREAMBLE_DETECTED PREAMBLE_DETECTED
|
||||
|
||||
#define RADIOLIB_ERR_NONE ERR_NONE
|
||||
#define RADIOLIB_ERR_WRONG_MODEM ERR_WRONG_MODEM
|
||||
|
||||
#define RADIOLIB_SX126X_IRQ_HEADER_VALID SX126X_IRQ_HEADER_VALID
|
||||
#define RADIOLIB_SX126X_LORA_CRC_ON SX126X_LORA_CRC_ON
|
||||
|
||||
#define RADIOLIB_SX127X_REG_TCXO SX127X_REG_TCXO
|
||||
#define RADIOLIB_SX127X_REG_MODEM_STAT SX127X_REG_MODEM_STAT
|
||||
#define RADIOLIB_SX127X_SYNC_WORD SX127X_SYNC_WORD
|
||||
#define RADIOLIB_SX127X_MASK_IRQ_FLAG_VALID_HEADER SX127X_MASK_IRQ_FLAG_VALID_HEADER
|
||||
|
||||
@@ -59,11 +59,11 @@ static const uint8_t SCK = 33;
|
||||
|
||||
// https://docs.rakwireless.com/Product-Categories/WisBlock/RAK13300/
|
||||
|
||||
#define LORA_DIO0 -1 // a No connect on the SX1262/SX1268 module
|
||||
#define LORA_RESET WB_IO4 // RST for SX1276, and for SX1262/SX1268
|
||||
#define LORA_DIO1 WB_IO6 // IRQ for SX1262/SX1268
|
||||
#define LORA_DIO2 WB_IO5 // BUSY for SX1262/SX1268
|
||||
#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262/SX1268, if DIO3 is high the TXCO is enabled
|
||||
#define LORA_DIO0 RADIOLIB_NC // a No connect on the SX1262/SX1268 module
|
||||
#define LORA_RESET WB_IO4 // RST for SX1276, and for SX1262/SX1268
|
||||
#define LORA_DIO1 WB_IO6 // IRQ for SX1262/SX1268
|
||||
#define LORA_DIO2 WB_IO5 // BUSY for SX1262/SX1268
|
||||
#define LORA_DIO3 RADIOLIB_NC // Not connected on PCB, but internally on the TTGO SX1262/SX1268, if DIO3 is high the TXCO is enabled
|
||||
|
||||
#undef RF95_SCK
|
||||
#define RF95_SCK SCK
|
||||
@@ -75,10 +75,9 @@ static const uint8_t SCK = 33;
|
||||
#define RF95_NSS SS
|
||||
|
||||
#define USE_SX1262
|
||||
#define SX126X_CS (SS)// NSS for SX126X
|
||||
#define SX126X_DIO1 (LORA_DIO1)
|
||||
#define SX126X_BUSY (LORA_DIO2)
|
||||
#define SX126X_RESET (LORA_RESET)
|
||||
#define SX126X_TXEN (-1)
|
||||
#define SX126X_RXEN (WB_IO3)
|
||||
#define SX126X_CS SS// NSS for SX126X
|
||||
#define SX126X_DIO1 LORA_DIO1
|
||||
#define SX126X_BUSY LORA_DIO2
|
||||
#define SX126X_RESET LORA_RESET
|
||||
#define SX126X_POWER_EN WB_IO3
|
||||
#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
|
||||
|
||||
@@ -8,7 +8,7 @@ lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
${networking_base.lib_deps}
|
||||
melopero/Melopero RV3028@^1.1.0
|
||||
https://github.com/meshtastic/RAK13800-W5100S.git#b680706eb8006cd62c919ac74c8af1950eb82c81
|
||||
https://github.com/RAKWireless/RAK13800-W5100S.git#1.0.2
|
||||
debug_tool = jlink
|
||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||
;upload_protocol = jlink
|
||||
@@ -17,20 +17,28 @@
|
||||
static const uint8_t TX = 43;
|
||||
static const uint8_t RX = 44;
|
||||
|
||||
// The default Wire will be mapped to PMU and RTC
|
||||
static const uint8_t SDA = 42;
|
||||
static const uint8_t SCL = 41;
|
||||
|
||||
// Default SPI will be mapped to Radio
|
||||
static const uint8_t SS = 10;
|
||||
static const uint8_t MOSI = 11;
|
||||
static const uint8_t MISO = 13;
|
||||
static const uint8_t SCK = 12;
|
||||
|
||||
#define SDMMC_CMD (35)
|
||||
#define SDMMC_CLK (36)
|
||||
#define SDMMC_DATA (37)
|
||||
// Another SPI bus shares SD card and QMI8653 inertial measurement sensor
|
||||
#define SPI_MOSI (35)
|
||||
#define SPI_SCK (36)
|
||||
#define SPI_MISO (37)
|
||||
#define SPI_CS (47)
|
||||
#define IMU_CS (34)
|
||||
|
||||
#define ACCEL_INT1 (34)
|
||||
#define ACCEL_INT2 (33)
|
||||
#define SDCARD_CS SPI_CS
|
||||
#define IMU_INT (33)
|
||||
// #define PMU_IRQ (40)
|
||||
#define RTC_INT (14)
|
||||
|
||||
|
||||
|
||||
#endif /* Pins_Arduino_h */
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
// #define BUTTON_NEED_PULLUP // if set we need to turn on the internal CPU pullup during sleep
|
||||
|
||||
#define I2C_SDA1 42 //Used for PMU management
|
||||
#define I2C_SCL1 41 //Used for PMU management
|
||||
#define I2C_SDA1 42 //Used for PMU management and PCF8563
|
||||
#define I2C_SCL1 41 //Used for PMU management and PCF8563
|
||||
|
||||
#define I2C_SDA 17 //For sensors and screens
|
||||
#define I2C_SCL 18 //For sensors and screens
|
||||
#define I2C_SDA 17 //For QMC6310 sensors and screens
|
||||
#define I2C_SCL 18 //For QMC6310 sensors and screens
|
||||
|
||||
#define BUTTON_PIN 0 // The middle button GPIO on the T-Beam S3
|
||||
//#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented anywhere.
|
||||
// #define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module.
|
||||
|
||||
#define BUTTON1_PIN 47 //Additional keys
|
||||
|
||||
|
||||
#define LED_INVERTED 1
|
||||
// #define LED_PIN 4 // Newer tbeams (1.1) have an extra led on GPIO4
|
||||
|
||||
// TTGO uses a common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if
|
||||
// not found then probe for SX1262
|
||||
@@ -42,8 +40,9 @@
|
||||
// #define PMU_IRQ 40
|
||||
#define HAS_AXP2101
|
||||
|
||||
// Specify the PMU as Wire1. In the t-beam-s3-core, the PMU enjoys a separate bus
|
||||
// Specify the PMU as Wire1. In the t-beam-s3 core, PCF8563 and PMU share the bus
|
||||
#define PMU_USE_WIRE1
|
||||
#define RTC_USE_WIRE1
|
||||
|
||||
#define RF95_SCK 12
|
||||
#define RF95_MISO 13
|
||||
@@ -56,10 +55,14 @@
|
||||
#define GPS_1PPS_PIN 6
|
||||
|
||||
|
||||
#define HAS_SDCARD //Have 3-bit SDMMC interface SD card slot
|
||||
#define HAS_SDCARD //Have SPI interface SD card slot
|
||||
#define SDCARD_USE_SPI1
|
||||
|
||||
// PCF8563 RTC Module
|
||||
// #define PCF8563_RTC 0x51 //Putting definitions in variant. h does not compile correctly
|
||||
|
||||
#define HAS_RTC 1
|
||||
|
||||
//has 32768 Hz crystal
|
||||
#define HAS_32768HZ
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user