mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-16 23:07:34 +00:00
Compare commits
91 Commits
v2.2.12.09
...
v2.2.14.57
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57542ce9e6 | ||
|
|
1b20a82b55 | ||
|
|
195706e0e5 | ||
|
|
c1f5878648 | ||
|
|
7380f3b170 | ||
|
|
a9d846c1b3 | ||
|
|
cfb09ee115 | ||
|
|
8f0ce606db | ||
|
|
d04ff29c2a | ||
|
|
8e92754b59 | ||
|
|
dad824c0e9 | ||
|
|
31d7c6826d | ||
|
|
d33521ee86 | ||
|
|
5ad12fed60 | ||
|
|
4af90eeb39 | ||
|
|
08297bb0b7 | ||
|
|
16ef40b21f | ||
|
|
7ef4abb974 | ||
|
|
297267d037 | ||
|
|
f8e766ebc7 | ||
|
|
7bd2b07024 | ||
|
|
b6ddbd0087 | ||
|
|
dc8903ec42 | ||
|
|
46bd6ca7ba | ||
|
|
9d4af1146e | ||
|
|
5ce6ca25f2 | ||
|
|
f2210d8f8d | ||
|
|
5d917885df | ||
|
|
e99ae64ece | ||
|
|
61f888e952 | ||
|
|
a144d5d6cc | ||
|
|
c3e3569c14 | ||
|
|
b1b5bafdda | ||
|
|
91e399a2b6 | ||
|
|
8b16367597 | ||
|
|
0b9accc3b6 | ||
|
|
590b0bbff4 | ||
|
|
19be230b24 | ||
|
|
8df16ad6a6 | ||
|
|
2d62f00ac3 | ||
|
|
9f93b9ab9d | ||
|
|
fc3200134d | ||
|
|
470264b7f9 | ||
|
|
600541ac25 | ||
|
|
298b383127 | ||
|
|
f57020412e | ||
|
|
4a6cc8fd8c | ||
|
|
45c5e0e730 | ||
|
|
527bffb7e0 | ||
|
|
4c35a7fb7d | ||
|
|
0f9936a0e0 | ||
|
|
40395bef01 | ||
|
|
8b8fffda81 | ||
|
|
4052194dfe | ||
|
|
b36ffe5200 | ||
|
|
a60b4d08bf | ||
|
|
227467f638 | ||
|
|
b388f8edcd | ||
|
|
5075849ec0 | ||
|
|
7f16b6b342 | ||
|
|
762166495f | ||
|
|
00ea6ef5ad | ||
|
|
b5b66f43f2 | ||
|
|
1e71d346ae | ||
|
|
919b2d1e48 | ||
|
|
171cca435e | ||
|
|
e878f55ed3 | ||
|
|
d74cbdaa8b | ||
|
|
3a5b79e4c1 | ||
|
|
9bee35118f | ||
|
|
80f029aa32 | ||
|
|
b75aa79da5 | ||
|
|
49febc0d9d | ||
|
|
85818b8dfd | ||
|
|
7d299b06a7 | ||
|
|
14080d4667 | ||
|
|
8a806efb95 | ||
|
|
ef2d0cb830 | ||
|
|
5e779bfb33 | ||
|
|
498964e04e | ||
|
|
7d0bea267a | ||
|
|
ed1aa9ddb0 | ||
|
|
97a0b164be | ||
|
|
82706a961f | ||
|
|
06a1b079da | ||
|
|
56afed84df | ||
|
|
945fd7a05c | ||
|
|
e9a55fc296 | ||
|
|
472c43aace | ||
|
|
8b5937892b | ||
|
|
8c20fe5ec4 |
45
.github/workflows/build_raspbian.yml
vendored
Normal file
45
.github/workflows/build_raspbian.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
name: Build Raspbian
|
||||||
|
|
||||||
|
on: workflow_call
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-raspbian:
|
||||||
|
runs-on: [self-hosted, linux, ARM64]
|
||||||
|
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: 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
|
||||||
|
|
||||||
|
- name: Build Raspbian
|
||||||
|
run: bin/build-native.sh
|
||||||
|
|
||||||
|
- 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-raspbian-${{ steps.version.outputs.version }}.zip
|
||||||
|
path: |
|
||||||
|
release/meshtasticd_linux_arm64
|
||||||
|
bin/config-dist.yaml
|
||||||
44
.github/workflows/main_matrix.yml
vendored
44
.github/workflows/main_matrix.yml
vendored
@@ -103,7 +103,6 @@ jobs:
|
|||||||
build-nrf52:
|
build-nrf52:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
max-parallel: 2
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- board: rak4631
|
- board: rak4631
|
||||||
@@ -129,6 +128,15 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
board: ${{ matrix.board }}
|
board: ${{ matrix.board }}
|
||||||
|
|
||||||
|
build-raspbian:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
max-parallel: 1
|
||||||
|
uses: ./.github/workflows/build_raspbian.yml
|
||||||
|
|
||||||
|
package-raspbian:
|
||||||
|
uses: ./.github/workflows/package_raspbian.yml
|
||||||
|
|
||||||
build-native:
|
build-native:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -204,7 +212,15 @@ jobs:
|
|||||||
gather-artifacts:
|
gather-artifacts:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs:
|
needs:
|
||||||
[build-esp32, build-esp32-s3, build-nrf52, build-native, build-rpi2040]
|
[
|
||||||
|
build-esp32,
|
||||||
|
build-esp32-s3,
|
||||||
|
build-nrf52,
|
||||||
|
build-raspbian,
|
||||||
|
build-native,
|
||||||
|
build-rpi2040,
|
||||||
|
package-raspbian,
|
||||||
|
]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
@@ -216,12 +232,15 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
path: ./
|
path: ./
|
||||||
|
|
||||||
|
- name: Display structure of downloaded files
|
||||||
|
run: ls -R
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Move files up
|
- name: Move files up
|
||||||
run: mv -b -t ./ ./*tbeam-2*/littlefs*.bin ./*tbeam-2*/bleota.bin ./*tbeam-s3*/bleota-s3.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase.uf2 ./**/firmware-*.uf2 ./**/firmware-*-ota.zip ./**/*.elf ./*native*/*device-*.sh ./*native*/*device-*.bat
|
run: mv -b -t ./ ./*tbeam-2*/littlefs*.bin ./*tbeam-2*/bleota.bin ./*tbeam-s3*/bleota-s3.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase.uf2 ./**/firmware-*.uf2 ./**/firmware-*-ota.zip ./**/*.elf ./*native*/*device-*.sh ./*native*/*device-*.bat ./firmware-raspbian-*/release/meshtasticd_linux_arm64 ./firmware-raspbian-*/bin/config-dist.yaml
|
||||||
|
|
||||||
- name: Repackage in single firmware zip
|
- name: Repackage in single firmware zip
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
@@ -233,6 +252,8 @@ jobs:
|
|||||||
./firmware-*-ota.zip
|
./firmware-*-ota.zip
|
||||||
./device-*.sh
|
./device-*.sh
|
||||||
./device-*.bat
|
./device-*.bat
|
||||||
|
./meshtasticd_linux_arm64
|
||||||
|
./config-dist.yaml
|
||||||
retention-days: 90
|
retention-days: 90
|
||||||
|
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
@@ -294,6 +315,13 @@ jobs:
|
|||||||
name: firmware-${{ steps.version.outputs.version }}
|
name: firmware-${{ steps.version.outputs.version }}
|
||||||
path: ./output
|
path: ./output
|
||||||
|
|
||||||
|
- uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: artifact-deb
|
||||||
|
|
||||||
|
- name: Display structure of downloaded files
|
||||||
|
run: ls -R
|
||||||
|
|
||||||
- name: Device scripts permissions
|
- name: Device scripts permissions
|
||||||
run: |
|
run: |
|
||||||
chmod +x ./output/device-install.sh
|
chmod +x ./output/device-install.sh
|
||||||
@@ -347,6 +375,16 @@ jobs:
|
|||||||
asset_name: debug-elfs-${{ steps.version.outputs.version }}.zip
|
asset_name: debug-elfs-${{ steps.version.outputs.version }}.zip
|
||||||
asset_content_type: application/zip
|
asset_content_type: application/zip
|
||||||
|
|
||||||
|
- name: Add raspbian .deb
|
||||||
|
uses: actions/upload-release-asset@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
|
with:
|
||||||
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
|
asset_path: ./meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
|
||||||
|
asset_name: meshtasticd_${{ steps.version.outputs.version }}_arm64.deb
|
||||||
|
asset_content_type: application/vnd.debian.binary-package
|
||||||
|
|
||||||
- name: Bump version.properties
|
- name: Bump version.properties
|
||||||
run: >-
|
run: >-
|
||||||
bin/bump_version.py
|
bin/bump_version.py
|
||||||
|
|||||||
60
.github/workflows/package_raspbian.yml
vendored
Normal file
60
.github/workflows/package_raspbian.yml
vendored
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
name: Package Raspbian
|
||||||
|
|
||||||
|
on: workflow_call
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-raspbian:
|
||||||
|
uses: ./.github/workflows/build_raspbian.yml
|
||||||
|
|
||||||
|
package-raspbian:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build-raspbian
|
||||||
|
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: Get release version string
|
||||||
|
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- name: Download artifacts
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: firmware-raspbian-${{ steps.version.outputs.version }}.zip
|
||||||
|
|
||||||
|
- name: Display structure of downloaded files
|
||||||
|
run: ls -R
|
||||||
|
|
||||||
|
- name: build .debpkg
|
||||||
|
run: |
|
||||||
|
mkdir -p .debpkg/usr/sbin
|
||||||
|
mkdir -p .debpkg/etc/meshtasticd
|
||||||
|
mkdir -p .debpkg/usr/lib/systemd/system/
|
||||||
|
cp release/meshtasticd_linux_arm64 .debpkg/usr/sbin/meshtasticd
|
||||||
|
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
|
||||||
|
chmod +x .debpkg/usr/sbin/meshtasticd
|
||||||
|
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
|
||||||
|
|
||||||
|
- uses: jiro4989/build-deb-action@v3
|
||||||
|
with:
|
||||||
|
package: meshtasticd
|
||||||
|
package_root: .debpkg
|
||||||
|
maintainer: Jonathan Bennett
|
||||||
|
version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.*
|
||||||
|
arch: arm64
|
||||||
|
depends: libyaml-cpp0.7
|
||||||
|
desc: Native Linux Meshtastic binary.
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: artifact-deb
|
||||||
|
path: |
|
||||||
|
./*.deb
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
enable=all
|
enable=all
|
||||||
source-path=SCRIPTDIR
|
source-path=SCRIPTDIR
|
||||||
disable=SC2154
|
disable=SC2154
|
||||||
|
disable=SC2248
|
||||||
|
disable=SC2250
|
||||||
|
|
||||||
# If you're having issues with shellcheck following source, disable the errors via:
|
# If you're having issues with shellcheck following source, disable the errors via:
|
||||||
# disable=SC1090
|
# disable=SC1090
|
||||||
# disable=SC1091
|
# disable=SC1091
|
||||||
|
#
|
||||||
@@ -3,7 +3,7 @@ rules:
|
|||||||
required: only-when-needed
|
required: only-when-needed
|
||||||
extra-allowed: ["{|}"]
|
extra-allowed: ["{|}"]
|
||||||
empty-values:
|
empty-values:
|
||||||
forbid-in-block-mappings: true
|
forbid-in-block-mappings: false
|
||||||
forbid-in-flow-mappings: true
|
forbid-in-flow-mappings: true
|
||||||
key-duplicates: {}
|
key-duplicates: {}
|
||||||
octal-values:
|
octal-values:
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
version: 0.1
|
version: 0.1
|
||||||
cli:
|
cli:
|
||||||
version: 1.17.0
|
version: 1.17.1
|
||||||
plugins:
|
plugins:
|
||||||
sources:
|
sources:
|
||||||
- id: trunk
|
- id: trunk
|
||||||
ref: v1.2.5
|
ref: v1.2.6
|
||||||
uri: https://github.com/trunk-io/plugins
|
uri: https://github.com/trunk-io/plugins
|
||||||
lint:
|
lint:
|
||||||
enabled:
|
enabled:
|
||||||
- bandit@1.7.5
|
- bandit@1.7.5
|
||||||
- checkov@2.5.0
|
- checkov@3.0.16
|
||||||
- terrascan@1.18.3
|
- terrascan@1.18.3
|
||||||
- trivy@0.45.1
|
- trivy@0.46.1
|
||||||
- trufflehog@3.59.0
|
- trufflehog@3.62.1
|
||||||
- taplo@0.8.1
|
- taplo@0.8.1
|
||||||
- ruff@0.0.292
|
- ruff@0.1.3
|
||||||
- yamllint@1.32.0
|
- yamllint@1.32.0
|
||||||
- isort@5.12.0
|
- isort@5.12.0
|
||||||
- markdownlint@0.37.0
|
- markdownlint@0.37.0
|
||||||
- oxipng@8.0.0
|
- oxipng@9.0.0
|
||||||
- svgo@3.0.2
|
- svgo@3.0.2
|
||||||
- actionlint@1.6.26
|
- actionlint@1.6.26
|
||||||
- flake8@6.1.0
|
- flake8@6.1.0
|
||||||
@@ -30,15 +30,6 @@ lint:
|
|||||||
- gitleaks@8.18.0
|
- gitleaks@8.18.0
|
||||||
- clang-format@16.0.3
|
- clang-format@16.0.3
|
||||||
- prettier@3.0.3
|
- prettier@3.0.3
|
||||||
disabled:
|
|
||||||
- taplo@0.8.1
|
|
||||||
- shellcheck@0.9.0
|
|
||||||
- shfmt@3.6.0
|
|
||||||
- oxipng@8.0.0
|
|
||||||
- actionlint@1.6.22
|
|
||||||
- markdownlint@0.37.0
|
|
||||||
- hadolint@2.12.0
|
|
||||||
- svgo@3.0.2
|
|
||||||
runtimes:
|
runtimes:
|
||||||
enabled:
|
enabled:
|
||||||
- python@3.10.8
|
- python@3.10.8
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
VERSION=`bin/buildinfo.py long`
|
VERSION=$(bin/buildinfo.py long)
|
||||||
SHORT_VERSION=`bin/buildinfo.py short`
|
SHORT_VERSION=$(bin/buildinfo.py short)
|
||||||
|
|
||||||
OUTDIR=release/
|
OUTDIR=release/
|
||||||
|
|
||||||
@@ -13,11 +13,15 @@ mkdir -p $OUTDIR/
|
|||||||
rm -r $OUTDIR/* || true
|
rm -r $OUTDIR/* || true
|
||||||
|
|
||||||
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
|
||||||
platformio pkg update
|
platformio pkg update
|
||||||
|
|
||||||
pio run --environment native
|
if command -v raspi-config &>/dev/null; then
|
||||||
cp .pio/build/native/program $OUTDIR/meshtasticd_linux_amd64
|
pio run --environment raspbian
|
||||||
|
cp .pio/build/raspbian/program $OUTDIR/meshtasticd_linux_arm64
|
||||||
|
else
|
||||||
|
pio run --environment native
|
||||||
|
cp .pio/build/native/program $OUTDIR/meshtasticd_linux_amd64
|
||||||
|
fi
|
||||||
|
|
||||||
cp bin/device-install.* $OUTDIR
|
cp bin/device-install.* $OUTDIR
|
||||||
cp bin/device-update.* $OUTDIR
|
cp bin/device-update.* $OUTDIR
|
||||||
|
|
||||||
|
|||||||
21
bin/config-dist.yaml
Normal file
21
bin/config-dist.yaml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Define your devices here using Broadcom pin numbering
|
||||||
|
# Uncomment the block that corresponds to your hardware
|
||||||
|
---
|
||||||
|
Lora:
|
||||||
|
# Module: sx1262 # Waveshare SX126X XXXM
|
||||||
|
# DIO2_AS_RF_SWITCH: true
|
||||||
|
# CS: 21
|
||||||
|
# IRQ: 16
|
||||||
|
# Busy: 20
|
||||||
|
# Reset: 18
|
||||||
|
|
||||||
|
# Module: sx1262 # Waveshare SX1302 LISTEN ONLY AT THIS TIME!
|
||||||
|
# CS: 7
|
||||||
|
# IRQ: 17
|
||||||
|
# Reset: 22
|
||||||
|
|
||||||
|
# Module: RF95 # Adafruit RFM9x
|
||||||
|
# Reset: 25
|
||||||
|
# CS: 7
|
||||||
|
# IRQ: 22
|
||||||
|
# Busy: 23
|
||||||
9
bin/meshtasticd.service
Normal file
9
bin/meshtasticd.service
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[unit]
|
||||||
|
description=Meshtastic Native Daemon
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/usr/sbin/meshtasticd
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
10
bin/native-install.sh
Executable file
10
bin/native-install.sh
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
cp release/meshtasticd_linux_arm64 /usr/sbin/meshtasticd
|
||||||
|
mkdir /etc/meshtasticd
|
||||||
|
if [[ -f "/etc/meshtasticd/config.yaml" ]]; then
|
||||||
|
cp bin/config-dist.yaml /etc/meshtasticd/config-upgrade.yaml
|
||||||
|
else
|
||||||
|
cp bin/config-dist.yaml /etc/meshtasticd/config.yaml
|
||||||
|
fi
|
||||||
|
cp bin/meshtasticd.service /usr/lib/systemd/system/meshtasticd.service
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
;default_envs = meshtastic-dr-dev
|
;default_envs = meshtastic-dr-dev
|
||||||
;default_envs = m5stack-coreink
|
;default_envs = m5stack-coreink
|
||||||
;default_envs = rak4631
|
;default_envs = rak4631
|
||||||
|
;default_envs = rak10701
|
||||||
default_envs = wio-e5
|
default_envs = wio-e5
|
||||||
|
|
||||||
extra_configs =
|
extra_configs =
|
||||||
@@ -113,6 +114,7 @@ lib_deps =
|
|||||||
https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.5.2400
|
https://github.com/boschsensortec/Bosch-BSEC2-Library#v1.5.2400
|
||||||
boschsensortec/BME68x Sensor Library@^1.1.40407
|
boschsensortec/BME68x Sensor Library@^1.1.40407
|
||||||
adafruit/Adafruit MCP9808 Library@^2.0.0
|
adafruit/Adafruit MCP9808 Library@^2.0.0
|
||||||
|
https://github.com/Tinyu-Zhao/INA3221@^0.0.1
|
||||||
adafruit/Adafruit INA260 Library@^1.5.0
|
adafruit/Adafruit INA260 Library@^1.5.0
|
||||||
adafruit/Adafruit INA219@^1.2.0
|
adafruit/Adafruit INA219@^1.2.0
|
||||||
adafruit/Adafruit SHTC3 Library@^1.0.0
|
adafruit/Adafruit SHTC3 Library@^1.0.0
|
||||||
|
|||||||
Submodule protobufs updated: 6290ee0f6a...c845b7848e
@@ -52,6 +52,7 @@ static const adc_atten_t atten = ADC_ATTENUATION;
|
|||||||
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
|
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
|
||||||
INA260Sensor ina260Sensor;
|
INA260Sensor ina260Sensor;
|
||||||
INA219Sensor ina219Sensor;
|
INA219Sensor ina219Sensor;
|
||||||
|
INA3221Sensor ina3221Sensor;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAS_PMU
|
#ifdef HAS_PMU
|
||||||
@@ -286,6 +287,9 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||||||
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first ==
|
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first ==
|
||||||
config.power.device_battery_ina_address) {
|
config.power.device_battery_ina_address) {
|
||||||
return ina260Sensor.getBusVoltageMv();
|
return ina260Sensor.getBusVoltageMv();
|
||||||
|
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA3221].first ==
|
||||||
|
config.power.device_battery_ina_address) {
|
||||||
|
return ina3221Sensor.getBusVoltageMv();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define REQUIRE_RADIO true // If true, we will fail to start if the radio is not found
|
#define REQUIRE_RADIO true // If true, we will fail to start if the radio is not found
|
||||||
|
|
||||||
/// Convert a preprocessor name into a quoted string
|
/// Convert a preprocessor name into a quoted string
|
||||||
#define xstr(s) str(s)
|
#define xstr(s) ystr(s)
|
||||||
#define str(s) #s
|
#define ystr(s) #s
|
||||||
|
|
||||||
/// Convert a preprocessor name into a quoted string and if that string is empty use "unset"
|
/// Convert a preprocessor name into a quoted string and if that string is empty use "unset"
|
||||||
#define optstr(s) (xstr(s)[0] ? xstr(s) : "unset")
|
#define optstr(s) (xstr(s)[0] ? xstr(s) : "unset")
|
||||||
@@ -111,6 +111,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define MCP9808_ADDR 0x18
|
#define MCP9808_ADDR 0x18
|
||||||
#define INA_ADDR 0x40
|
#define INA_ADDR 0x40
|
||||||
#define INA_ADDR_ALTERNATE 0x41
|
#define INA_ADDR_ALTERNATE 0x41
|
||||||
|
#define INA3221_ADDR 0x42
|
||||||
#define QMC6310_ADDR 0x1C
|
#define QMC6310_ADDR 0x1C
|
||||||
#define QMI8658_ADDR 0x6B
|
#define QMI8658_ADDR 0x6B
|
||||||
#define QMC5883L_ADDR 0x1E
|
#define QMC5883L_ADDR 0x1E
|
||||||
@@ -187,6 +188,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#ifndef HAS_TELEMETRY
|
#ifndef HAS_TELEMETRY
|
||||||
#define HAS_TELEMETRY 0
|
#define HAS_TELEMETRY 0
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef HAS_SENSOR
|
||||||
|
#define HAS_SENSOR 0
|
||||||
|
#endif
|
||||||
#ifndef HAS_RADIO
|
#ifndef HAS_RADIO
|
||||||
#define HAS_RADIO 0
|
#define HAS_RADIO 0
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class ScanI2C
|
|||||||
BMP_280,
|
BMP_280,
|
||||||
INA260,
|
INA260,
|
||||||
INA219,
|
INA219,
|
||||||
|
INA3221,
|
||||||
MCP9808,
|
MCP9808,
|
||||||
SHT31,
|
SHT31,
|
||||||
SHTC3,
|
SHTC3,
|
||||||
|
|||||||
@@ -251,7 +251,10 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
|
|||||||
type = INA219;
|
type = INA219;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case INA3221_ADDR:
|
||||||
|
LOG_INFO("INA3221 sensor found at address 0x%x\n", (uint8_t)addr.address);
|
||||||
|
type = INA3221;
|
||||||
|
break;
|
||||||
case MCP9808_ADDR:
|
case MCP9808_ADDR:
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
|
||||||
if (registerValue == 0x0400) {
|
if (registerValue == 0x0400) {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#ifdef ARCH_PORTDUINO
|
#ifdef ARCH_PORTDUINO
|
||||||
#include "meshUtils.h"
|
#include "meshUtils.h"
|
||||||
|
#include <ctime>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GPS_RESET_MODE
|
#ifndef GPS_RESET_MODE
|
||||||
@@ -16,6 +17,9 @@
|
|||||||
|
|
||||||
#if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32)
|
#if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32)
|
||||||
HardwareSerial *GPS::_serial_gps = &Serial1;
|
HardwareSerial *GPS::_serial_gps = &Serial1;
|
||||||
|
#elif defined(ARCH_RASPBERRY_PI)
|
||||||
|
// need a translation layer to make _serial_gps work with pigpio https://abyz.me.uk/rpi/pigpio/cif.html#serOpen
|
||||||
|
HardwareSerial *GPS::_serial_gps = NULL;
|
||||||
#else
|
#else
|
||||||
HardwareSerial *GPS::_serial_gps = NULL;
|
HardwareSerial *GPS::_serial_gps = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -390,7 +390,7 @@ class Screen : public concurrency::OSThread
|
|||||||
SH1106Wire dispdev;
|
SH1106Wire dispdev;
|
||||||
#elif defined(USE_SSD1306)
|
#elif defined(USE_SSD1306)
|
||||||
SSD1306Wire dispdev;
|
SSD1306Wire dispdev;
|
||||||
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ST7789_CS)
|
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ST7789_CS) || defined(RAK14014)
|
||||||
TFTDisplay dispdev;
|
TFTDisplay dispdev;
|
||||||
#elif defined(USE_EINK)
|
#elif defined(USE_EINK)
|
||||||
EInkDisplay dispdev;
|
EInkDisplay dispdev;
|
||||||
|
|||||||
@@ -105,6 +105,10 @@ class LGFX : public lgfx::LGFX_Device
|
|||||||
|
|
||||||
static LGFX tft;
|
static LGFX tft;
|
||||||
|
|
||||||
|
#elif defined(RAK14014)
|
||||||
|
#include <TFT_eSPI.h>
|
||||||
|
TFT_eSPI tft = TFT_eSPI();
|
||||||
|
|
||||||
#elif defined(ST7789_CS)
|
#elif defined(ST7789_CS)
|
||||||
#include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip
|
#include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip
|
||||||
|
|
||||||
@@ -327,7 +331,7 @@ static TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER)
|
#if defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER) || defined(RAK14014)
|
||||||
#include "SPILock.h"
|
#include "SPILock.h"
|
||||||
#include "TFTDisplay.h"
|
#include "TFTDisplay.h"
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
@@ -393,7 +397,9 @@ void TFTDisplay::sendCommand(uint8_t com)
|
|||||||
#ifdef VTFT_CTRL
|
#ifdef VTFT_CTRL
|
||||||
digitalWrite(VTFT_CTRL, LOW);
|
digitalWrite(VTFT_CTRL, LOW);
|
||||||
#endif
|
#endif
|
||||||
#ifndef M5STACK
|
|
||||||
|
#ifdef RAK14014
|
||||||
|
#elif !defined(M5STACK)
|
||||||
tft.setBrightness(128);
|
tft.setBrightness(128);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
@@ -419,7 +425,8 @@ void TFTDisplay::sendCommand(uint8_t com)
|
|||||||
#ifdef VTFT_CTRL
|
#ifdef VTFT_CTRL
|
||||||
digitalWrite(VTFT_CTRL, HIGH);
|
digitalWrite(VTFT_CTRL, HIGH);
|
||||||
#endif
|
#endif
|
||||||
#ifndef M5STACK
|
#ifdef RAK14014
|
||||||
|
#elif !defined(M5STACK)
|
||||||
tft.setBrightness(0);
|
tft.setBrightness(0);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
@@ -441,7 +448,8 @@ void TFTDisplay::flipScreenVertically()
|
|||||||
|
|
||||||
bool TFTDisplay::hasTouch(void)
|
bool TFTDisplay::hasTouch(void)
|
||||||
{
|
{
|
||||||
#ifndef M5STACK
|
#ifdef RAK14014
|
||||||
|
#elif !defined(M5STACK)
|
||||||
return tft.touch() != nullptr;
|
return tft.touch() != nullptr;
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
@@ -450,7 +458,8 @@ bool TFTDisplay::hasTouch(void)
|
|||||||
|
|
||||||
bool TFTDisplay::getTouch(int16_t *x, int16_t *y)
|
bool TFTDisplay::getTouch(int16_t *x, int16_t *y)
|
||||||
{
|
{
|
||||||
#ifndef M5STACK
|
#ifdef RAK14014
|
||||||
|
#elif !defined(M5STACK)
|
||||||
return tft.getTouch(x, y);
|
return tft.getTouch(x, y);
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
@@ -471,6 +480,9 @@ bool TFTDisplay::connect()
|
|||||||
#ifdef TFT_BL
|
#ifdef TFT_BL
|
||||||
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
|
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
|
||||||
pinMode(TFT_BL, OUTPUT);
|
pinMode(TFT_BL, OUTPUT);
|
||||||
|
// pinMode(PIN_3V3_EN, OUTPUT);
|
||||||
|
// digitalWrite(PIN_3V3_EN, HIGH);
|
||||||
|
LOG_INFO("Power to TFT Backlight\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ST7735_BACKLIGHT_EN_V03
|
#ifdef ST7735_BACKLIGHT_EN_V03
|
||||||
@@ -484,8 +496,13 @@ bool TFTDisplay::connect()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
tft.init();
|
tft.init();
|
||||||
|
|
||||||
#if defined(M5STACK)
|
#if defined(M5STACK)
|
||||||
tft.setRotation(0);
|
tft.setRotation(0);
|
||||||
|
#elif defined(RAK14014)
|
||||||
|
tft.setRotation(1);
|
||||||
|
tft.setSwapBytes(true);
|
||||||
|
// tft.fillScreen(TFT_BLACK);
|
||||||
#elif defined(T_DECK) || defined(PICOMPUTER_S3)
|
#elif defined(T_DECK) || defined(PICOMPUTER_S3)
|
||||||
tft.setRotation(1); // T-Deck has the TFT in landscape
|
tft.setRotation(1); // T-Deck has the TFT in landscape
|
||||||
#elif defined(T_WATCH_S3)
|
#elif defined(T_WATCH_S3)
|
||||||
@@ -494,6 +511,7 @@ bool TFTDisplay::connect()
|
|||||||
tft.setRotation(3); // Orient horizontal and wide underneath the silkscreen name label
|
tft.setRotation(3); // Orient horizontal and wide underneath the silkscreen name label
|
||||||
#endif
|
#endif
|
||||||
tft.fillScreen(TFT_BLACK);
|
tft.fillScreen(TFT_BLACK);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
67
src/main.cpp
67
src/main.cpp
@@ -67,6 +67,14 @@ NRF52Bluetooth *nrf52Bluetooth;
|
|||||||
#include "platform/portduino/SimRadio.h"
|
#include "platform/portduino/SimRadio.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ARCH_RASPBERRY_PI
|
||||||
|
#include "platform/portduino/PiHal.h"
|
||||||
|
#include "platform/portduino/PortduinoGlue.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if HAS_BUTTON
|
#if HAS_BUTTON
|
||||||
#include "ButtonThread.h"
|
#include "ButtonThread.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -128,12 +136,32 @@ std::pair<uint8_t, TwoWire *> nodeTelemetrySensorsMap[_meshtastic_TelemetrySenso
|
|||||||
|
|
||||||
Router *router = NULL; // Users of router don't care what sort of subclass implements that API
|
Router *router = NULL; // Users of router don't care what sort of subclass implements that API
|
||||||
|
|
||||||
|
#ifdef ARCH_RASPBERRY_PI
|
||||||
|
void getPiMacAddr(uint8_t *dmac)
|
||||||
|
{
|
||||||
|
std::fstream macIdentity;
|
||||||
|
macIdentity.open("/sys/kernel/debug/bluetooth/hci0/identity", std::ios::in);
|
||||||
|
std::string macLine;
|
||||||
|
getline(macIdentity, macLine);
|
||||||
|
macIdentity.close();
|
||||||
|
|
||||||
|
dmac[0] = strtol(macLine.substr(0, 2).c_str(), NULL, 16);
|
||||||
|
dmac[1] = strtol(macLine.substr(3, 2).c_str(), NULL, 16);
|
||||||
|
dmac[2] = strtol(macLine.substr(6, 2).c_str(), NULL, 16);
|
||||||
|
dmac[3] = strtol(macLine.substr(9, 2).c_str(), NULL, 16);
|
||||||
|
dmac[4] = strtol(macLine.substr(12, 2).c_str(), NULL, 16);
|
||||||
|
dmac[5] = strtol(macLine.substr(15, 2).c_str(), NULL, 16);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const char *getDeviceName()
|
const char *getDeviceName()
|
||||||
{
|
{
|
||||||
uint8_t dmac[6];
|
uint8_t dmac[6];
|
||||||
|
#ifdef ARCH_RASPBERRY_PI
|
||||||
|
getPiMacAddr(dmac);
|
||||||
|
#else
|
||||||
getMacAddr(dmac);
|
getMacAddr(dmac);
|
||||||
|
#endif
|
||||||
// Meshtastic_ab3c or Shortname_abcd
|
// Meshtastic_ab3c or Shortname_abcd
|
||||||
static char name[20];
|
static char name[20];
|
||||||
snprintf(name, sizeof(name), "%02x%02x", dmac[4], dmac[5]);
|
snprintf(name, sizeof(name), "%02x%02x", dmac[4], dmac[5]);
|
||||||
@@ -502,6 +530,7 @@ void setup()
|
|||||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::BMP_280, meshtastic_TelemetrySensorType_BMP280)
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::BMP_280, meshtastic_TelemetrySensorType_BMP280)
|
||||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::INA260, meshtastic_TelemetrySensorType_INA260)
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::INA260, meshtastic_TelemetrySensorType_INA260)
|
||||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::INA219, meshtastic_TelemetrySensorType_INA219)
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::INA219, meshtastic_TelemetrySensorType_INA219)
|
||||||
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::INA3221, meshtastic_TelemetrySensorType_INA3221)
|
||||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MCP9808, meshtastic_TelemetrySensorType_MCP9808)
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MCP9808, meshtastic_TelemetrySensorType_MCP9808)
|
||||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MCP9808, meshtastic_TelemetrySensorType_MCP9808)
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MCP9808, meshtastic_TelemetrySensorType_MCP9808)
|
||||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHT31, meshtastic_TelemetrySensorType_SHT31)
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHT31, meshtastic_TelemetrySensorType_SHT31)
|
||||||
@@ -661,7 +690,37 @@ void setup()
|
|||||||
digitalWrite(SX126X_ANT_SW, 1);
|
digitalWrite(SX126X_ANT_SW, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HW_SPI1_DEVICE
|
#ifdef ARCH_RASPBERRY_PI
|
||||||
|
if (settingsMap[use_sx1262]) {
|
||||||
|
if (!rIf) {
|
||||||
|
PiHal *RadioLibHAL = new PiHal(1);
|
||||||
|
rIf = new SX1262Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
||||||
|
settingsMap[busy]);
|
||||||
|
if (!rIf->init()) {
|
||||||
|
LOG_ERROR("Failed to find SX1262 radio\n");
|
||||||
|
delete rIf;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
} else {
|
||||||
|
LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (settingsMap[use_rf95]) {
|
||||||
|
if (!rIf) {
|
||||||
|
PiHal *RadioLibHAL = new PiHal(1);
|
||||||
|
rIf = new RF95Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
||||||
|
settingsMap[busy]);
|
||||||
|
if (!rIf->init()) {
|
||||||
|
LOG_ERROR("Failed to find RF95 radio\n");
|
||||||
|
delete rIf;
|
||||||
|
rIf = NULL;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
} else {
|
||||||
|
LOG_INFO("RF95 Radio init succeeded, using RF95 radio\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(HW_SPI1_DEVICE)
|
||||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI1, spiSettings);
|
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI1, spiSettings);
|
||||||
#else // HW_SPI1_DEVICE
|
#else // HW_SPI1_DEVICE
|
||||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
||||||
@@ -707,7 +766,7 @@ void setup()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_SX1262)
|
#if defined(USE_SX1262) && !defined(ARCH_RASPBERRY_PI)
|
||||||
if (!rIf) {
|
if (!rIf) {
|
||||||
rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
|
rIf = new SX1262Interface(RadioLibHAL, SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY);
|
||||||
if (!rIf->init()) {
|
if (!rIf->init()) {
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ extern graphics::Screen *screen;
|
|||||||
|
|
||||||
// Return a human readable string of the form "Meshtastic_ab13"
|
// Return a human readable string of the form "Meshtastic_ab13"
|
||||||
const char *getDeviceName();
|
const char *getDeviceName();
|
||||||
|
void getPiMacAddr(uint8_t *dmac);
|
||||||
|
|
||||||
extern uint32_t timeLastPowered;
|
extern uint32_t timeLastPowered;
|
||||||
|
|
||||||
|
|||||||
@@ -267,14 +267,22 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
|
|||||||
|
|
||||||
void MeshService::sendToPhone(meshtastic_MeshPacket *p)
|
void MeshService::sendToPhone(meshtastic_MeshPacket *p)
|
||||||
{
|
{
|
||||||
|
perhapsDecode(p);
|
||||||
|
|
||||||
if (toPhoneQueue.numFree() == 0) {
|
if (toPhoneQueue.numFree() == 0) {
|
||||||
LOG_WARN("ToPhone queue is full, discarding oldest\n");
|
if (p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP ||
|
||||||
meshtastic_MeshPacket *d = toPhoneQueue.dequeuePtr(0);
|
p->decoded.portnum == meshtastic_PortNum_RANGE_TEST_APP) {
|
||||||
if (d)
|
LOG_WARN("ToPhone queue is full, discarding oldest\n");
|
||||||
releaseToPool(d);
|
meshtastic_MeshPacket *d = toPhoneQueue.dequeuePtr(0);
|
||||||
|
if (d)
|
||||||
|
releaseToPool(d);
|
||||||
|
} else {
|
||||||
|
LOG_WARN("ToPhone queue is full, dropping packet.\n");
|
||||||
|
releaseToPool(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
perhapsDecode(p);
|
|
||||||
assert(toPhoneQueue.enqueue(p, 0));
|
assert(toPhoneQueue.enqueue(p, 0));
|
||||||
fromNum++;
|
fromNum++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -316,13 +316,27 @@ void NodeDB::installDefaultChannels()
|
|||||||
|
|
||||||
void NodeDB::resetNodes()
|
void NodeDB::resetNodes()
|
||||||
{
|
{
|
||||||
devicestate.node_db_lite_count = 0;
|
devicestate.node_db_lite_count = 1;
|
||||||
memset(devicestate.node_db_lite, 0, sizeof(devicestate.node_db_lite));
|
std::fill(&devicestate.node_db_lite[1], &devicestate.node_db_lite[MAX_NUM_NODES - 1], meshtastic_NodeInfoLite());
|
||||||
saveDeviceStateToDisk();
|
saveDeviceStateToDisk();
|
||||||
if (neighborInfoModule && moduleConfig.neighbor_info.enabled)
|
if (neighborInfoModule && moduleConfig.neighbor_info.enabled)
|
||||||
neighborInfoModule->resetNeighbors();
|
neighborInfoModule->resetNeighbors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodeDB::removeNodeByNum(uint nodeNum)
|
||||||
|
{
|
||||||
|
int newPos = 0, removed = 0;
|
||||||
|
for (int i = 0; i < *numMeshNodes; i++) {
|
||||||
|
if (meshNodes[i].num != nodeNum)
|
||||||
|
meshNodes[newPos++] = meshNodes[i];
|
||||||
|
else
|
||||||
|
removed++;
|
||||||
|
}
|
||||||
|
*numMeshNodes -= removed;
|
||||||
|
LOG_DEBUG("NodeDB::removeNodeByNum purged %d entries. Saving changes...\n", removed);
|
||||||
|
saveDeviceStateToDisk();
|
||||||
|
}
|
||||||
|
|
||||||
void NodeDB::cleanupMeshDB()
|
void NodeDB::cleanupMeshDB()
|
||||||
{
|
{
|
||||||
int newPos = 0, removed = 0;
|
int newPos = 0, removed = 0;
|
||||||
@@ -421,7 +435,11 @@ void NodeDB::init()
|
|||||||
*/
|
*/
|
||||||
void NodeDB::pickNewNodeNum()
|
void NodeDB::pickNewNodeNum()
|
||||||
{
|
{
|
||||||
|
#ifdef ARCH_RASPBERRY_PI
|
||||||
|
getPiMacAddr(ourMacAddr); // Make sure ourMacAddr is set
|
||||||
|
#else
|
||||||
getMacAddr(ourMacAddr); // Make sure ourMacAddr is set
|
getMacAddr(ourMacAddr); // Make sure ourMacAddr is set
|
||||||
|
#endif
|
||||||
|
|
||||||
// Pick an initial nodenum based on the macaddr
|
// Pick an initial nodenum based on the macaddr
|
||||||
NodeNum nodeNum = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5];
|
NodeNum nodeNum = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5];
|
||||||
@@ -433,6 +451,7 @@ void NodeDB::pickNewNodeNum()
|
|||||||
LOG_WARN("NOTE! Our desired nodenum 0x%x is invalid or in use, so trying for 0x%x\n", nodeNum, candidate);
|
LOG_WARN("NOTE! Our desired nodenum 0x%x is invalid or in use, so trying for 0x%x\n", nodeNum, candidate);
|
||||||
nodeNum = candidate;
|
nodeNum = candidate;
|
||||||
}
|
}
|
||||||
|
LOG_WARN("Using nodenum 0x%x \n", nodeNum);
|
||||||
|
|
||||||
myNodeInfo.my_node_num = nodeNum;
|
myNodeInfo.my_node_num = nodeNum;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ class NodeDB
|
|||||||
/// Return the number of nodes we've heard from recently (within the last 2 hrs?)
|
/// Return the number of nodes we've heard from recently (within the last 2 hrs?)
|
||||||
size_t getNumOnlineMeshNodes();
|
size_t getNumOnlineMeshNodes();
|
||||||
|
|
||||||
void initConfigIntervals(), initModuleConfigIntervals(), resetNodes();
|
void initConfigIntervals(), initModuleConfigIntervals(), resetNodes(), removeNodeByNum(uint nodeNum);
|
||||||
|
|
||||||
bool factoryReset();
|
bool factoryReset();
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
#include "Router.h"
|
#include "Router.h"
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
/// We clear our old flood record five minute after we see the last of it
|
/// We clear our old flood record 10 minutes after we see the last of it
|
||||||
#define FLOOD_EXPIRE_TIME (5 * 60 * 1000L)
|
#define FLOOD_EXPIRE_TIME (10 * 60 * 1000L)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A record of a recent message broadcast
|
* A record of a recent message broadcast
|
||||||
|
|||||||
@@ -294,6 +294,10 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_detection_sensor_tag;
|
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_detection_sensor_tag;
|
||||||
fromRadioScratch.moduleConfig.payload_variant.detection_sensor = moduleConfig.detection_sensor;
|
fromRadioScratch.moduleConfig.payload_variant.detection_sensor = moduleConfig.detection_sensor;
|
||||||
break;
|
break;
|
||||||
|
case meshtastic_ModuleConfig_ambient_lighting_tag:
|
||||||
|
fromRadioScratch.moduleConfig.which_payload_variant = meshtastic_ModuleConfig_ambient_lighting_tag;
|
||||||
|
fromRadioScratch.moduleConfig.payload_variant.ambient_lighting = moduleConfig.ambient_lighting;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR("Unknown module config type %d\n", config_state);
|
LOG_ERROR("Unknown module config type %d\n", config_state);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,9 +37,6 @@ bool RF95Interface::init()
|
|||||||
{
|
{
|
||||||
RadioLibInterface::init();
|
RadioLibInterface::init();
|
||||||
|
|
||||||
if (power == 0)
|
|
||||||
power = POWER_DEFAULT;
|
|
||||||
|
|
||||||
if (power > MAX_POWER) // This chip has lower power limits than some
|
if (power > MAX_POWER) // This chip has lower power limits than some
|
||||||
power = MAX_POWER;
|
power = MAX_POWER;
|
||||||
|
|
||||||
|
|||||||
@@ -384,27 +384,27 @@ void RadioInterface::applyModemConfig()
|
|||||||
switch (loraConfig.modem_preset) {
|
switch (loraConfig.modem_preset) {
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
|
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
|
||||||
bw = (myRegion->wideLora) ? 812.5 : 250;
|
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||||
cr = 8;
|
cr = 5;
|
||||||
sf = 7;
|
sf = 7;
|
||||||
break;
|
break;
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
|
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
|
||||||
bw = (myRegion->wideLora) ? 812.5 : 250;
|
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||||
cr = 8;
|
cr = 5;
|
||||||
sf = 8;
|
sf = 8;
|
||||||
break;
|
break;
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
|
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
|
||||||
bw = (myRegion->wideLora) ? 812.5 : 250;
|
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||||
cr = 8;
|
cr = 5;
|
||||||
sf = 9;
|
sf = 9;
|
||||||
break;
|
break;
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
|
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
|
||||||
bw = (myRegion->wideLora) ? 812.5 : 250;
|
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||||
cr = 8;
|
cr = 5;
|
||||||
sf = 10;
|
sf = 10;
|
||||||
break;
|
break;
|
||||||
default: // Config_LoRaConfig_ModemPreset_LONG_FAST is default. Gracefully use this is preset is something illegal.
|
default: // Config_LoRaConfig_ModemPreset_LONG_FAST is default. Gracefully use this is preset is something illegal.
|
||||||
bw = (myRegion->wideLora) ? 812.5 : 250;
|
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||||
cr = 8;
|
cr = 5;
|
||||||
sf = 11;
|
sf = 11;
|
||||||
break;
|
break;
|
||||||
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
|
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
|
||||||
@@ -448,7 +448,9 @@ void RadioInterface::applyModemConfig()
|
|||||||
power = myRegion->powerLimit;
|
power = myRegion->powerLimit;
|
||||||
|
|
||||||
if (power == 0)
|
if (power == 0)
|
||||||
power = 17; // Default to default power if we don't have a valid power
|
power = 17; // Default to this power level if we don't have a valid regional power limit (powerLimit of myRegion defaults
|
||||||
|
// to 0, currently no region has an actual power limit of 0 [dBm] so we can assume regions which have this
|
||||||
|
// variable set to 0 don't have a valid power limit)
|
||||||
|
|
||||||
// Set final tx_power back onto config
|
// Set final tx_power back onto config
|
||||||
loraConfig.tx_power = (int8_t)power; // cppcheck-suppress assignmentAddressToInteger
|
loraConfig.tx_power = (int8_t)power; // cppcheck-suppress assignmentAddressToInteger
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class RadioInterface
|
|||||||
|
|
||||||
float bw = 125;
|
float bw = 125;
|
||||||
uint8_t sf = 9;
|
uint8_t sf = 9;
|
||||||
uint8_t cr = 7;
|
uint8_t cr = 5;
|
||||||
/** Slottime is the minimum time to wait, consisting of:
|
/** Slottime is the minimum time to wait, consisting of:
|
||||||
- CAD duration (maximum of SX126x and SX127x);
|
- CAD duration (maximum of SX126x and SX127x);
|
||||||
- roundtrip air propagation time (assuming max. 30km between nodes);
|
- roundtrip air propagation time (assuming max. 30km between nodes);
|
||||||
@@ -223,4 +223,4 @@ class RadioInterface
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Debug printing for packets
|
/// Debug printing for packets
|
||||||
void printPacket(const char *prefix, const meshtastic_MeshPacket *p);
|
void printPacket(const char *prefix, const meshtastic_MeshPacket *p);
|
||||||
@@ -20,9 +20,6 @@ bool STM32WLE5JCInterface::init()
|
|||||||
|
|
||||||
lora.setRfSwitchTable(rfswitch_pins, rfswitch_table);
|
lora.setRfSwitchTable(rfswitch_pins, rfswitch_table);
|
||||||
|
|
||||||
if (power == 0)
|
|
||||||
power = STM32WLx_MAX_POWER;
|
|
||||||
|
|
||||||
if (power > STM32WLx_MAX_POWER) // This chip has lower power limits than some
|
if (power > STM32WLx_MAX_POWER) // This chip has lower power limits than some
|
||||||
power = STM32WLx_MAX_POWER;
|
power = STM32WLx_MAX_POWER;
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "mesh/NodeDB.h"
|
#include "mesh/NodeDB.h"
|
||||||
|
#ifdef ARCH_RASPBERRY_PI
|
||||||
|
#include "PortduinoGlue.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// Particular boards might define a different max power based on what their hardware can do, default to max power output if not
|
// Particular boards might define a different max power based on what their hardware can do, default to max power output if not
|
||||||
// specified (may be dangerous if using external PA and SX126x power config forgotten)
|
// specified (may be dangerous if using external PA and SX126x power config forgotten)
|
||||||
@@ -43,6 +46,7 @@ template <typename T> bool SX126xInterface<T>::init()
|
|||||||
bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC?
|
bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC?
|
||||||
|
|
||||||
RadioLibInterface::init();
|
RadioLibInterface::init();
|
||||||
|
|
||||||
if (power > SX126X_MAX_POWER) // Clamp power to maximum defined level
|
if (power > SX126X_MAX_POWER) // Clamp power to maximum defined level
|
||||||
power = SX126X_MAX_POWER;
|
power = SX126X_MAX_POWER;
|
||||||
|
|
||||||
@@ -73,6 +77,12 @@ template <typename T> bool SX126xInterface<T>::init()
|
|||||||
#ifdef SX126X_DIO2_AS_RF_SWITCH
|
#ifdef SX126X_DIO2_AS_RF_SWITCH
|
||||||
LOG_DEBUG("Setting DIO2 as RF switch\n");
|
LOG_DEBUG("Setting DIO2 as RF switch\n");
|
||||||
bool dio2AsRfSwitch = true;
|
bool dio2AsRfSwitch = true;
|
||||||
|
#elif defined(ARCH_RASPBERRY_PI)
|
||||||
|
bool dio2AsRfSwitch = false;
|
||||||
|
if (settingsMap[dio2_as_rf_switch]) {
|
||||||
|
LOG_DEBUG("Setting DIO2 as RF switch\n");
|
||||||
|
dio2AsRfSwitch = true;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
LOG_DEBUG("Setting DIO2 as not RF switch\n");
|
LOG_DEBUG("Setting DIO2 as not RF switch\n");
|
||||||
bool dio2AsRfSwitch = false;
|
bool dio2AsRfSwitch = false;
|
||||||
@@ -317,4 +327,4 @@ template <typename T> bool SX126xInterface<T>::sleep()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -42,9 +42,6 @@ template <typename T> bool SX128xInterface<T>::init()
|
|||||||
|
|
||||||
RadioLibInterface::init();
|
RadioLibInterface::init();
|
||||||
|
|
||||||
if (power == 0)
|
|
||||||
power = SX128X_MAX_POWER;
|
|
||||||
|
|
||||||
if (power > SX128X_MAX_POWER) // This chip has lower power limits than some
|
if (power > SX128X_MAX_POWER) // This chip has lower power limits than some
|
||||||
power = SX128X_MAX_POWER;
|
power = SX128X_MAX_POWER;
|
||||||
|
|
||||||
|
|||||||
@@ -145,6 +145,8 @@ typedef struct _meshtastic_AdminMessage {
|
|||||||
char set_canned_message_module_messages[201];
|
char set_canned_message_module_messages[201];
|
||||||
/* Set the ringtone for ExternalNotification. */
|
/* Set the ringtone for ExternalNotification. */
|
||||||
char set_ringtone_message[231];
|
char set_ringtone_message[231];
|
||||||
|
/* Remove the node by the specified node-num from the NodeDB on the device */
|
||||||
|
uint32_t remove_by_nodenum;
|
||||||
/* Begins an edit transaction for config, module config, owner, and channel settings changes
|
/* 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) */
|
This will delay the standard *implicit* save to the file system and subsequent reboot behavior until committed (commit_edit_settings) */
|
||||||
bool begin_edit_settings;
|
bool begin_edit_settings;
|
||||||
@@ -226,6 +228,7 @@ extern "C" {
|
|||||||
#define meshtastic_AdminMessage_set_module_config_tag 35
|
#define meshtastic_AdminMessage_set_module_config_tag 35
|
||||||
#define meshtastic_AdminMessage_set_canned_message_module_messages_tag 36
|
#define meshtastic_AdminMessage_set_canned_message_module_messages_tag 36
|
||||||
#define meshtastic_AdminMessage_set_ringtone_message_tag 37
|
#define meshtastic_AdminMessage_set_ringtone_message_tag 37
|
||||||
|
#define meshtastic_AdminMessage_remove_by_nodenum_tag 38
|
||||||
#define meshtastic_AdminMessage_begin_edit_settings_tag 64
|
#define meshtastic_AdminMessage_begin_edit_settings_tag 64
|
||||||
#define meshtastic_AdminMessage_commit_edit_settings_tag 65
|
#define meshtastic_AdminMessage_commit_edit_settings_tag 65
|
||||||
#define meshtastic_AdminMessage_reboot_ota_seconds_tag 95
|
#define meshtastic_AdminMessage_reboot_ota_seconds_tag 95
|
||||||
@@ -262,6 +265,7 @@ 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, 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, STRING, (payload_variant,set_canned_message_module_messages,set_canned_message_module_messages), 36) \
|
||||||
X(a, STATIC, ONEOF, STRING, (payload_variant,set_ringtone_message,set_ringtone_message), 37) \
|
X(a, STATIC, ONEOF, STRING, (payload_variant,set_ringtone_message,set_ringtone_message), 37) \
|
||||||
|
X(a, STATIC, ONEOF, UINT32, (payload_variant,remove_by_nodenum,remove_by_nodenum), 38) \
|
||||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,begin_edit_settings,begin_edit_settings), 64) \
|
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,commit_edit_settings,commit_edit_settings), 65) \
|
||||||
X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_ota_seconds,reboot_ota_seconds), 95) \
|
X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_ota_seconds,reboot_ota_seconds), 95) \
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ typedef struct _meshtastic_Config_NetworkConfig {
|
|||||||
acquire an address via DHCP */
|
acquire an address via DHCP */
|
||||||
char wifi_ssid[33];
|
char wifi_ssid[33];
|
||||||
/* If set, will be use to authenticate to the named wifi */
|
/* If set, will be use to authenticate to the named wifi */
|
||||||
char wifi_psk[64];
|
char wifi_psk[65];
|
||||||
/* NTP server to use if WiFi is conneced, defaults to `0.pool.ntp.org` */
|
/* NTP server to use if WiFi is conneced, defaults to `0.pool.ntp.org` */
|
||||||
char ntp_server[33];
|
char ntp_server[33];
|
||||||
/* Enable Ethernet */
|
/* Enable Ethernet */
|
||||||
@@ -790,10 +790,10 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg;
|
|||||||
#define meshtastic_Config_DisplayConfig_size 28
|
#define meshtastic_Config_DisplayConfig_size 28
|
||||||
#define meshtastic_Config_LoRaConfig_size 77
|
#define meshtastic_Config_LoRaConfig_size 77
|
||||||
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
|
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
|
||||||
#define meshtastic_Config_NetworkConfig_size 195
|
#define meshtastic_Config_NetworkConfig_size 196
|
||||||
#define meshtastic_Config_PositionConfig_size 60
|
#define meshtastic_Config_PositionConfig_size 60
|
||||||
#define meshtastic_Config_PowerConfig_size 40
|
#define meshtastic_Config_PowerConfig_size 40
|
||||||
#define meshtastic_Config_size 198
|
#define meshtastic_Config_size 199
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|||||||
@@ -316,7 +316,7 @@ extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePin_msg;
|
|||||||
#define meshtastic_DeviceState_size 16854
|
#define meshtastic_DeviceState_size 16854
|
||||||
#define meshtastic_NodeInfoLite_size 151
|
#define meshtastic_NodeInfoLite_size 151
|
||||||
#define meshtastic_NodeRemoteHardwarePin_size 29
|
#define meshtastic_NodeRemoteHardwarePin_size 29
|
||||||
#define meshtastic_OEMStore_size 3218
|
#define meshtastic_OEMStore_size 3231
|
||||||
#define meshtastic_PositionLite_size 28
|
#define meshtastic_PositionLite_size 28
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -174,8 +174,8 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
|
|||||||
#define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg
|
#define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg
|
||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define meshtastic_LocalConfig_size 463
|
#define meshtastic_LocalConfig_size 464
|
||||||
#define meshtastic_LocalModuleConfig_size 609
|
#define meshtastic_LocalModuleConfig_size 621
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|||||||
@@ -232,6 +232,9 @@ typedef struct _meshtastic_ModuleConfig_ExternalNotificationConfig {
|
|||||||
Default is 0 which means don't repeat at all. 60 would mean blink
|
Default is 0 which means don't repeat at all. 60 would mean blink
|
||||||
and/or beep for 60 seconds */
|
and/or beep for 60 seconds */
|
||||||
uint16_t nag_timeout;
|
uint16_t nag_timeout;
|
||||||
|
/* When true, enables devices with native I2S audio output to use the RTTTL over speaker like a buzzer
|
||||||
|
T-Watch S3 and T-Deck for example have this capability */
|
||||||
|
bool use_i2s_as_buzzer;
|
||||||
} meshtastic_ModuleConfig_ExternalNotificationConfig;
|
} meshtastic_ModuleConfig_ExternalNotificationConfig;
|
||||||
|
|
||||||
/* Store and Forward Module Config */
|
/* Store and Forward Module Config */
|
||||||
@@ -278,6 +281,15 @@ typedef struct _meshtastic_ModuleConfig_TelemetryConfig {
|
|||||||
/* Interval in seconds of how often we should try to send our
|
/* Interval in seconds of how often we should try to send our
|
||||||
air quality metrics to the mesh */
|
air quality metrics to the mesh */
|
||||||
uint32_t air_quality_interval;
|
uint32_t air_quality_interval;
|
||||||
|
/* Interval in seconds of how often we should try to send our
|
||||||
|
air quality metrics to the mesh */
|
||||||
|
bool power_measurement_enabled;
|
||||||
|
/* Interval in seconds of how often we should try to send our
|
||||||
|
air quality metrics to the mesh */
|
||||||
|
uint32_t power_update_interval;
|
||||||
|
/* Interval in seconds of how often we should try to send our
|
||||||
|
air quality metrics to the mesh */
|
||||||
|
bool power_screen_enabled;
|
||||||
} meshtastic_ModuleConfig_TelemetryConfig;
|
} meshtastic_ModuleConfig_TelemetryConfig;
|
||||||
|
|
||||||
/* TODO: REPLACE */
|
/* TODO: REPLACE */
|
||||||
@@ -431,10 +443,10 @@ extern "C" {
|
|||||||
#define meshtastic_ModuleConfig_DetectionSensorConfig_init_default {0, 0, 0, 0, "", 0, 0, 0}
|
#define meshtastic_ModuleConfig_DetectionSensorConfig_init_default {0, 0, 0, 0, "", 0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_AudioConfig_init_default {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
|
#define meshtastic_ModuleConfig_AudioConfig_init_default {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0}
|
#define meshtastic_ModuleConfig_SerialConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0}
|
||||||
#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_StoreForwardConfig_init_default {0, 0, 0, 0, 0}
|
#define meshtastic_ModuleConfig_StoreForwardConfig_init_default {0, 0, 0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_RangeTestConfig_init_default {0, 0, 0}
|
#define meshtastic_ModuleConfig_RangeTestConfig_init_default {0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_TelemetryConfig_init_default {0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_ModuleConfig_TelemetryConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_CannedMessageConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
|
#define meshtastic_ModuleConfig_CannedMessageConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
|
||||||
#define meshtastic_ModuleConfig_AmbientLightingConfig_init_default {0, 0, 0, 0, 0}
|
#define meshtastic_ModuleConfig_AmbientLightingConfig_init_default {0, 0, 0, 0, 0}
|
||||||
#define meshtastic_RemoteHardwarePin_init_default {0, "", _meshtastic_RemoteHardwarePinType_MIN}
|
#define meshtastic_RemoteHardwarePin_init_default {0, "", _meshtastic_RemoteHardwarePinType_MIN}
|
||||||
@@ -445,10 +457,10 @@ extern "C" {
|
|||||||
#define meshtastic_ModuleConfig_DetectionSensorConfig_init_zero {0, 0, 0, 0, "", 0, 0, 0}
|
#define meshtastic_ModuleConfig_DetectionSensorConfig_init_zero {0, 0, 0, 0, "", 0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_AudioConfig_init_zero {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
|
#define meshtastic_ModuleConfig_AudioConfig_init_zero {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0}
|
#define meshtastic_ModuleConfig_SerialConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_MIN, 0, _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN, 0}
|
||||||
#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_ModuleConfig_ExternalNotificationConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_StoreForwardConfig_init_zero {0, 0, 0, 0, 0}
|
#define meshtastic_ModuleConfig_StoreForwardConfig_init_zero {0, 0, 0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_RangeTestConfig_init_zero {0, 0, 0}
|
#define meshtastic_ModuleConfig_RangeTestConfig_init_zero {0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_TelemetryConfig_init_zero {0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_ModuleConfig_TelemetryConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_CannedMessageConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
|
#define meshtastic_ModuleConfig_CannedMessageConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
|
||||||
#define meshtastic_ModuleConfig_AmbientLightingConfig_init_zero {0, 0, 0, 0, 0}
|
#define meshtastic_ModuleConfig_AmbientLightingConfig_init_zero {0, 0, 0, 0, 0}
|
||||||
#define meshtastic_RemoteHardwarePin_init_zero {0, "", _meshtastic_RemoteHardwarePinType_MIN}
|
#define meshtastic_RemoteHardwarePin_init_zero {0, "", _meshtastic_RemoteHardwarePinType_MIN}
|
||||||
@@ -502,6 +514,7 @@ extern "C" {
|
|||||||
#define meshtastic_ModuleConfig_ExternalNotificationConfig_alert_bell_vibra_tag 12
|
#define meshtastic_ModuleConfig_ExternalNotificationConfig_alert_bell_vibra_tag 12
|
||||||
#define meshtastic_ModuleConfig_ExternalNotificationConfig_alert_bell_buzzer_tag 13
|
#define meshtastic_ModuleConfig_ExternalNotificationConfig_alert_bell_buzzer_tag 13
|
||||||
#define meshtastic_ModuleConfig_ExternalNotificationConfig_nag_timeout_tag 14
|
#define meshtastic_ModuleConfig_ExternalNotificationConfig_nag_timeout_tag 14
|
||||||
|
#define meshtastic_ModuleConfig_ExternalNotificationConfig_use_i2s_as_buzzer_tag 15
|
||||||
#define meshtastic_ModuleConfig_StoreForwardConfig_enabled_tag 1
|
#define meshtastic_ModuleConfig_StoreForwardConfig_enabled_tag 1
|
||||||
#define meshtastic_ModuleConfig_StoreForwardConfig_heartbeat_tag 2
|
#define meshtastic_ModuleConfig_StoreForwardConfig_heartbeat_tag 2
|
||||||
#define meshtastic_ModuleConfig_StoreForwardConfig_records_tag 3
|
#define meshtastic_ModuleConfig_StoreForwardConfig_records_tag 3
|
||||||
@@ -517,6 +530,9 @@ extern "C" {
|
|||||||
#define meshtastic_ModuleConfig_TelemetryConfig_environment_display_fahrenheit_tag 5
|
#define meshtastic_ModuleConfig_TelemetryConfig_environment_display_fahrenheit_tag 5
|
||||||
#define meshtastic_ModuleConfig_TelemetryConfig_air_quality_enabled_tag 6
|
#define meshtastic_ModuleConfig_TelemetryConfig_air_quality_enabled_tag 6
|
||||||
#define meshtastic_ModuleConfig_TelemetryConfig_air_quality_interval_tag 7
|
#define meshtastic_ModuleConfig_TelemetryConfig_air_quality_interval_tag 7
|
||||||
|
#define meshtastic_ModuleConfig_TelemetryConfig_power_measurement_enabled_tag 8
|
||||||
|
#define meshtastic_ModuleConfig_TelemetryConfig_power_update_interval_tag 9
|
||||||
|
#define meshtastic_ModuleConfig_TelemetryConfig_power_screen_enabled_tag 10
|
||||||
#define meshtastic_ModuleConfig_CannedMessageConfig_rotary1_enabled_tag 1
|
#define meshtastic_ModuleConfig_CannedMessageConfig_rotary1_enabled_tag 1
|
||||||
#define meshtastic_ModuleConfig_CannedMessageConfig_inputbroker_pin_a_tag 2
|
#define meshtastic_ModuleConfig_CannedMessageConfig_inputbroker_pin_a_tag 2
|
||||||
#define meshtastic_ModuleConfig_CannedMessageConfig_inputbroker_pin_b_tag 3
|
#define meshtastic_ModuleConfig_CannedMessageConfig_inputbroker_pin_b_tag 3
|
||||||
@@ -657,7 +673,8 @@ X(a, STATIC, SINGULAR, BOOL, alert_message_vibra, 10) \
|
|||||||
X(a, STATIC, SINGULAR, BOOL, alert_message_buzzer, 11) \
|
X(a, STATIC, SINGULAR, BOOL, alert_message_buzzer, 11) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, alert_bell_vibra, 12) \
|
X(a, STATIC, SINGULAR, BOOL, alert_bell_vibra, 12) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, alert_bell_buzzer, 13) \
|
X(a, STATIC, SINGULAR, BOOL, alert_bell_buzzer, 13) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, nag_timeout, 14)
|
X(a, STATIC, SINGULAR, UINT32, nag_timeout, 14) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, use_i2s_as_buzzer, 15)
|
||||||
#define meshtastic_ModuleConfig_ExternalNotificationConfig_CALLBACK NULL
|
#define meshtastic_ModuleConfig_ExternalNotificationConfig_CALLBACK NULL
|
||||||
#define meshtastic_ModuleConfig_ExternalNotificationConfig_DEFAULT NULL
|
#define meshtastic_ModuleConfig_ExternalNotificationConfig_DEFAULT NULL
|
||||||
|
|
||||||
@@ -684,7 +701,10 @@ X(a, STATIC, SINGULAR, BOOL, environment_measurement_enabled, 3) \
|
|||||||
X(a, STATIC, SINGULAR, BOOL, environment_screen_enabled, 4) \
|
X(a, STATIC, SINGULAR, BOOL, environment_screen_enabled, 4) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, environment_display_fahrenheit, 5) \
|
X(a, STATIC, SINGULAR, BOOL, environment_display_fahrenheit, 5) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, air_quality_enabled, 6) \
|
X(a, STATIC, SINGULAR, BOOL, air_quality_enabled, 6) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, air_quality_interval, 7)
|
X(a, STATIC, SINGULAR, UINT32, air_quality_interval, 7) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, power_measurement_enabled, 8) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, power_update_interval, 9) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, power_screen_enabled, 10)
|
||||||
#define meshtastic_ModuleConfig_TelemetryConfig_CALLBACK NULL
|
#define meshtastic_ModuleConfig_TelemetryConfig_CALLBACK NULL
|
||||||
#define meshtastic_ModuleConfig_TelemetryConfig_DEFAULT NULL
|
#define meshtastic_ModuleConfig_TelemetryConfig_DEFAULT NULL
|
||||||
|
|
||||||
@@ -755,14 +775,14 @@ extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg;
|
|||||||
#define meshtastic_ModuleConfig_AudioConfig_size 19
|
#define meshtastic_ModuleConfig_AudioConfig_size 19
|
||||||
#define meshtastic_ModuleConfig_CannedMessageConfig_size 49
|
#define meshtastic_ModuleConfig_CannedMessageConfig_size 49
|
||||||
#define meshtastic_ModuleConfig_DetectionSensorConfig_size 44
|
#define meshtastic_ModuleConfig_DetectionSensorConfig_size 44
|
||||||
#define meshtastic_ModuleConfig_ExternalNotificationConfig_size 40
|
#define meshtastic_ModuleConfig_ExternalNotificationConfig_size 42
|
||||||
#define meshtastic_ModuleConfig_MQTTConfig_size 222
|
#define meshtastic_ModuleConfig_MQTTConfig_size 222
|
||||||
#define meshtastic_ModuleConfig_NeighborInfoConfig_size 8
|
#define meshtastic_ModuleConfig_NeighborInfoConfig_size 8
|
||||||
#define meshtastic_ModuleConfig_RangeTestConfig_size 10
|
#define meshtastic_ModuleConfig_RangeTestConfig_size 10
|
||||||
#define meshtastic_ModuleConfig_RemoteHardwareConfig_size 96
|
#define meshtastic_ModuleConfig_RemoteHardwareConfig_size 96
|
||||||
#define meshtastic_ModuleConfig_SerialConfig_size 28
|
#define meshtastic_ModuleConfig_SerialConfig_size 28
|
||||||
#define meshtastic_ModuleConfig_StoreForwardConfig_size 22
|
#define meshtastic_ModuleConfig_StoreForwardConfig_size 22
|
||||||
#define meshtastic_ModuleConfig_TelemetryConfig_size 26
|
#define meshtastic_ModuleConfig_TelemetryConfig_size 36
|
||||||
#define meshtastic_ModuleConfig_size 225
|
#define meshtastic_ModuleConfig_size 225
|
||||||
#define meshtastic_RemoteHardwarePin_size 21
|
#define meshtastic_RemoteHardwarePin_size 21
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ PB_BIND(meshtastic_DeviceMetrics, meshtastic_DeviceMetrics, AUTO)
|
|||||||
PB_BIND(meshtastic_EnvironmentMetrics, meshtastic_EnvironmentMetrics, AUTO)
|
PB_BIND(meshtastic_EnvironmentMetrics, meshtastic_EnvironmentMetrics, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(meshtastic_PowerMetrics, meshtastic_PowerMetrics, AUTO)
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(meshtastic_AirQualityMetrics, meshtastic_AirQualityMetrics, AUTO)
|
PB_BIND(meshtastic_AirQualityMetrics, meshtastic_AirQualityMetrics, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ typedef enum _meshtastic_TelemetrySensorType {
|
|||||||
/* High accuracy temperature and humidity */
|
/* High accuracy temperature and humidity */
|
||||||
meshtastic_TelemetrySensorType_SHT31 = 12,
|
meshtastic_TelemetrySensorType_SHT31 = 12,
|
||||||
/* PM2.5 air quality sensor */
|
/* PM2.5 air quality sensor */
|
||||||
meshtastic_TelemetrySensorType_PMSA003I = 13
|
meshtastic_TelemetrySensorType_PMSA003I = 13,
|
||||||
|
/* INA3221 3 Channel Voltage / Current Sensor */
|
||||||
|
meshtastic_TelemetrySensorType_INA3221 = 14
|
||||||
} meshtastic_TelemetrySensorType;
|
} meshtastic_TelemetrySensorType;
|
||||||
|
|
||||||
/* Struct definitions */
|
/* Struct definitions */
|
||||||
@@ -65,12 +67,28 @@ typedef struct _meshtastic_EnvironmentMetrics {
|
|||||||
float barometric_pressure;
|
float barometric_pressure;
|
||||||
/* Gas resistance in MOhm measured */
|
/* Gas resistance in MOhm measured */
|
||||||
float gas_resistance;
|
float gas_resistance;
|
||||||
/* Voltage measured */
|
/* Voltage measured (To be depreciated in favor of PowerMetrics in Meshtastic 3.x) */
|
||||||
float voltage;
|
float voltage;
|
||||||
/* Current measured */
|
/* Current measured (To be depreciated in favor of PowerMetrics in Meshtastic 3.x) */
|
||||||
float current;
|
float current;
|
||||||
} meshtastic_EnvironmentMetrics;
|
} meshtastic_EnvironmentMetrics;
|
||||||
|
|
||||||
|
/* Power Metrics (voltage / current / etc) */
|
||||||
|
typedef struct _meshtastic_PowerMetrics {
|
||||||
|
/* Voltage (Ch1) */
|
||||||
|
float ch1_voltage;
|
||||||
|
/* Current (Ch1) */
|
||||||
|
float ch1_current;
|
||||||
|
/* Voltage (Ch2) */
|
||||||
|
float ch2_voltage;
|
||||||
|
/* Current (Ch2) */
|
||||||
|
float ch2_current;
|
||||||
|
/* Voltage (Ch3) */
|
||||||
|
float ch3_voltage;
|
||||||
|
/* Current (Ch3) */
|
||||||
|
float ch3_current;
|
||||||
|
} meshtastic_PowerMetrics;
|
||||||
|
|
||||||
/* Air quality metrics */
|
/* Air quality metrics */
|
||||||
typedef struct _meshtastic_AirQualityMetrics {
|
typedef struct _meshtastic_AirQualityMetrics {
|
||||||
/* Concentration Units Standard PM1.0 */
|
/* Concentration Units Standard PM1.0 */
|
||||||
@@ -111,6 +129,8 @@ typedef struct _meshtastic_Telemetry {
|
|||||||
meshtastic_EnvironmentMetrics environment_metrics;
|
meshtastic_EnvironmentMetrics environment_metrics;
|
||||||
/* Air quality metrics */
|
/* Air quality metrics */
|
||||||
meshtastic_AirQualityMetrics air_quality_metrics;
|
meshtastic_AirQualityMetrics air_quality_metrics;
|
||||||
|
/* Power Metrics */
|
||||||
|
meshtastic_PowerMetrics power_metrics;
|
||||||
} variant;
|
} variant;
|
||||||
} meshtastic_Telemetry;
|
} meshtastic_Telemetry;
|
||||||
|
|
||||||
@@ -121,8 +141,9 @@ extern "C" {
|
|||||||
|
|
||||||
/* Helper constants for enums */
|
/* Helper constants for enums */
|
||||||
#define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET
|
#define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET
|
||||||
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_PMSA003I
|
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_INA3221
|
||||||
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_PMSA003I+1))
|
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_INA3221+1))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -132,10 +153,12 @@ extern "C" {
|
|||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define meshtastic_DeviceMetrics_init_default {0, 0, 0, 0}
|
#define meshtastic_DeviceMetrics_init_default {0, 0, 0, 0}
|
||||||
#define meshtastic_EnvironmentMetrics_init_default {0, 0, 0, 0, 0, 0}
|
#define meshtastic_EnvironmentMetrics_init_default {0, 0, 0, 0, 0, 0}
|
||||||
|
#define meshtastic_PowerMetrics_init_default {0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_AirQualityMetrics_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_AirQualityMetrics_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Telemetry_init_default {0, 0, {meshtastic_DeviceMetrics_init_default}}
|
#define meshtastic_Telemetry_init_default {0, 0, {meshtastic_DeviceMetrics_init_default}}
|
||||||
#define meshtastic_DeviceMetrics_init_zero {0, 0, 0, 0}
|
#define meshtastic_DeviceMetrics_init_zero {0, 0, 0, 0}
|
||||||
#define meshtastic_EnvironmentMetrics_init_zero {0, 0, 0, 0, 0, 0}
|
#define meshtastic_EnvironmentMetrics_init_zero {0, 0, 0, 0, 0, 0}
|
||||||
|
#define meshtastic_PowerMetrics_init_zero {0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_AirQualityMetrics_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_AirQualityMetrics_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Telemetry_init_zero {0, 0, {meshtastic_DeviceMetrics_init_zero}}
|
#define meshtastic_Telemetry_init_zero {0, 0, {meshtastic_DeviceMetrics_init_zero}}
|
||||||
|
|
||||||
@@ -150,6 +173,12 @@ extern "C" {
|
|||||||
#define meshtastic_EnvironmentMetrics_gas_resistance_tag 4
|
#define meshtastic_EnvironmentMetrics_gas_resistance_tag 4
|
||||||
#define meshtastic_EnvironmentMetrics_voltage_tag 5
|
#define meshtastic_EnvironmentMetrics_voltage_tag 5
|
||||||
#define meshtastic_EnvironmentMetrics_current_tag 6
|
#define meshtastic_EnvironmentMetrics_current_tag 6
|
||||||
|
#define meshtastic_PowerMetrics_ch1_voltage_tag 1
|
||||||
|
#define meshtastic_PowerMetrics_ch1_current_tag 2
|
||||||
|
#define meshtastic_PowerMetrics_ch2_voltage_tag 3
|
||||||
|
#define meshtastic_PowerMetrics_ch2_current_tag 4
|
||||||
|
#define meshtastic_PowerMetrics_ch3_voltage_tag 5
|
||||||
|
#define meshtastic_PowerMetrics_ch3_current_tag 6
|
||||||
#define meshtastic_AirQualityMetrics_pm10_standard_tag 1
|
#define meshtastic_AirQualityMetrics_pm10_standard_tag 1
|
||||||
#define meshtastic_AirQualityMetrics_pm25_standard_tag 2
|
#define meshtastic_AirQualityMetrics_pm25_standard_tag 2
|
||||||
#define meshtastic_AirQualityMetrics_pm100_standard_tag 3
|
#define meshtastic_AirQualityMetrics_pm100_standard_tag 3
|
||||||
@@ -166,6 +195,7 @@ extern "C" {
|
|||||||
#define meshtastic_Telemetry_device_metrics_tag 2
|
#define meshtastic_Telemetry_device_metrics_tag 2
|
||||||
#define meshtastic_Telemetry_environment_metrics_tag 3
|
#define meshtastic_Telemetry_environment_metrics_tag 3
|
||||||
#define meshtastic_Telemetry_air_quality_metrics_tag 4
|
#define meshtastic_Telemetry_air_quality_metrics_tag 4
|
||||||
|
#define meshtastic_Telemetry_power_metrics_tag 5
|
||||||
|
|
||||||
/* Struct field encoding specification for nanopb */
|
/* Struct field encoding specification for nanopb */
|
||||||
#define meshtastic_DeviceMetrics_FIELDLIST(X, a) \
|
#define meshtastic_DeviceMetrics_FIELDLIST(X, a) \
|
||||||
@@ -186,6 +216,16 @@ X(a, STATIC, SINGULAR, FLOAT, current, 6)
|
|||||||
#define meshtastic_EnvironmentMetrics_CALLBACK NULL
|
#define meshtastic_EnvironmentMetrics_CALLBACK NULL
|
||||||
#define meshtastic_EnvironmentMetrics_DEFAULT NULL
|
#define meshtastic_EnvironmentMetrics_DEFAULT NULL
|
||||||
|
|
||||||
|
#define meshtastic_PowerMetrics_FIELDLIST(X, a) \
|
||||||
|
X(a, STATIC, SINGULAR, FLOAT, ch1_voltage, 1) \
|
||||||
|
X(a, STATIC, SINGULAR, FLOAT, ch1_current, 2) \
|
||||||
|
X(a, STATIC, SINGULAR, FLOAT, ch2_voltage, 3) \
|
||||||
|
X(a, STATIC, SINGULAR, FLOAT, ch2_current, 4) \
|
||||||
|
X(a, STATIC, SINGULAR, FLOAT, ch3_voltage, 5) \
|
||||||
|
X(a, STATIC, SINGULAR, FLOAT, ch3_current, 6)
|
||||||
|
#define meshtastic_PowerMetrics_CALLBACK NULL
|
||||||
|
#define meshtastic_PowerMetrics_DEFAULT NULL
|
||||||
|
|
||||||
#define meshtastic_AirQualityMetrics_FIELDLIST(X, a) \
|
#define meshtastic_AirQualityMetrics_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, pm10_standard, 1) \
|
X(a, STATIC, SINGULAR, UINT32, pm10_standard, 1) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, pm25_standard, 2) \
|
X(a, STATIC, SINGULAR, UINT32, pm25_standard, 2) \
|
||||||
@@ -206,21 +246,25 @@ X(a, STATIC, SINGULAR, UINT32, particles_100um, 12)
|
|||||||
X(a, STATIC, SINGULAR, FIXED32, time, 1) \
|
X(a, STATIC, SINGULAR, FIXED32, time, 1) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,device_metrics,variant.device_metrics), 2) \
|
X(a, STATIC, ONEOF, MESSAGE, (variant,device_metrics,variant.device_metrics), 2) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,environment_metrics,variant.environment_metrics), 3) \
|
X(a, STATIC, ONEOF, MESSAGE, (variant,environment_metrics,variant.environment_metrics), 3) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (variant,air_quality_metrics,variant.air_quality_metrics), 4)
|
X(a, STATIC, ONEOF, MESSAGE, (variant,air_quality_metrics,variant.air_quality_metrics), 4) \
|
||||||
|
X(a, STATIC, ONEOF, MESSAGE, (variant,power_metrics,variant.power_metrics), 5)
|
||||||
#define meshtastic_Telemetry_CALLBACK NULL
|
#define meshtastic_Telemetry_CALLBACK NULL
|
||||||
#define meshtastic_Telemetry_DEFAULT NULL
|
#define meshtastic_Telemetry_DEFAULT NULL
|
||||||
#define meshtastic_Telemetry_variant_device_metrics_MSGTYPE meshtastic_DeviceMetrics
|
#define meshtastic_Telemetry_variant_device_metrics_MSGTYPE meshtastic_DeviceMetrics
|
||||||
#define meshtastic_Telemetry_variant_environment_metrics_MSGTYPE meshtastic_EnvironmentMetrics
|
#define meshtastic_Telemetry_variant_environment_metrics_MSGTYPE meshtastic_EnvironmentMetrics
|
||||||
#define meshtastic_Telemetry_variant_air_quality_metrics_MSGTYPE meshtastic_AirQualityMetrics
|
#define meshtastic_Telemetry_variant_air_quality_metrics_MSGTYPE meshtastic_AirQualityMetrics
|
||||||
|
#define meshtastic_Telemetry_variant_power_metrics_MSGTYPE meshtastic_PowerMetrics
|
||||||
|
|
||||||
extern const pb_msgdesc_t meshtastic_DeviceMetrics_msg;
|
extern const pb_msgdesc_t meshtastic_DeviceMetrics_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_EnvironmentMetrics_msg;
|
extern const pb_msgdesc_t meshtastic_EnvironmentMetrics_msg;
|
||||||
|
extern const pb_msgdesc_t meshtastic_PowerMetrics_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_AirQualityMetrics_msg;
|
extern const pb_msgdesc_t meshtastic_AirQualityMetrics_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_Telemetry_msg;
|
extern const pb_msgdesc_t meshtastic_Telemetry_msg;
|
||||||
|
|
||||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||||
#define meshtastic_DeviceMetrics_fields &meshtastic_DeviceMetrics_msg
|
#define meshtastic_DeviceMetrics_fields &meshtastic_DeviceMetrics_msg
|
||||||
#define meshtastic_EnvironmentMetrics_fields &meshtastic_EnvironmentMetrics_msg
|
#define meshtastic_EnvironmentMetrics_fields &meshtastic_EnvironmentMetrics_msg
|
||||||
|
#define meshtastic_PowerMetrics_fields &meshtastic_PowerMetrics_msg
|
||||||
#define meshtastic_AirQualityMetrics_fields &meshtastic_AirQualityMetrics_msg
|
#define meshtastic_AirQualityMetrics_fields &meshtastic_AirQualityMetrics_msg
|
||||||
#define meshtastic_Telemetry_fields &meshtastic_Telemetry_msg
|
#define meshtastic_Telemetry_fields &meshtastic_Telemetry_msg
|
||||||
|
|
||||||
@@ -228,6 +272,7 @@ extern const pb_msgdesc_t meshtastic_Telemetry_msg;
|
|||||||
#define meshtastic_AirQualityMetrics_size 72
|
#define meshtastic_AirQualityMetrics_size 72
|
||||||
#define meshtastic_DeviceMetrics_size 21
|
#define meshtastic_DeviceMetrics_size 21
|
||||||
#define meshtastic_EnvironmentMetrics_size 30
|
#define meshtastic_EnvironmentMetrics_size 30
|
||||||
|
#define meshtastic_PowerMetrics_size 30
|
||||||
#define meshtastic_Telemetry_size 79
|
#define meshtastic_Telemetry_size 79
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -144,8 +144,8 @@ void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
For documentation, see:
|
For documentation, see:
|
||||||
https://meshtastic.org/docs/developers/device/http-api
|
https://meshtastic.org/docs/development/device/http-api
|
||||||
https://meshtastic.org/docs/developers/device/device-api
|
https://meshtastic.org/docs/development/device/client-api
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Get access to the parameters
|
// Get access to the parameters
|
||||||
@@ -194,8 +194,8 @@ void handleAPIv1ToRadio(HTTPRequest *req, HTTPResponse *res)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
For documentation, see:
|
For documentation, see:
|
||||||
https://meshtastic.org/docs/developers/device/http-api
|
https://meshtastic.org/docs/development/device/http-api
|
||||||
https://meshtastic.org/docs/developers/device/device-api
|
https://meshtastic.org/docs/development/device/client-api
|
||||||
*/
|
*/
|
||||||
|
|
||||||
res->setHeader("Content-Type", "application/x-protobuf");
|
res->setHeader("Content-Type", "application/x-protobuf");
|
||||||
|
|||||||
@@ -182,6 +182,12 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case meshtastic_AdminMessage_remove_by_nodenum_tag: {
|
||||||
|
LOG_INFO("Client is receiving a remove_nodenum command.\n");
|
||||||
|
nodeDB.removeNodeByNum(r->remove_by_nodenum);
|
||||||
|
reboot(DEFAULT_REBOOT_SECONDS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
#ifdef ARCH_PORTDUINO
|
#ifdef ARCH_PORTDUINO
|
||||||
case meshtastic_AdminMessage_exit_simulator_tag:
|
case meshtastic_AdminMessage_exit_simulator_tag:
|
||||||
LOG_INFO("Exiting simulator\n");
|
LOG_INFO("Exiting simulator\n");
|
||||||
@@ -378,6 +384,11 @@ void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
|
|||||||
moduleConfig.has_detection_sensor = true;
|
moduleConfig.has_detection_sensor = true;
|
||||||
moduleConfig.detection_sensor = c.payload_variant.detection_sensor;
|
moduleConfig.detection_sensor = c.payload_variant.detection_sensor;
|
||||||
break;
|
break;
|
||||||
|
case meshtastic_ModuleConfig_ambient_lighting_tag:
|
||||||
|
LOG_INFO("Setting module config: Ambient Lighting\n");
|
||||||
|
moduleConfig.has_ambient_lighting = true;
|
||||||
|
moduleConfig.ambient_lighting = c.payload_variant.ambient_lighting;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveChanges(SEGMENT_MODULECONFIG);
|
saveChanges(SEGMENT_MODULECONFIG);
|
||||||
@@ -523,6 +534,11 @@ void AdminModule::handleGetModuleConfig(const meshtastic_MeshPacket &req, const
|
|||||||
res.get_module_config_response.which_payload_variant = meshtastic_ModuleConfig_detection_sensor_tag;
|
res.get_module_config_response.which_payload_variant = meshtastic_ModuleConfig_detection_sensor_tag;
|
||||||
res.get_module_config_response.payload_variant.detection_sensor = moduleConfig.detection_sensor;
|
res.get_module_config_response.payload_variant.detection_sensor = moduleConfig.detection_sensor;
|
||||||
break;
|
break;
|
||||||
|
case meshtastic_AdminMessage_ModuleConfigType_AMBIENTLIGHTING_CONFIG:
|
||||||
|
LOG_INFO("Getting module config: Ambient Lighting\n");
|
||||||
|
res.get_module_config_response.which_payload_variant = meshtastic_ModuleConfig_ambient_lighting_tag;
|
||||||
|
res.get_module_config_response.payload_variant.ambient_lighting = moduleConfig.ambient_lighting;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: The phone app needs to know the ls_secsvalue so it can properly expect sleep behavior.
|
// NOTE: The phone app needs to know the ls_secsvalue so it can properly expect sleep behavior.
|
||||||
@@ -676,7 +692,7 @@ void AdminModule::handleSetHamMode(const meshtastic_HamParameters &p)
|
|||||||
channels.onConfigChanged();
|
channels.onConfigChanged();
|
||||||
|
|
||||||
service.reloadOwner(false);
|
service.reloadOwner(false);
|
||||||
service.reloadConfig(SEGMENT_CONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
|
saveChanges(SEGMENT_CONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS);
|
||||||
}
|
}
|
||||||
|
|
||||||
AdminModule::AdminModule() : ProtobufModule("Admin", meshtastic_PortNum_ADMIN_APP, &meshtastic_AdminMessage_msg)
|
AdminModule::AdminModule() : ProtobufModule("Admin", meshtastic_PortNum_ADMIN_APP, &meshtastic_AdminMessage_msg)
|
||||||
|
|||||||
@@ -28,6 +28,12 @@ int32_t DetectionSensorModule::runOnce()
|
|||||||
return disable();
|
return disable();
|
||||||
|
|
||||||
if (firstTime) {
|
if (firstTime) {
|
||||||
|
|
||||||
|
#ifdef DETECTION_SENSOR_EN
|
||||||
|
pinMode(DETECTION_SENSOR_EN, OUTPUT);
|
||||||
|
digitalWrite(DETECTION_SENSOR_EN, HIGH);
|
||||||
|
#endif
|
||||||
|
|
||||||
// This is the first time the OSThread library has called this function, so do some setup
|
// This is the first time the OSThread library has called this function, so do some setup
|
||||||
firstTime = false;
|
firstTime = false;
|
||||||
if (moduleConfig.detection_sensor.monitor_pin > 0) {
|
if (moduleConfig.detection_sensor.monitor_pin > 0) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
* handle the module's behavior.
|
* handle the module's behavior.
|
||||||
*
|
*
|
||||||
* Documentation:
|
* Documentation:
|
||||||
* https://meshtastic.org/docs/settings/moduleconfig/external-notification
|
* https://meshtastic.org/docs/configuration/module/external-notification
|
||||||
*
|
*
|
||||||
* @author Jm Casler & Meshtastic Team
|
* @author Jm Casler & Meshtastic Team
|
||||||
* @date [Insert Date]
|
* @date [Insert Date]
|
||||||
@@ -31,6 +31,10 @@
|
|||||||
uint8_t red = 0;
|
uint8_t red = 0;
|
||||||
uint8_t green = 0;
|
uint8_t green = 0;
|
||||||
uint8_t blue = 0;
|
uint8_t blue = 0;
|
||||||
|
uint8_t colorState = 1;
|
||||||
|
uint8_t brightnessIndex = 0;
|
||||||
|
uint8_t brightnessValues[] = {0, 10, 20, 30, 50, 90, 160, 170}; // blue gets multiplied by 1.5
|
||||||
|
bool ascending = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PIN_BUZZER
|
#ifndef PIN_BUZZER
|
||||||
@@ -39,7 +43,7 @@ uint8_t blue = 0;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Documentation:
|
Documentation:
|
||||||
https://meshtastic.org/docs/settings/moduleconfig/external-notification
|
https://meshtastic.org/docs/configuration/module/external-notification
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Default configurations
|
// Default configurations
|
||||||
@@ -100,11 +104,26 @@ int32_t ExternalNotificationModule::runOnce()
|
|||||||
}
|
}
|
||||||
#ifdef HAS_NCP5623
|
#ifdef HAS_NCP5623
|
||||||
if (rgb_found.type == ScanI2C::NCP5623) {
|
if (rgb_found.type == ScanI2C::NCP5623) {
|
||||||
green = (green + 50) % 255;
|
red = (colorState & 4) ? brightnessValues[brightnessIndex] : 0; // Red enabled on colorState = 4,5,6,7
|
||||||
red = abs(red - green) % 255;
|
green = (colorState & 2) ? brightnessValues[brightnessIndex] : 0; // Green enabled on colorState = 2,3,6,7
|
||||||
blue = abs(blue / red) % 255;
|
blue = (colorState & 1) ? (brightnessValues[brightnessIndex] * 1.5) : 0; // Blue enabled on colorState = 1,3,5,7
|
||||||
|
|
||||||
rgb.setColor(red, green, blue);
|
rgb.setColor(red, green, blue);
|
||||||
|
|
||||||
|
if (ascending) { // fade in
|
||||||
|
brightnessIndex++;
|
||||||
|
if (brightnessIndex == (sizeof(brightnessValues) - 1)) {
|
||||||
|
ascending = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
brightnessIndex--; // fade out
|
||||||
|
}
|
||||||
|
if (brightnessIndex == 0) {
|
||||||
|
ascending = true;
|
||||||
|
colorState++; // next color
|
||||||
|
if (colorState > 7) {
|
||||||
|
colorState = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,9 @@
|
|||||||
#include "modules/Telemetry/AirQualityTelemetry.h"
|
#include "modules/Telemetry/AirQualityTelemetry.h"
|
||||||
#include "modules/Telemetry/EnvironmentTelemetry.h"
|
#include "modules/Telemetry/EnvironmentTelemetry.h"
|
||||||
#endif
|
#endif
|
||||||
|
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
|
||||||
|
#include "modules/Telemetry/PowerTelemetry.h"
|
||||||
|
#endif
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
#include "modules/esp32/AudioModule.h"
|
#include "modules/esp32/AudioModule.h"
|
||||||
#include "modules/esp32/StoreForwardModule.h"
|
#include "modules/esp32/StoreForwardModule.h"
|
||||||
@@ -92,6 +95,9 @@ void setupModules()
|
|||||||
new AirQualityTelemetryModule();
|
new AirQualityTelemetryModule();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
|
||||||
|
new PowerTelemetryModule();
|
||||||
|
#endif
|
||||||
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
|
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)) && !defined(CONFIG_IDF_TARGET_ESP32S2) && \
|
||||||
!defined(CONFIG_IDF_TARGET_ESP32C3)
|
!defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||||
new SerialModule();
|
new SerialModule();
|
||||||
|
|||||||
235
src/modules/Telemetry/PowerTelemetry.cpp
Normal file
235
src/modules/Telemetry/PowerTelemetry.cpp
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
#include "PowerTelemetry.h"
|
||||||
|
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||||
|
#include "MeshService.h"
|
||||||
|
#include "NodeDB.h"
|
||||||
|
#include "PowerFSM.h"
|
||||||
|
#include "RTC.h"
|
||||||
|
#include "Router.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "power.h"
|
||||||
|
#include "sleep.h"
|
||||||
|
#include "target_specific.h"
|
||||||
|
|
||||||
|
#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
|
||||||
|
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
|
||||||
|
|
||||||
|
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)) && \
|
||||||
|
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||||
|
|
||||||
|
// The screen is bigger so use bigger fonts
|
||||||
|
#define FONT_SMALL ArialMT_Plain_16
|
||||||
|
#define FONT_MEDIUM ArialMT_Plain_24
|
||||||
|
#define FONT_LARGE ArialMT_Plain_24
|
||||||
|
#else
|
||||||
|
#define FONT_SMALL ArialMT_Plain_10
|
||||||
|
#define FONT_MEDIUM ArialMT_Plain_16
|
||||||
|
#define FONT_LARGE ArialMT_Plain_24
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define fontHeight(font) ((font)[1] + 1) // height is position 1
|
||||||
|
|
||||||
|
#define FONT_HEIGHT_SMALL fontHeight(FONT_SMALL)
|
||||||
|
#define FONT_HEIGHT_MEDIUM fontHeight(FONT_MEDIUM)
|
||||||
|
|
||||||
|
int32_t PowerTelemetryModule::runOnce()
|
||||||
|
{
|
||||||
|
if (sleepOnNextExecution == true) {
|
||||||
|
sleepOnNextExecution = false;
|
||||||
|
uint32_t nightyNightMs = getConfiguredOrDefaultMs(moduleConfig.telemetry.power_update_interval);
|
||||||
|
LOG_DEBUG("Sleeping for %ims, then awaking to send metrics again.\n", nightyNightMs);
|
||||||
|
doDeepSleep(nightyNightMs, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t result = UINT32_MAX;
|
||||||
|
/*
|
||||||
|
Uncomment the preferences below if you want to use the module
|
||||||
|
without having to configure it from the PythonAPI or WebUI.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// moduleConfig.telemetry.power_measurement_enabled = 1;
|
||||||
|
// moduleConfig.telemetry.power_screen_enabled = 1;
|
||||||
|
// moduleConfig.telemetry.power_update_interval = 45;
|
||||||
|
|
||||||
|
if (!(moduleConfig.telemetry.power_measurement_enabled)) {
|
||||||
|
// If this module is not enabled, and the user doesn't want the display screen don't waste any OSThread time on it
|
||||||
|
return disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstTime) {
|
||||||
|
// This is the first time the OSThread library has called this function, so do some setup
|
||||||
|
firstTime = 0;
|
||||||
|
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
|
||||||
|
if (moduleConfig.telemetry.power_measurement_enabled) {
|
||||||
|
LOG_INFO("Power Telemetry: Initializing\n");
|
||||||
|
// it's possible to have this module enabled, only for displaying values on the screen.
|
||||||
|
// therefore, we should only enable the sensor loop if measurement is also enabled
|
||||||
|
if (ina219Sensor.hasSensor() && !ina219Sensor.isInitialized())
|
||||||
|
result = ina219Sensor.runOnce();
|
||||||
|
if (ina260Sensor.hasSensor() && !ina260Sensor.isInitialized())
|
||||||
|
result = ina260Sensor.runOnce();
|
||||||
|
if (ina3221Sensor.hasSensor() && !ina3221Sensor.isInitialized())
|
||||||
|
result = ina3221Sensor.runOnce();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
|
return disable();
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
// if we somehow got to a second run of this module with measurement disabled, then just wait forever
|
||||||
|
if (!moduleConfig.telemetry.power_measurement_enabled)
|
||||||
|
return disable();
|
||||||
|
|
||||||
|
uint32_t now = millis();
|
||||||
|
if (((lastSentToMesh == 0) ||
|
||||||
|
((now - lastSentToMesh) >= getConfiguredOrDefaultMs(moduleConfig.telemetry.power_update_interval))) &&
|
||||||
|
airTime->isTxAllowedAirUtil()) {
|
||||||
|
sendTelemetry();
|
||||||
|
lastSentToMesh = now;
|
||||||
|
} else if (((lastSentToPhone == 0) || ((now - lastSentToPhone) >= sendToPhoneIntervalMs)) &&
|
||||||
|
(service.isToPhoneQueueEmpty())) {
|
||||||
|
// Just send to phone when it's not our time to send to mesh yet
|
||||||
|
// Only send while queue is empty (phone assumed connected)
|
||||||
|
sendTelemetry(NODENUM_BROADCAST, true);
|
||||||
|
lastSentToPhone = now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return min(sendToPhoneIntervalMs, result);
|
||||||
|
}
|
||||||
|
bool PowerTelemetryModule::wantUIFrame()
|
||||||
|
{
|
||||||
|
return moduleConfig.telemetry.power_screen_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t GetTimeyWimeySinceMeshPacket(const meshtastic_MeshPacket *mp)
|
||||||
|
{
|
||||||
|
uint32_t now = getTime();
|
||||||
|
|
||||||
|
uint32_t last_seen = mp->rx_time;
|
||||||
|
int delta = (int)(now - last_seen);
|
||||||
|
if (delta < 0) // our clock must be slightly off still - not set from GPS yet
|
||||||
|
delta = 0;
|
||||||
|
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
|
{
|
||||||
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||||
|
display->setFont(FONT_MEDIUM);
|
||||||
|
display->drawString(x, y, "Power Telemetry");
|
||||||
|
if (lastMeasurementPacket == nullptr) {
|
||||||
|
display->setFont(FONT_SMALL);
|
||||||
|
display->drawString(x, y += fontHeight(FONT_MEDIUM), "No measurement");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
meshtastic_Telemetry lastMeasurement;
|
||||||
|
|
||||||
|
uint32_t agoSecs = GetTimeyWimeySinceMeshPacket(lastMeasurementPacket);
|
||||||
|
const char *lastSender = getSenderShortName(*lastMeasurementPacket);
|
||||||
|
|
||||||
|
auto &p = lastMeasurementPacket->decoded;
|
||||||
|
if (!pb_decode_from_bytes(p.payload.bytes, p.payload.size, &meshtastic_Telemetry_msg, &lastMeasurement)) {
|
||||||
|
display->setFont(FONT_SMALL);
|
||||||
|
display->drawString(x, y += fontHeight(FONT_MEDIUM), "Measurement Error");
|
||||||
|
LOG_ERROR("Unable to decode last packet");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
display->setFont(FONT_SMALL);
|
||||||
|
String last_temp = String(lastMeasurement.variant.environment_metrics.temperature, 0) + "°C";
|
||||||
|
display->drawString(x, y += fontHeight(FONT_MEDIUM) - 2, "From: " + String(lastSender) + "(" + String(agoSecs) + "s)");
|
||||||
|
if (lastMeasurement.variant.power_metrics.ch1_voltage != 0) {
|
||||||
|
display->drawString(x, y += fontHeight(FONT_SMALL),
|
||||||
|
"Ch 1 Volt/Cur: " + String(lastMeasurement.variant.power_metrics.ch1_voltage, 0) + "V / " +
|
||||||
|
String(lastMeasurement.variant.power_metrics.ch1_current, 0) + "mA");
|
||||||
|
display->drawString(x, y += fontHeight(FONT_SMALL),
|
||||||
|
"Ch 2 Volt/Cur: " + String(lastMeasurement.variant.power_metrics.ch2_voltage, 0) + "V / " +
|
||||||
|
String(lastMeasurement.variant.power_metrics.ch2_current, 0) + "mA");
|
||||||
|
display->drawString(x, y += fontHeight(FONT_SMALL),
|
||||||
|
"Ch 3 Volt/Cur: " + String(lastMeasurement.variant.power_metrics.ch3_voltage, 0) + "V / " +
|
||||||
|
String(lastMeasurement.variant.power_metrics.ch3_current, 0) + "mA");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PowerTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t)
|
||||||
|
{
|
||||||
|
if (t->which_variant == meshtastic_Telemetry_power_metrics_tag) {
|
||||||
|
#ifdef DEBUG_PORT
|
||||||
|
const char *sender = getSenderShortName(mp);
|
||||||
|
|
||||||
|
LOG_INFO("(Received from %s): ch1_voltage=%f, ch1_current=%f, ch2_voltage=%f, ch2_current=%f, "
|
||||||
|
"ch3_voltage=%f, ch3_current=%f\n",
|
||||||
|
sender, t->variant.power_metrics.ch1_voltage, t->variant.power_metrics.ch1_current,
|
||||||
|
t->variant.power_metrics.ch2_voltage, t->variant.power_metrics.ch2_current, t->variant.power_metrics.ch3_voltage,
|
||||||
|
t->variant.power_metrics.ch3_current);
|
||||||
|
#endif
|
||||||
|
// release previous packet before occupying a new spot
|
||||||
|
if (lastMeasurementPacket != nullptr)
|
||||||
|
packetPool.release(lastMeasurementPacket);
|
||||||
|
|
||||||
|
lastMeasurementPacket = packetPool.allocCopy(mp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; // Let others look at this message also if they want
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PowerTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
|
||||||
|
{
|
||||||
|
meshtastic_Telemetry m;
|
||||||
|
bool valid = false;
|
||||||
|
m.time = getTime();
|
||||||
|
m.which_variant = meshtastic_Telemetry_power_metrics_tag;
|
||||||
|
|
||||||
|
m.variant.power_metrics.ch1_voltage = 0;
|
||||||
|
m.variant.power_metrics.ch1_current = 0;
|
||||||
|
m.variant.power_metrics.ch2_voltage = 0;
|
||||||
|
m.variant.power_metrics.ch2_current = 0;
|
||||||
|
m.variant.power_metrics.ch3_voltage = 0;
|
||||||
|
m.variant.power_metrics.ch3_current = 0;
|
||||||
|
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
|
||||||
|
if (ina219Sensor.hasSensor())
|
||||||
|
valid = ina219Sensor.getMetrics(&m);
|
||||||
|
if (ina260Sensor.hasSensor())
|
||||||
|
valid = ina260Sensor.getMetrics(&m);
|
||||||
|
if (ina3221Sensor.hasSensor())
|
||||||
|
valid = ina3221Sensor.getMetrics(&m);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (valid) {
|
||||||
|
LOG_INFO("(Sending): ch1_voltage=%f, ch1_current=%f, ch2_voltage=%f, ch2_current=%f, "
|
||||||
|
"ch3_voltage=%f, ch3_current=%f\n",
|
||||||
|
m.variant.power_metrics.ch1_voltage, m.variant.power_metrics.ch1_current, m.variant.power_metrics.ch2_voltage,
|
||||||
|
m.variant.power_metrics.ch2_current, m.variant.power_metrics.ch3_voltage, m.variant.power_metrics.ch3_current);
|
||||||
|
|
||||||
|
sensor_read_error_count = 0;
|
||||||
|
|
||||||
|
meshtastic_MeshPacket *p = allocDataProtobuf(m);
|
||||||
|
p->to = dest;
|
||||||
|
p->decoded.want_response = false;
|
||||||
|
if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR)
|
||||||
|
p->priority = meshtastic_MeshPacket_Priority_RELIABLE;
|
||||||
|
else
|
||||||
|
p->priority = meshtastic_MeshPacket_Priority_MIN;
|
||||||
|
// release previous packet before occupying a new spot
|
||||||
|
if (lastMeasurementPacket != nullptr)
|
||||||
|
packetPool.release(lastMeasurementPacket);
|
||||||
|
|
||||||
|
lastMeasurementPacket = packetPool.allocCopy(*p);
|
||||||
|
if (phoneOnly) {
|
||||||
|
LOG_INFO("Sending packet to phone\n");
|
||||||
|
service.sendToPhone(p);
|
||||||
|
} else {
|
||||||
|
LOG_INFO("Sending packet to mesh\n");
|
||||||
|
service.sendToMesh(p, RX_SRC_LOCAL, true);
|
||||||
|
|
||||||
|
if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR && config.power.is_power_saving) {
|
||||||
|
LOG_DEBUG("Starting next execution in 5 seconds and then going to sleep.\n");
|
||||||
|
sleepOnNextExecution = true;
|
||||||
|
setIntervalFromNow(5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
43
src/modules/Telemetry/PowerTelemetry.h
Normal file
43
src/modules/Telemetry/PowerTelemetry.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||||
|
#include "NodeDB.h"
|
||||||
|
#include "ProtobufModule.h"
|
||||||
|
#include <OLEDDisplay.h>
|
||||||
|
#include <OLEDDisplayUi.h>
|
||||||
|
|
||||||
|
class PowerTelemetryModule : private concurrency::OSThread, public ProtobufModule<meshtastic_Telemetry>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PowerTelemetryModule()
|
||||||
|
: concurrency::OSThread("PowerTelemetryModule"),
|
||||||
|
ProtobufModule("PowerTelemetry", meshtastic_PortNum_TELEMETRY_APP, &meshtastic_Telemetry_msg)
|
||||||
|
{
|
||||||
|
lastMeasurementPacket = nullptr;
|
||||||
|
setIntervalFromNow(10 * 1000);
|
||||||
|
}
|
||||||
|
virtual bool wantUIFrame() override;
|
||||||
|
#if !HAS_SCREEN
|
||||||
|
void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||||
|
#else
|
||||||
|
virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) override;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** Called to handle a particular incoming message
|
||||||
|
@return true if you've guaranteed you've handled this message and no other handlers should be considered for it
|
||||||
|
*/
|
||||||
|
virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *p) override;
|
||||||
|
virtual int32_t runOnce() override;
|
||||||
|
/**
|
||||||
|
* Send our Telemetry into the mesh
|
||||||
|
*/
|
||||||
|
bool sendTelemetry(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool firstTime = 1;
|
||||||
|
meshtastic_MeshPacket *lastMeasurementPacket;
|
||||||
|
uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute
|
||||||
|
uint32_t lastSentToMesh = 0;
|
||||||
|
uint32_t lastSentToPhone = 0;
|
||||||
|
uint32_t sensor_read_error_count = 0;
|
||||||
|
};
|
||||||
44
src/modules/Telemetry/Sensor/INA3221Sensor.cpp
Normal file
44
src/modules/Telemetry/Sensor/INA3221Sensor.cpp
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#include "INA3221Sensor.h"
|
||||||
|
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||||
|
#include "TelemetrySensor.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
#include <INA3221.h>
|
||||||
|
|
||||||
|
INA3221Sensor::INA3221Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_INA3221, "INA3221"){};
|
||||||
|
|
||||||
|
int32_t INA3221Sensor::runOnce()
|
||||||
|
{
|
||||||
|
LOG_INFO("Init sensor: %s\n", sensorName);
|
||||||
|
if (!hasSensor()) {
|
||||||
|
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||||
|
}
|
||||||
|
if (!status) {
|
||||||
|
ina3221.setAddr(INA3221_ADDR42_SDA); // i2c address 0x42
|
||||||
|
ina3221.begin();
|
||||||
|
ina3221.setShuntRes(100, 100, 100); // 0.1 Ohm shunt resistors
|
||||||
|
status = true;
|
||||||
|
} else {
|
||||||
|
status = true;
|
||||||
|
}
|
||||||
|
return initI2CSensor();
|
||||||
|
};
|
||||||
|
|
||||||
|
void INA3221Sensor::setup() {}
|
||||||
|
|
||||||
|
bool INA3221Sensor::getMetrics(meshtastic_Telemetry *measurement)
|
||||||
|
{
|
||||||
|
measurement->variant.environment_metrics.voltage = ina3221.getVoltage(INA3221_CH1);
|
||||||
|
measurement->variant.environment_metrics.current = ina3221.getCurrent(INA3221_CH1);
|
||||||
|
measurement->variant.power_metrics.ch1_voltage = ina3221.getVoltage(INA3221_CH1);
|
||||||
|
measurement->variant.power_metrics.ch1_current = ina3221.getCurrent(INA3221_CH1);
|
||||||
|
measurement->variant.power_metrics.ch2_voltage = ina3221.getVoltage(INA3221_CH2);
|
||||||
|
measurement->variant.power_metrics.ch2_current = ina3221.getCurrent(INA3221_CH2);
|
||||||
|
measurement->variant.power_metrics.ch3_voltage = ina3221.getVoltage(INA3221_CH3);
|
||||||
|
measurement->variant.power_metrics.ch3_current = ina3221.getCurrent(INA3221_CH3);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t INA3221Sensor::getBusVoltageMv()
|
||||||
|
{
|
||||||
|
return lround(ina3221.getVoltage(INA3221_CH1) * 1000);
|
||||||
|
}
|
||||||
19
src/modules/Telemetry/Sensor/INA3221Sensor.h
Normal file
19
src/modules/Telemetry/Sensor/INA3221Sensor.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||||
|
#include "TelemetrySensor.h"
|
||||||
|
#include "VoltageSensor.h"
|
||||||
|
#include <INA3221.h>
|
||||||
|
|
||||||
|
class INA3221Sensor : public TelemetrySensor, VoltageSensor
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
INA3221 ina3221 = INA3221(INA3221_ADDR42_SDA);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setup() override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
INA3221Sensor();
|
||||||
|
int32_t runOnce() override;
|
||||||
|
bool getMetrics(meshtastic_Telemetry *measurement) override;
|
||||||
|
virtual uint16_t getBusVoltageMv() override;
|
||||||
|
};
|
||||||
@@ -565,6 +565,13 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
|
|||||||
msgPayload["gas_resistance"] = new JSONValue(decoded->variant.environment_metrics.gas_resistance);
|
msgPayload["gas_resistance"] = new JSONValue(decoded->variant.environment_metrics.gas_resistance);
|
||||||
msgPayload["voltage"] = new JSONValue(decoded->variant.environment_metrics.voltage);
|
msgPayload["voltage"] = new JSONValue(decoded->variant.environment_metrics.voltage);
|
||||||
msgPayload["current"] = new JSONValue(decoded->variant.environment_metrics.current);
|
msgPayload["current"] = new JSONValue(decoded->variant.environment_metrics.current);
|
||||||
|
} else if (decoded->which_variant == meshtastic_Telemetry_power_metrics_tag) {
|
||||||
|
msgPayload["voltage_ch1"] = new JSONValue(decoded->variant.power_metrics.ch1_voltage);
|
||||||
|
msgPayload["current_ch1"] = new JSONValue(decoded->variant.power_metrics.ch1_current);
|
||||||
|
msgPayload["voltage_ch2"] = new JSONValue(decoded->variant.power_metrics.ch2_voltage);
|
||||||
|
msgPayload["current_ch2"] = new JSONValue(decoded->variant.power_metrics.ch2_current);
|
||||||
|
msgPayload["voltage_ch3"] = new JSONValue(decoded->variant.power_metrics.ch3_voltage);
|
||||||
|
msgPayload["current_ch3"] = new JSONValue(decoded->variant.power_metrics.ch3_current);
|
||||||
}
|
}
|
||||||
jsonObj["payload"] = new JSONValue(msgPayload);
|
jsonObj["payload"] = new JSONValue(msgPayload);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
155
src/platform/portduino/PiHal.h
Normal file
155
src/platform/portduino/PiHal.h
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
#ifndef PI_HAL_H
|
||||||
|
#define PI_HAL_H
|
||||||
|
|
||||||
|
// include RadioLib
|
||||||
|
#include <RadioLib.h>
|
||||||
|
|
||||||
|
// include the library for Raspberry GPIO pins
|
||||||
|
#include "pigpio.h"
|
||||||
|
|
||||||
|
// create a new Raspberry Pi hardware abstraction layer
|
||||||
|
// using the pigpio library
|
||||||
|
// the HAL must inherit from the base RadioLibHal class
|
||||||
|
// and implement all of its virtual methods
|
||||||
|
class PiHal : public RadioLibHal
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// default constructor - initializes the base HAL and any needed private members
|
||||||
|
PiHal(uint8_t spiChannel, uint32_t spiSpeed = 2000000)
|
||||||
|
: RadioLibHal(PI_INPUT, PI_OUTPUT, PI_LOW, PI_HIGH, RISING_EDGE, FALLING_EDGE), _spiChannel(spiChannel),
|
||||||
|
_spiSpeed(spiSpeed)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void init() override
|
||||||
|
{
|
||||||
|
// first initialise pigpio library
|
||||||
|
gpioInitialise();
|
||||||
|
|
||||||
|
// now the SPI
|
||||||
|
spiBegin();
|
||||||
|
|
||||||
|
// Waveshare LoRaWAN Hat also needs pin 18 to be pulled high to enable the radio
|
||||||
|
// gpioSetMode(18, PI_OUTPUT);
|
||||||
|
// gpioWrite(18, PI_HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void term() override
|
||||||
|
{
|
||||||
|
// stop the SPI
|
||||||
|
spiEnd();
|
||||||
|
|
||||||
|
// pull the enable pin low
|
||||||
|
// gpioSetMode(18, PI_OUTPUT);
|
||||||
|
// gpioWrite(18, PI_LOW);
|
||||||
|
|
||||||
|
// finally, stop the pigpio library
|
||||||
|
gpioTerminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// GPIO-related methods (pinMode, digitalWrite etc.) should check
|
||||||
|
// RADIOLIB_NC as an alias for non-connected pins
|
||||||
|
void pinMode(uint32_t pin, uint32_t mode) override
|
||||||
|
{
|
||||||
|
if (pin == RADIOLIB_NC) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpioSetMode(pin, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void digitalWrite(uint32_t pin, uint32_t value) override
|
||||||
|
{
|
||||||
|
if (pin == RADIOLIB_NC) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpioWrite(pin, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t digitalRead(uint32_t pin) override
|
||||||
|
{
|
||||||
|
if (pin == RADIOLIB_NC) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (gpioRead(pin));
|
||||||
|
}
|
||||||
|
|
||||||
|
void attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) override
|
||||||
|
{
|
||||||
|
if (interruptNum == RADIOLIB_NC) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (gpioRead(interruptNum) == 1) {
|
||||||
|
interruptCb();
|
||||||
|
} else {
|
||||||
|
gpioSetAlertFunc(interruptNum, (gpioISRFunc_t)interruptCb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void detachInterrupt(uint32_t interruptNum) override
|
||||||
|
{
|
||||||
|
if (interruptNum == RADIOLIB_NC) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpioSetAlertFunc(interruptNum, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void delay(unsigned long ms) override { gpioDelay(ms * 1000); }
|
||||||
|
|
||||||
|
void delayMicroseconds(unsigned long us) override { gpioDelay(us); }
|
||||||
|
|
||||||
|
unsigned long millis() override { return (gpioTick() / 1000); }
|
||||||
|
|
||||||
|
unsigned long micros() override { return (gpioTick()); }
|
||||||
|
|
||||||
|
long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override
|
||||||
|
{
|
||||||
|
if (pin == RADIOLIB_NC) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->pinMode(pin, PI_INPUT);
|
||||||
|
uint32_t start = this->micros();
|
||||||
|
uint32_t curtick = this->micros();
|
||||||
|
|
||||||
|
while (this->digitalRead(pin) == state) {
|
||||||
|
if ((this->micros() - curtick) > timeout) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (this->micros() - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
void spiBegin()
|
||||||
|
{
|
||||||
|
if (_spiHandle < 0) {
|
||||||
|
_spiHandle = spiOpen(_spiChannel, _spiSpeed, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void spiBeginTransaction() {}
|
||||||
|
|
||||||
|
void spiTransfer(uint8_t *out, size_t len, uint8_t *in) { spiXfer(_spiHandle, (char *)out, (char *)in, len); }
|
||||||
|
|
||||||
|
void spiEndTransaction() {}
|
||||||
|
|
||||||
|
void spiEnd()
|
||||||
|
{
|
||||||
|
if (_spiHandle >= 0) {
|
||||||
|
spiClose(_spiHandle);
|
||||||
|
_spiHandle = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// the HAL can contain any additional private members
|
||||||
|
const unsigned int _spiSpeed;
|
||||||
|
const uint8_t _spiChannel;
|
||||||
|
int _spiHandle = -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -7,10 +7,22 @@
|
|||||||
|
|
||||||
#include <Utility.h>
|
#include <Utility.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#ifdef ARCH_RASPBERRY_PI
|
||||||
|
#include "PortduinoGlue.h"
|
||||||
|
#include "pigpio.h"
|
||||||
|
#include "yaml-cpp/yaml.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
std::map<int, int> settingsMap;
|
||||||
|
|
||||||
|
#else
|
||||||
#include <linux/gpio/LinuxGPIOPin.h>
|
#include <linux/gpio/LinuxGPIOPin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// FIXME - move setBluetoothEnable into a HALPlatform class
|
// FIXME - move setBluetoothEnable into a HALPlatform class
|
||||||
|
|
||||||
void setBluetoothEnable(bool on)
|
void setBluetoothEnable(bool on)
|
||||||
{
|
{
|
||||||
// not needed
|
// not needed
|
||||||
@@ -22,7 +34,7 @@ void cpuDeepSleep(uint32_t msecs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel");
|
void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel");
|
||||||
|
#ifndef ARCH_RASPBERRY_PI
|
||||||
/** a simulated pin for busted IRQ hardware
|
/** a simulated pin for busted IRQ hardware
|
||||||
* Porduino helper class to do this i2c based polling:
|
* Porduino helper class to do this i2c based polling:
|
||||||
*/
|
*/
|
||||||
@@ -49,7 +61,7 @@ class PolledIrqPin : public GPIOPin
|
|||||||
};
|
};
|
||||||
|
|
||||||
static GPIOPin *loraIrq;
|
static GPIOPin *loraIrq;
|
||||||
|
#endif
|
||||||
int TCPPort = 4403;
|
int TCPPort = 4403;
|
||||||
|
|
||||||
static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
||||||
@@ -88,7 +100,57 @@ void portduinoSetup()
|
|||||||
{
|
{
|
||||||
printf("Setting up Meshtastic on Portduino...\n");
|
printf("Setting up Meshtastic on Portduino...\n");
|
||||||
|
|
||||||
#ifdef PORTDUINO_LINUX_HARDWARE
|
#ifdef ARCH_RASPBERRY_PI
|
||||||
|
YAML::Node yamlConfig;
|
||||||
|
|
||||||
|
if (access("config.yaml", R_OK) == 0) {
|
||||||
|
try {
|
||||||
|
yamlConfig = YAML::LoadFile("config.yaml");
|
||||||
|
} catch (YAML::Exception e) {
|
||||||
|
std::cout << "*** Exception " << e.what() << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
} else if (access("/etc/meshtasticd/config.yaml", R_OK) == 0) {
|
||||||
|
try {
|
||||||
|
yamlConfig = YAML::LoadFile("/etc/meshtasticd/config.yaml");
|
||||||
|
} catch (YAML::Exception e) {
|
||||||
|
std::cout << "*** Exception " << e.what() << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::cout << "No 'config.yaml' found, exiting." << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (yamlConfig["Lora"]) {
|
||||||
|
settingsMap[use_sx1262] = false;
|
||||||
|
settingsMap[use_rf95] = false;
|
||||||
|
|
||||||
|
if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "sx1262") {
|
||||||
|
settingsMap[use_sx1262] = true;
|
||||||
|
} else if (yamlConfig["Lora"]["Module"] && yamlConfig["Lora"]["Module"].as<std::string>("") == "RF95") {
|
||||||
|
settingsMap[use_rf95] = true;
|
||||||
|
}
|
||||||
|
settingsMap[dio2_as_rf_switch] = yamlConfig["Lora"]["DIO2_AS_RF_SWITCH"].as<bool>(false);
|
||||||
|
settingsMap[cs] = yamlConfig["Lora"]["CS"].as<int>(RADIOLIB_NC);
|
||||||
|
settingsMap[irq] = yamlConfig["Lora"]["IRQ"].as<int>(RADIOLIB_NC);
|
||||||
|
settingsMap[busy] = yamlConfig["Lora"]["Busy"].as<int>(RADIOLIB_NC);
|
||||||
|
settingsMap[reset] = yamlConfig["Lora"]["Reset"].as<int>(RADIOLIB_NC);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (YAML::Exception e) {
|
||||||
|
std::cout << "*** Exception " << e.what() << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (access("/sys/kernel/debug/bluetooth/hci0/identity", R_OK) != 0) {
|
||||||
|
std::cout << "Cannot read Bluetooth MAC Address. Please run as root" << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef defined(PORTDUINO_LINUX_HARDWARE)
|
||||||
SPI.begin(); // We need to create SPI
|
SPI.begin(); // We need to create SPI
|
||||||
bool usePineLora = !spiChip->isSimulated();
|
bool usePineLora = !spiChip->isSimulated();
|
||||||
if (usePineLora) {
|
if (usePineLora) {
|
||||||
@@ -112,7 +174,7 @@ void portduinoSetup()
|
|||||||
gpioBind(loraCs);
|
gpioBind(loraCs);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef ARCH_RASPBERRY_PI
|
||||||
{
|
{
|
||||||
// Set the random seed equal to TCPPort to have a different seed per instance
|
// Set the random seed equal to TCPPort to have a different seed per instance
|
||||||
randomSeed(TCPPort);
|
randomSeed(TCPPort);
|
||||||
@@ -129,7 +191,7 @@ void portduinoSetup()
|
|||||||
gpioBind(new SimGPIOPin(SX126X_RESET, "fakeLoraReset"));
|
gpioBind(new SimGPIOPin(SX126X_RESET, "fakeLoraReset"));
|
||||||
gpioBind(new SimGPIOPin(LORA_DIO1, "fakeLoraIrq"));
|
gpioBind(new SimGPIOPin(LORA_DIO1, "fakeLoraIrq"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// gpioBind((new SimGPIOPin(LORA_RESET, "LORA_RESET")));
|
// gpioBind((new SimGPIOPin(LORA_RESET, "LORA_RESET")));
|
||||||
// gpioBind((new SimGPIOPin(RF95_NSS, "RF95_NSS"))->setSilent());
|
// gpioBind((new SimGPIOPin(RF95_NSS, "RF95_NSS"))->setSilent());
|
||||||
}
|
#endif
|
||||||
|
}
|
||||||
9
src/platform/portduino/PortduinoGlue.h
Normal file
9
src/platform/portduino/PortduinoGlue.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifdef ARCH_RASPBERRY_PI
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
extern std::map<int, int> settingsMap;
|
||||||
|
|
||||||
|
enum { use_sx1262, cs, irq, busy, reset, dio2_as_rf_switch, use_rf95 };
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -25,8 +25,10 @@ extern RTC_NOINIT_ATTR uint64_t RTC_reg_b;
|
|||||||
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
|
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
|
||||||
#include "modules/Telemetry/Sensor/INA219Sensor.h"
|
#include "modules/Telemetry/Sensor/INA219Sensor.h"
|
||||||
#include "modules/Telemetry/Sensor/INA260Sensor.h"
|
#include "modules/Telemetry/Sensor/INA260Sensor.h"
|
||||||
|
#include "modules/Telemetry/Sensor/INA3221Sensor.h"
|
||||||
extern INA260Sensor ina260Sensor;
|
extern INA260Sensor ina260Sensor;
|
||||||
extern INA219Sensor ina219Sensor;
|
extern INA219Sensor ina219Sensor;
|
||||||
|
extern INA3221Sensor ina3221Sensor;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class Power : private concurrency::OSThread
|
class Power : private concurrency::OSThread
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ void powerCommandsCheck()
|
|||||||
NVIC_SystemReset();
|
NVIC_SystemReset();
|
||||||
#elif defined(ARCH_RP2040)
|
#elif defined(ARCH_RP2040)
|
||||||
rp2040.reboot();
|
rp2040.reboot();
|
||||||
|
#elif defined(ARCH_RASPBERRY_PI)
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
#else
|
#else
|
||||||
rebootAtMsec = -1;
|
rebootAtMsec = -1;
|
||||||
LOG_WARN("FIXME implement reboot for this platform. Note that some settings require a restart to be applied.\n");
|
LOG_WARN("FIXME implement reboot for this platform. Note that some settings require a restart to be applied.\n");
|
||||||
|
|||||||
@@ -2,13 +2,11 @@
|
|||||||
#define I2C_SDA 21
|
#define I2C_SDA 21
|
||||||
#define I2C_SCL 22
|
#define I2C_SCL 22
|
||||||
|
|
||||||
// GPS
|
// For GPS, 'undef's not needed
|
||||||
#undef GPS_RX_PIN
|
|
||||||
#undef GPS_TX_PIN
|
|
||||||
#define GPS_RX_PIN 12
|
|
||||||
#define GPS_TX_PIN 15
|
#define GPS_TX_PIN 15
|
||||||
#define GPS_UBLOX
|
#define GPS_RX_PIN 12
|
||||||
#define PIN_GPS_EN 4
|
#define PIN_GPS_EN 4
|
||||||
|
#define GPS_POWER_TOGGLE // Moved definition from platformio.ini to here
|
||||||
|
|
||||||
#define BUTTON_PIN 39 // The middle button GPIO on the T-Beam
|
#define BUTTON_PIN 39 // The middle button GPIO on the T-Beam
|
||||||
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||||
@@ -18,28 +16,25 @@
|
|||||||
#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Module (#975).
|
#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Module (#975).
|
||||||
#define LED_PIN 2 // add status LED (compatible with core-pcb and DIY targets)
|
#define LED_PIN 2 // add status LED (compatible with core-pcb and DIY targets)
|
||||||
|
|
||||||
#define LORA_DIO0 26 // a No connect on the SX1262/SX1268 module
|
// Radio
|
||||||
#define LORA_RESET 23 // RST for SX1276, and for SX1262/SX1268
|
#define USE_SX1262 // E22-900M30S uses SX1262
|
||||||
#define LORA_DIO1 33 // IRQ for SX1262/SX1268
|
#define SX126X_MAX_POWER \
|
||||||
#define LORA_DIO2 32 // BUSY for SX1262/SX1268
|
22 // Outputting 22dBm from SX1262 results in ~30dBm E22-900M30S output (module only uses last stage of the YP2233W PA)
|
||||||
#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262/SX1268, if DIO3 is high the TXCO is enabled
|
#define SX126X_DIO3_TCXO_VOLTAGE 1.8 // E22 series TCXO reference voltage is 1.8V
|
||||||
|
|
||||||
#define RF95_SCK 5
|
#define SX126X_CS 18 // EBYTE module's NSS pin
|
||||||
#define RF95_MISO 19
|
#define SX126X_SCK 5 // EBYTE module's SCK pin
|
||||||
#define RF95_MOSI 27
|
#define SX126X_MOSI 27 // EBYTE module's MOSI pin
|
||||||
#define RF95_NSS 18
|
#define SX126X_MISO 19 // EBYTE module's MISO pin
|
||||||
|
#define SX126X_RESET 23 // EBYTE module's NRST pin
|
||||||
|
#define SX126X_BUSY 32 // EBYTE module's BUSY pin
|
||||||
|
#define SX126X_DIO1 33 // EBYTE module's DIO1 pin
|
||||||
|
|
||||||
#define USE_SX1262
|
#define SX126X_TXEN 13 // Schematic connects EBYTE module's TXEN pin to MCU
|
||||||
|
#define SX126X_RXEN 14 // Schematic connects EBYTE module's RXEN pin to MCU
|
||||||
|
|
||||||
#define SX126X_CS 18 // NSS for SX126X
|
#define RF95_NSS SX126X_CS // Compatibility with variant file configuration structure
|
||||||
#define SX126X_DIO1 LORA_DIO1
|
#define RF95_SCK SX126X_SCK // Compatibility with variant file configuration structure
|
||||||
#define SX126X_BUSY LORA_DIO2
|
#define RF95_MOSI SX126X_MOSI // Compatibility with variant file configuration structure
|
||||||
#define SX126X_RESET LORA_RESET
|
#define RF95_MISO SX126X_MISO // Compatibility with variant file configuration structure
|
||||||
#define SX126X_RXEN 14
|
#define LORA_DIO1 SX126X_DIO1 // Compatibility with variant file configuration structure
|
||||||
#define SX126X_TXEN RADIOLIB_NC
|
|
||||||
#define SX126X_DIO2_AS_RF_SWITCH
|
|
||||||
|
|
||||||
// Set lora.tx_power to 13 for Hydra or other E22 900M30S target due to PA
|
|
||||||
#define SX126X_MAX_POWER 13
|
|
||||||
|
|
||||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
|
||||||
|
|||||||
@@ -43,6 +43,4 @@ board_level = extra
|
|||||||
build_flags =
|
build_flags =
|
||||||
${esp32_base.build_flags}
|
${esp32_base.build_flags}
|
||||||
-D DIY_V1
|
-D DIY_V1
|
||||||
-D EBYTE_E22
|
|
||||||
-D GPS_POWER_TOGGLE
|
|
||||||
-I variants/diy/hydra
|
-I variants/diy/hydra
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ board = linux_hardware
|
|||||||
lib_deps = ${portduino_base.lib_deps}
|
lib_deps = ${portduino_base.lib_deps}
|
||||||
build_src_filter = ${portduino_base.build_src_filter}
|
build_src_filter = ${portduino_base.build_src_filter}
|
||||||
|
|
||||||
; The Portduino based sim environment on top of a linux OS and touching linux hardware devices
|
; The Raspberry Pi actually has accessible SPI and GPIO, so we can support real hardware there.
|
||||||
[env:linux-arm]
|
[env:raspbian]
|
||||||
extends = portduino_base
|
extends = portduino_base
|
||||||
build_flags = ${portduino_base.build_flags} -O0 -lgpiod -I variants/portduino
|
build_flags = ${portduino_base.build_flags} -O0 -lgpiod -I variants/portduino -DARCH_RASPBERRY_PI -lpigpio -lyaml-cpp
|
||||||
board = linux_arm
|
board = linux_arm
|
||||||
lib_deps = ${portduino_base.lib_deps}
|
lib_deps = ${portduino_base.lib_deps}
|
||||||
build_src_filter = ${portduino_base.build_src_filter}
|
build_src_filter = ${portduino_base.build_src_filter}
|
||||||
@@ -1,3 +1,8 @@
|
|||||||
|
#if defined(ARCH_RASPBERRY_PI)
|
||||||
|
#define NO_SCREEN
|
||||||
|
|
||||||
|
#else // Pine64 mode.
|
||||||
|
|
||||||
// Pine64 uses a common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if
|
// Pine64 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. Currently the RF95 code is disabled because I think the RF95 module won't need to ship.
|
// not found then probe for SX1262. Currently the RF95 code is disabled because I think the RF95 module won't need to ship.
|
||||||
// #define USE_RF95
|
// #define USE_RF95
|
||||||
@@ -13,7 +18,7 @@
|
|||||||
#define LORA_RESET 14
|
#define LORA_RESET 14
|
||||||
#define LORA_DIO1 33 // SX1262 IRQ, called DIO0 on pinelora schematic, pin 7 on ch341f "ack" - FIXME, enable hwints in linux
|
#define LORA_DIO1 33 // SX1262 IRQ, called DIO0 on pinelora schematic, pin 7 on ch341f "ack" - FIXME, enable hwints in linux
|
||||||
#define LORA_DIO2 32 // SX1262 BUSY, actually connected to "DIO5" on pinelora schematic, pin 8 on ch341f "slct"
|
#define LORA_DIO2 32 // SX1262 BUSY, actually connected to "DIO5" on pinelora schematic, pin 8 on ch341f "slct"
|
||||||
#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TXCO is enabled
|
#define LORA_DIO3 RADIOLIB_NC // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TXCO is enabled
|
||||||
|
|
||||||
#ifdef USE_SX1262
|
#ifdef USE_SX1262
|
||||||
#define SX126X_CS 20 // CS0 on pinelora schematic, hooked to gpio D0 on ch341f
|
#define SX126X_CS 20 // CS0 on pinelora schematic, hooked to gpio D0 on ch341f
|
||||||
@@ -21,5 +26,6 @@
|
|||||||
#define SX126X_BUSY LORA_DIO2
|
#define SX126X_BUSY LORA_DIO2
|
||||||
#define SX126X_RESET LORA_RESET
|
#define SX126X_RESET LORA_RESET
|
||||||
#define SX126X_DIO2_AS_RF_SWITCH
|
#define SX126X_DIO2_AS_RF_SWITCH
|
||||||
// HOPE RFM90 does not have a TCXO therefore not SX126X_E22
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
18
variants/rak10701/platformio.ini
Normal file
18
variants/rak10701/platformio.ini
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
; The very slick RAK wireless RAK10701 Field Tester device. Note you will have to flash to Arduino bootloader to use this firmware. Be aware touch is not currently working.
|
||||||
|
[env:rak10701]
|
||||||
|
extends = nrf52840_base
|
||||||
|
board = wiscore_rak4631
|
||||||
|
build_flags = ${nrf52840_base.build_flags} -Ivariants/rak10701 -D RAK_4631
|
||||||
|
-L "${platformio.libdeps_dir}/${this.__env__}/BSEC2 Software Library/src/cortex-m4/fpv4-sp-d16-hard"
|
||||||
|
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
||||||
|
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak10701> +<mesh/eth/> +<mesh/api/> +<mqtt/>
|
||||||
|
lib_deps =
|
||||||
|
${nrf52840_base.lib_deps}
|
||||||
|
${networking_base.lib_deps}
|
||||||
|
melopero/Melopero RV3028@^1.1.0
|
||||||
|
https://github.com/RAKWireless/RAK13800-W5100S.git#1.0.2
|
||||||
|
rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2
|
||||||
|
bodmer/TFT_eSPI
|
||||||
|
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
|
||||||
41
variants/rak10701/variant.cpp
Normal file
41
variants/rak10701/variant.cpp
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
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"
|
||||||
|
|
||||||
|
const uint32_t g_ADigitalPinMap[] = {
|
||||||
|
// P0
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||||
|
|
||||||
|
// P1
|
||||||
|
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47};
|
||||||
|
|
||||||
|
void initVariant()
|
||||||
|
{
|
||||||
|
// LED1 & LED2
|
||||||
|
pinMode(PIN_LED1, OUTPUT);
|
||||||
|
ledOff(PIN_LED1);
|
||||||
|
|
||||||
|
pinMode(PIN_LED2, OUTPUT);
|
||||||
|
ledOff(PIN_LED2);
|
||||||
|
}
|
||||||
329
variants/rak10701/variant.h
Normal file
329
variants/rak10701/variant.h
Normal file
@@ -0,0 +1,329 @@
|
|||||||
|
/*
|
||||||
|
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_RAK4630_
|
||||||
|
#define _VARIANT_RAK4630_
|
||||||
|
|
||||||
|
#define RAK4630
|
||||||
|
|
||||||
|
/** 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)
|
||||||
|
|
||||||
|
// LEDs
|
||||||
|
#define PIN_LED1 (35)
|
||||||
|
#define PIN_LED2 (36)
|
||||||
|
|
||||||
|
#define LED_BUILTIN PIN_LED1
|
||||||
|
#define LED_CONN PIN_LED2
|
||||||
|
|
||||||
|
#define LED_GREEN PIN_LED1
|
||||||
|
#define LED_BLUE PIN_LED2
|
||||||
|
|
||||||
|
#define LED_STATE_ON 1 // State when LED is litted
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Buttons
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PIN_BUTTON1 9 // Pin for button on E-ink button module or IO expansion such as the RAK14014 or RAK14015 TFT modules
|
||||||
|
#define BUTTON_NEED_PULLUP
|
||||||
|
#define PIN_BUTTON2 12
|
||||||
|
#define PIN_BUTTON3 24
|
||||||
|
#define PIN_BUTTON4 25
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Analog pins
|
||||||
|
*/
|
||||||
|
#define PIN_A0 (5)
|
||||||
|
#define PIN_A1 (31)
|
||||||
|
#define PIN_A2 (28)
|
||||||
|
#define PIN_A3 (29)
|
||||||
|
#define PIN_A4 (30)
|
||||||
|
#define PIN_A5 (31)
|
||||||
|
#define PIN_A6 (0xff)
|
||||||
|
#define PIN_A7 (0xff)
|
||||||
|
|
||||||
|
static const uint8_t A0 = PIN_A0;
|
||||||
|
static const uint8_t A1 = PIN_A1;
|
||||||
|
static const uint8_t A2 = PIN_A2;
|
||||||
|
static const uint8_t A3 = PIN_A3;
|
||||||
|
static const uint8_t A4 = PIN_A4;
|
||||||
|
static const uint8_t A5 = PIN_A5;
|
||||||
|
static const uint8_t A6 = PIN_A6;
|
||||||
|
static const uint8_t A7 = PIN_A7;
|
||||||
|
#define ADC_RESOLUTION 14
|
||||||
|
|
||||||
|
// Other pins
|
||||||
|
#define PIN_AREF (2)
|
||||||
|
#define PIN_NFC1 (9)
|
||||||
|
#define PIN_NFC2 (10)
|
||||||
|
|
||||||
|
static const uint8_t AREF = PIN_AREF;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Serial interfaces
|
||||||
|
*/
|
||||||
|
#define PIN_SERIAL1_RX (15)
|
||||||
|
#define PIN_SERIAL1_TX (16)
|
||||||
|
|
||||||
|
// Connected to Jlink CDC
|
||||||
|
#define PIN_SERIAL2_RX (8)
|
||||||
|
#define PIN_SERIAL2_TX (6)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPI Interfaces
|
||||||
|
*/
|
||||||
|
#define SPI_INTERFACES_COUNT 2
|
||||||
|
|
||||||
|
#define PIN_SPI_MISO (45)
|
||||||
|
#define PIN_SPI_MOSI (44)
|
||||||
|
#define PIN_SPI_SCK (43)
|
||||||
|
|
||||||
|
#define PIN_SPI1_MISO (29) // (0 + 29)
|
||||||
|
#define PIN_SPI1_MOSI (30) // (0 + 30)
|
||||||
|
#define PIN_SPI1_SCK (3) // (0 + 3)
|
||||||
|
|
||||||
|
static const uint8_t SS = 42;
|
||||||
|
static const uint8_t MOSI = PIN_SPI_MOSI;
|
||||||
|
static const uint8_t MISO = PIN_SPI_MISO;
|
||||||
|
static const uint8_t SCK = PIN_SPI_SCK;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* eink display pins
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PIN_EINK_CS (0 + 26)
|
||||||
|
#define PIN_EINK_BUSY (0 + 4)
|
||||||
|
#define PIN_EINK_DC (0 + 17)
|
||||||
|
#define PIN_EINK_RES (-1)
|
||||||
|
#define PIN_EINK_SCLK (0 + 3)
|
||||||
|
#define PIN_EINK_MOSI (0 + 30) // also called SDI
|
||||||
|
|
||||||
|
// Controls power for the eink display - Board power is enabled either by VBUS from USB or the CPU asserting PWR_ON
|
||||||
|
// FIXME - I think this is actually just the board power enable - it enables power to the CPU also
|
||||||
|
// #define PIN_EINK_PWR_ON (-1)
|
||||||
|
|
||||||
|
// #define USE_EINK
|
||||||
|
|
||||||
|
// RAKRGB
|
||||||
|
#define HAS_NCP5623
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wire Interfaces
|
||||||
|
*/
|
||||||
|
#define WIRE_INTERFACES_COUNT 1
|
||||||
|
|
||||||
|
#define PIN_WIRE_SDA (13)
|
||||||
|
#define PIN_WIRE_SCL (14)
|
||||||
|
|
||||||
|
// QSPI Pins
|
||||||
|
#define PIN_QSPI_SCK 3
|
||||||
|
#define PIN_QSPI_CS 26
|
||||||
|
#define PIN_QSPI_IO0 30
|
||||||
|
#define PIN_QSPI_IO1 29
|
||||||
|
#define PIN_QSPI_IO2 28
|
||||||
|
#define PIN_QSPI_IO3 2
|
||||||
|
|
||||||
|
// On-board QSPI Flash
|
||||||
|
#define EXTERNAL_FLASH_DEVICES IS25LP080D
|
||||||
|
#define EXTERNAL_FLASH_USE_QSPI
|
||||||
|
|
||||||
|
/* @note RAK5005-O GPIO mapping to RAK4631 GPIO ports
|
||||||
|
RAK5005-O <-> nRF52840
|
||||||
|
IO1 <-> P0.17 (Arduino GPIO number 17)
|
||||||
|
IO2 <-> P1.02 (Arduino GPIO number 34)
|
||||||
|
IO3 <-> P0.21 (Arduino GPIO number 21)
|
||||||
|
IO4 <-> P0.04 (Arduino GPIO number 4)
|
||||||
|
IO5 <-> P0.09 (Arduino GPIO number 9)
|
||||||
|
IO6 <-> P0.10 (Arduino GPIO number 10)
|
||||||
|
IO7 <-> P0.28 (Arduino GPIO number 28)
|
||||||
|
SW1 <-> P0.01 (Arduino GPIO number 1)
|
||||||
|
A0 <-> P0.04/AIN2 (Arduino Analog A2
|
||||||
|
A1 <-> P0.31/AIN7 (Arduino Analog A7
|
||||||
|
SPI_CS <-> P0.26 (Arduino GPIO number 26)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// No reason not to have the RAK Wireless pin defs here too. This allows code from example RAK sketches to run without
|
||||||
|
// modification.
|
||||||
|
|
||||||
|
static const uint8_t WB_IO1 = 17; // SLOT_A SLOT_B
|
||||||
|
static const uint8_t WB_IO2 = 34; // SLOT_A SLOT_B
|
||||||
|
static const uint8_t WB_IO3 = 21; // SLOT_C
|
||||||
|
static const uint8_t WB_IO4 = 4; // SLOT_C
|
||||||
|
static const uint8_t WB_IO5 = 9; // SLOT_D
|
||||||
|
static const uint8_t WB_IO6 = 10; // SLOT_D
|
||||||
|
static const uint8_t WB_SW1 = 33; // IO_SLOT
|
||||||
|
static const uint8_t WB_A0 = 5; // IO_SLOT
|
||||||
|
static const uint8_t WB_A1 = 31; // IO_SLOT
|
||||||
|
static const uint8_t WB_I2C1_SDA = 13; // SENSOR_SLOT IO_SLOT
|
||||||
|
static const uint8_t WB_I2C1_SCL = 14; // SENSOR_SLOT IO_SLOT
|
||||||
|
static const uint8_t WB_I2C2_SDA = 24; // IO_SLOT
|
||||||
|
static const uint8_t WB_I2C2_SCL = 25; // IO_SLOT
|
||||||
|
static const uint8_t WB_SPI_CS = 26; // IO_SLOT
|
||||||
|
static const uint8_t WB_SPI_CLK = 3; // IO_SLOT
|
||||||
|
static const uint8_t WB_SPI_MISO = 29; // IO_SLOT
|
||||||
|
static const uint8_t WB_SPI_MOSI = 30; // IO_SLOT
|
||||||
|
|
||||||
|
// RAK4630 LoRa module
|
||||||
|
|
||||||
|
/* Setup of the SX1262 LoRa module ( https://docs.rakwireless.com/Product-Categories/WisBlock/RAK4631/Datasheet/ )
|
||||||
|
|
||||||
|
P1.10 NSS SPI NSS (Arduino GPIO number 42)
|
||||||
|
P1.11 SCK SPI CLK (Arduino GPIO number 43)
|
||||||
|
P1.12 MOSI SPI MOSI (Arduino GPIO number 44)
|
||||||
|
P1.13 MISO SPI MISO (Arduino GPIO number 45)
|
||||||
|
P1.14 BUSY BUSY signal (Arduino GPIO number 46)
|
||||||
|
P1.15 DIO1 DIO1 event interrupt (Arduino GPIO number 47)
|
||||||
|
P1.06 NRESET NRESET manual reset of the SX1262 (Arduino GPIO number 38)
|
||||||
|
|
||||||
|
Important for successful SX1262 initialization:
|
||||||
|
|
||||||
|
* Setup DIO2 to control the antenna switch
|
||||||
|
* Setup DIO3 to control the TCXO power supply
|
||||||
|
* Setup the SX1262 to use it's DCDC regulator and not the LDO
|
||||||
|
* RAK4630 schematics show GPIO P1.07 connected to the antenna switch, but it should not be initialized, as DIO2 will do the
|
||||||
|
control of the antenna switch
|
||||||
|
|
||||||
|
SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USE_SX1262
|
||||||
|
#define SX126X_CS (42)
|
||||||
|
#define SX126X_DIO1 (47)
|
||||||
|
#define SX126X_BUSY (46)
|
||||||
|
#define SX126X_RESET (38)
|
||||||
|
// #define SX126X_TXEN (39)
|
||||||
|
// #define SX126X_RXEN (37)
|
||||||
|
#define SX126X_POWER_EN (37)
|
||||||
|
// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
|
||||||
|
#define SX126X_DIO2_AS_RF_SWITCH
|
||||||
|
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||||
|
|
||||||
|
// enables 3.3V periphery like GPS or IO Module
|
||||||
|
#define PIN_3V3_EN (34)
|
||||||
|
|
||||||
|
// RAK1910 GPS module
|
||||||
|
// If using the wisblock GPS module and pluged into Port A on WisBlock base
|
||||||
|
// IO1 is hooked to PPS (pin 12 on header) = gpio 17
|
||||||
|
// IO2 is hooked to GPS RESET = gpio 34, but it can not be used to this because IO2 is ALSO used to control 3V3_S power (1 is on).
|
||||||
|
// Therefore must be 1 to keep peripherals powered
|
||||||
|
// Power is on the controllable 3V3_S rail
|
||||||
|
// #define PIN_GPS_RESET (34)
|
||||||
|
#define PIN_GPS_EN PIN_3V3_EN
|
||||||
|
#define PIN_GPS_PPS (17) // Pulse per second input from the GPS
|
||||||
|
|
||||||
|
#define GPS_RX_PIN PIN_SERIAL1_RX
|
||||||
|
#define GPS_TX_PIN PIN_SERIAL1_TX
|
||||||
|
|
||||||
|
// Define pin to enable GPS toggle (set GPIO to LOW) via user button triple press
|
||||||
|
|
||||||
|
// RAK12002 RTC Module
|
||||||
|
#define RV3028_RTC (uint8_t)0b1010010
|
||||||
|
|
||||||
|
// RAK18001 Buzzer in Slot C
|
||||||
|
// #define PIN_BUZZER 21 // IO3 is PWM2
|
||||||
|
// NEW: set this via protobuf instead!
|
||||||
|
|
||||||
|
// Battery
|
||||||
|
// The battery sense is hooked to pin A0 (5)
|
||||||
|
#define BATTERY_PIN PIN_A0
|
||||||
|
// and has 12 bit resolution
|
||||||
|
#define BATTERY_SENSE_RESOLUTION_BITS 12
|
||||||
|
#define BATTERY_SENSE_RESOLUTION 4096.0
|
||||||
|
// Definition of milliVolt per LSB => 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096
|
||||||
|
#define VBAT_MV_PER_LSB (0.73242188F)
|
||||||
|
// Voltage divider value => 1.5M + 1M voltage divider on VBAT = (1.5M / (1M + 1.5M))
|
||||||
|
#define VBAT_DIVIDER (0.4F)
|
||||||
|
// Compensation factor for the VBAT divider
|
||||||
|
#define VBAT_DIVIDER_COMP (1.73)
|
||||||
|
// Fixed calculation of milliVolt from compensation value
|
||||||
|
#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
|
||||||
|
#undef AREF_VOLTAGE
|
||||||
|
#define AREF_VOLTAGE 3.0
|
||||||
|
#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
|
||||||
|
#define ADC_MULTIPLIER VBAT_DIVIDER_COMP // REAL_VBAT_MV_PER_LSB
|
||||||
|
#define VBAT_RAW_TO_SCALED(x) (REAL_VBAT_MV_PER_LSB * x)
|
||||||
|
|
||||||
|
#define HAS_RTC 1
|
||||||
|
|
||||||
|
#define HAS_ETHERNET 1
|
||||||
|
|
||||||
|
#define RAK_4631 1
|
||||||
|
|
||||||
|
#define PIN_ETHERNET_RESET 21
|
||||||
|
#define PIN_ETHERNET_SS PIN_EINK_CS
|
||||||
|
#define ETH_SPI_PORT SPI1
|
||||||
|
#define AQ_SET_PIN 10
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RAK14014 // Tell it we have a RAK14014
|
||||||
|
#define USER_SETUP_LOADED 1
|
||||||
|
#define DISABLE_ALL_LIBRARY_WARNINGS 1
|
||||||
|
#define ST7789_DRIVER 1
|
||||||
|
#define TFT_WIDTH 240
|
||||||
|
#define TFT_HEIGHT 320
|
||||||
|
#define TFT_MISO WB_SPI_MISO
|
||||||
|
#define TFT_MOSI WB_SPI_MOSI
|
||||||
|
#define TFT_SCLK WB_SPI_CLK
|
||||||
|
#define TFT_CS WB_SPI_CS
|
||||||
|
#define TFT_DC WB_IO4
|
||||||
|
#define TFT_RST -1
|
||||||
|
#define TFT_BL WB_IO3
|
||||||
|
#define LOAD_GLCD 1
|
||||||
|
#define LOAD_GFXFF 1
|
||||||
|
#define TFT_RGB_ORDER 0
|
||||||
|
#define SPI_FREQUENCY 50000000
|
||||||
|
#define TFT_SPI_PORT SPI1
|
||||||
|
#define ST7789_CS WB_SPI_CS // Adds compatibility with the rest of the checking for a ST7789 TFT.
|
||||||
|
|
||||||
|
#define SCREEN_ROTATE
|
||||||
|
#define SCREEN_TRANSITION_FRAMERATE 5
|
||||||
|
|
||||||
|
#define HAS_TOUCHSCREEN 0
|
||||||
|
#define SCREEN_TOUCH_INT 10 // From tp.h on the tracker open source code.
|
||||||
|
#define TOUCH_I2C_PORT 0
|
||||||
|
#define TOUCH_SLAVE_ADDRESS 0x5D // GT911
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Arduino objects - C++ only
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -22,6 +22,8 @@
|
|||||||
// ratio of voltage divider = 3.0 (R17=200k, R18=100k)
|
// ratio of voltage divider = 3.0 (R17=200k, R18=100k)
|
||||||
#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
|
#define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
|
||||||
|
|
||||||
|
#define DETECTION_SENSOR_EN 28
|
||||||
|
|
||||||
#define USE_SX1262
|
#define USE_SX1262
|
||||||
|
|
||||||
#undef RF95_SCK
|
#undef RF95_SCK
|
||||||
@@ -51,4 +53,4 @@
|
|||||||
// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
|
// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
|
||||||
#define SX126X_DIO2_AS_RF_SWITCH
|
#define SX126X_DIO2_AS_RF_SWITCH
|
||||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||||
#endif
|
#endif
|
||||||
@@ -201,6 +201,8 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define DETECTION_SENSOR_EN 4
|
||||||
|
|
||||||
#define USE_SX1262
|
#define USE_SX1262
|
||||||
#define SX126X_CS (42)
|
#define SX126X_CS (42)
|
||||||
#define SX126X_DIO1 (47)
|
#define SX126X_DIO1 (47)
|
||||||
@@ -223,7 +225,7 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
|
|||||||
// Therefore must be 1 to keep peripherals powered
|
// Therefore must be 1 to keep peripherals powered
|
||||||
// Power is on the controllable 3V3_S rail
|
// Power is on the controllable 3V3_S rail
|
||||||
// #define PIN_GPS_RESET (34)
|
// #define PIN_GPS_RESET (34)
|
||||||
#define PIN_GPS_EN PIN_3V3_EN
|
// #define PIN_GPS_EN PIN_3V3_EN
|
||||||
#define PIN_GPS_PPS (17) // Pulse per second input from the GPS
|
#define PIN_GPS_PPS (17) // Pulse per second input from the GPS
|
||||||
|
|
||||||
#define GPS_RX_PIN PIN_SERIAL1_RX
|
#define GPS_RX_PIN PIN_SERIAL1_RX
|
||||||
@@ -277,4 +279,4 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
|
|||||||
* Arduino objects - C++ only
|
* Arduino objects - C++ only
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
[VERSION]
|
[VERSION]
|
||||||
major = 2
|
major = 2
|
||||||
minor = 2
|
minor = 2
|
||||||
build = 12
|
build = 14
|
||||||
|
|||||||
Reference in New Issue
Block a user