diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 000000000..584097061
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,4 @@
+* text=auto eol=lf
+*.{cmd,[cC][mM][dD]} text eol=crlf
+*.{bat,[bB][aA][tT]} text eol=crlf
+*.{sh,[sS][hH]} text eol=lf
diff --git a/.github/ISSUE_TEMPLATE/New Board.yml b/.github/ISSUE_TEMPLATE/New Board.yml
index ad706f3c0..c71ed4ba2 100644
--- a/.github/ISSUE_TEMPLATE/New Board.yml
+++ b/.github/ISSUE_TEMPLATE/New Board.yml
@@ -28,7 +28,7 @@ body:
description: What LoRa IC does the board have?
validations:
required: true
-
+
- type: input
id: link
attributes:
diff --git a/.github/actions/setup-base/action.yml b/.github/actions/setup-base/action.yml
index 1791f80ae..45930a94f 100644
--- a/.github/actions/setup-base/action.yml
+++ b/.github/actions/setup-base/action.yml
@@ -1,5 +1,5 @@
-name: 'Setup Build Base Composite Action'
-description: 'Base build actions for Meshtastic Platform IO steps'
+name: "Setup Build Base Composite Action"
+description: "Base build actions for Meshtastic Platform IO steps"
runs:
using: "composite"
@@ -10,7 +10,7 @@ runs:
submodules: "recursive"
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
-
+
- name: Install cppcheck
shell: bash
run: |
@@ -38,4 +38,4 @@ runs:
- name: Upgrade platformio
shell: bash
run: |
- pio upgrade
\ No newline at end of file
+ pio upgrade
diff --git a/.github/workflows/build_esp32.yml b/.github/workflows/build_esp32.yml
index 6d5dd9863..7996a9b1b 100644
--- a/.github/workflows/build_esp32.yml
+++ b/.github/workflows/build_esp32.yml
@@ -7,7 +7,7 @@ on:
required: true
type: string
-jobs:
+jobs:
build-esp32:
runs-on: ubuntu-latest
steps:
@@ -29,6 +29,13 @@ jobs:
tar -xf build.tar -C data/static
rm build.tar
+ - name: Remove debug flags for release
+ if: ${{ github.event_name == 'workflow_dispatch' }}
+ run: |
+ sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini
+ sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini
+ sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini
+
- name: Build ESP32
run: bin/build-esp32.sh ${{ inputs.board }}
@@ -39,7 +46,7 @@ jobs:
file: "firmware.bin"
target: "release/bleota.bin"
token: ${{ secrets.GITHUB_TOKEN }}
-
+
- name: Get release version string
shell: bash
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
diff --git a/.github/workflows/build_nrf52.yml b/.github/workflows/build_nrf52.yml
index cdf43c22e..33ee4d00c 100644
--- a/.github/workflows/build_nrf52.yml
+++ b/.github/workflows/build_nrf52.yml
@@ -7,7 +7,7 @@ on:
required: true
type: string
-jobs:
+jobs:
build-nrf52:
runs-on: ubuntu-latest
steps:
@@ -30,4 +30,4 @@ jobs:
path: |
release/*.uf2
release/*.elf
- release/*.zip
\ No newline at end of file
+ release/*.zip
diff --git a/.github/workflows/build_rpi2040.yml b/.github/workflows/build_rpi2040.yml
index fb7e3db5b..76ca2c20e 100644
--- a/.github/workflows/build_rpi2040.yml
+++ b/.github/workflows/build_rpi2040.yml
@@ -7,7 +7,7 @@ on:
required: true
type: string
-jobs:
+jobs:
build-rpi2040:
runs-on: ubuntu-latest
steps:
@@ -29,4 +29,4 @@ jobs:
name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
path: |
release/*.uf2
- release/*.elf
\ No newline at end of file
+ release/*.elf
diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml
index 1953619c8..fb01f3208 100644
--- a/.github/workflows/main_matrix.yml
+++ b/.github/workflows/main_matrix.yml
@@ -33,7 +33,7 @@ jobs:
- board: m5stack-coreink
- board: tbeam-s3-core
- board: tlora-t3s3-v1
-
+
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
@@ -41,6 +41,9 @@ jobs:
id: base
uses: ./.github/actions/setup-base
+ - name: Trunk Check
+ uses: trunk-io/trunk-action@v1
+
- name: Check ${{ matrix.board }}
run: bin/check-all.sh ${{ matrix.board }}
@@ -109,14 +112,14 @@ jobs:
uses: ./.github/actions/setup-base
# We now run integration test before other build steps (to quickly see runtime failures)
- - name: Build for native
- run: platformio run -e native
- - name: Integration test
- run: |
- .pio/build/native/program &
- sleep 20 # 5 seconds was not enough
- echo "Simulator started, launching python test..."
- python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
+ #- name: Build for native
+ # run: platformio run -e native
+ #- name: Integration test
+ # run: |
+ #.pio/build/native/program
+ #& sleep 20 # 5 seconds was not enough
+ #echo "Simulator started, launching python test..."
+ #python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
- name: Build Native
run: bin/build-native.sh
@@ -132,27 +135,34 @@ jobs:
path: |
release/device-*.sh
release/device-*.bat
-
+
- name: Docker login
- if: ${{ github.event_name == 'workflow_dispatch' }}
uses: docker/login-action@v2
- with:
+ with:
username: meshtastic
password: ${{ secrets.DOCKER_TOKEN }}
- name: Docker setup
- if: ${{ github.event_name == 'workflow_dispatch' }}
uses: docker/setup-buildx-action@v2
- - name: Docker build and push
+ - name: Docker build and push tagged versions
if: ${{ github.event_name == 'workflow_dispatch' }}
uses: docker/build-push-action@v3
+ with:
+ context: .
+ file: ./Dockerfile
+ push: true
+ tags: meshtastic/device-simulator:${{ steps.version.outputs.version }}
+
+ - name: Docker build and push
+ if: github.ref == 'refs/heads/master'
+ uses: docker/build-push-action@v3
with:
context: .
file: ./Dockerfile
push: true
tags: meshtastic/device-simulator:latest
-
+
after-checks:
runs-on: ubuntu-latest
needs: [check]
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
new file mode 100644
index 000000000..d9d52a2a4
--- /dev/null
+++ b/.github/workflows/nightly.yml
@@ -0,0 +1,19 @@
+name: Nightly
+on:
+ schedule:
+ - cron: 0 8 * * 1-5
+ workflow_dispatch: {}
+
+jobs:
+ trunk_check:
+ name: Trunk Check Upload
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+
+ - name: Trunk Check
+ uses: trunk-io/trunk-action@v1
+ with:
+ trunk-token: ${{ secrets.TRUNK_TOKEN }}
diff --git a/.github/workflows/sec_sast_flawfinder.yml b/.github/workflows/sec_sast_flawfinder.yml
index e2ba44090..2c7e751af 100644
--- a/.github/workflows/sec_sast_flawfinder.yml
+++ b/.github/workflows/sec_sast_flawfinder.yml
@@ -10,31 +10,31 @@ on:
jobs:
flawfinder:
- runs-on: ubuntu-latest
- name: Flawfinder
+ runs-on: ubuntu-latest
+ name: Flawfinder
- steps:
- # step 1
- - name: clone application source code
- uses: actions/checkout@v3
+ steps:
+ # step 1
+ - name: clone application source code
+ uses: actions/checkout@v3
- # step 2
- - name: flawfinder_scan
- uses: david-a-wheeler/flawfinder@2.0.19
- with:
- arguments: '--sarif ./'
- output: 'flawfinder_report.sarif'
+ # step 2
+ - name: flawfinder_scan
+ uses: david-a-wheeler/flawfinder@2.0.19
+ with:
+ arguments: "--sarif ./"
+ output: "flawfinder_report.sarif"
- # step 3
- - name: save report as pipeline artifact
- uses: actions/upload-artifact@v3
- with:
- name: flawfinder_report.sarif
- path: flawfinder_report.sarif
+ # step 3
+ - name: save report as pipeline artifact
+ uses: actions/upload-artifact@v3
+ with:
+ name: flawfinder_report.sarif
+ path: flawfinder_report.sarif
- # step 4
- - name: publish code scanning alerts
- uses: github/codeql-action/upload-sarif@v2
- with:
- sarif_file: flawfinder_report.sarif
- category: flawfinder
+ # step 4
+ - name: publish code scanning alerts
+ uses: github/codeql-action/upload-sarif@v2
+ with:
+ sarif_file: flawfinder_report.sarif
+ category: flawfinder
diff --git a/.github/workflows/sec_sast_semgrep_cron.yml b/.github/workflows/sec_sast_semgrep_cron.yml
index 426250280..cdd2c3c37 100644
--- a/.github/workflows/sec_sast_semgrep_cron.yml
+++ b/.github/workflows/sec_sast_semgrep_cron.yml
@@ -6,39 +6,37 @@ on:
branches:
- master
schedule:
- - cron: '0 1 * * 6'
+ - cron: "0 1 * * 6"
jobs:
-
semgrep-full:
- runs-on: ubuntu-latest
- container:
- image: returntocorp/semgrep
+ runs-on: ubuntu-latest
+ container:
+ image: returntocorp/semgrep
- steps:
+ steps:
+ # step 1
+ - name: clone application source code
+ uses: actions/checkout@v3
- # step 1
- - name: clone application source code
- uses: actions/checkout@v3
+ # step 2
+ - name: full scan
+ run: |
+ semgrep \
+ --sarif --output report.sarif \
+ --metrics=off \
+ --config="p/default"
- # step 2
- - name: full scan
- run: |
- semgrep \
- --sarif --output report.sarif \
- --metrics=off \
- --config="p/default"
+ # step 3
+ - name: save report as pipeline artifact
+ uses: actions/upload-artifact@v3
+ with:
+ name: report.sarif
+ path: report.sarif
- # step 3
- - name: save report as pipeline artifact
- uses: actions/upload-artifact@v3
- with:
- name: report.sarif
- path: report.sarif
-
- # step 4
- - name: publish code scanning alerts
- uses: github/codeql-action/upload-sarif@v2
- with:
- sarif_file: report.sarif
- category: semgrep
+ # step 4
+ - name: publish code scanning alerts
+ uses: github/codeql-action/upload-sarif@v2
+ with:
+ sarif_file: report.sarif
+ category: semgrep
diff --git a/.github/workflows/sec_sast_semgrep_pull.yml b/.github/workflows/sec_sast_semgrep_pull.yml
index 8fe3632b4..1697ffb1b 100644
--- a/.github/workflows/sec_sast_semgrep_pull.yml
+++ b/.github/workflows/sec_sast_semgrep_pull.yml
@@ -1,17 +1,14 @@
---
name: Semgrep Differential Scan
-on:
- pull_request
+on: pull_request
jobs:
-
semgrep-diff:
runs-on: ubuntu-latest
container:
image: returntocorp/semgrep
steps:
-
# step 1
- name: clone application source code
uses: actions/checkout@v3
diff --git a/.trunk/.gitignore b/.trunk/.gitignore
new file mode 100644
index 000000000..cf2f25470
--- /dev/null
+++ b/.trunk/.gitignore
@@ -0,0 +1,7 @@
+*out
+*logs
+*actions
+*notifications
+plugins
+user_trunk.yaml
+user.yaml
diff --git a/.clang-format b/.trunk/configs/.clang-format
similarity index 100%
rename from .clang-format
rename to .trunk/configs/.clang-format
diff --git a/.trunk/configs/.flake8 b/.trunk/configs/.flake8
new file mode 100644
index 000000000..5ba6e2ffe
--- /dev/null
+++ b/.trunk/configs/.flake8
@@ -0,0 +1,3 @@
+# Autoformatter friendly flake8 config (all formatting rules disabled)
+[flake8]
+extend-ignore = D1, D2, E1, E2, E3, E501, W1, W2, W3, W5
diff --git a/.trunk/configs/.hadolint.yaml b/.trunk/configs/.hadolint.yaml
new file mode 100644
index 000000000..98bf0cd2e
--- /dev/null
+++ b/.trunk/configs/.hadolint.yaml
@@ -0,0 +1,4 @@
+# Following source doesn't work in most setups
+ignored:
+ - SC1090
+ - SC1091
diff --git a/.trunk/configs/.isort.cfg b/.trunk/configs/.isort.cfg
new file mode 100644
index 000000000..b9fb3f3e8
--- /dev/null
+++ b/.trunk/configs/.isort.cfg
@@ -0,0 +1,2 @@
+[settings]
+profile=black
diff --git a/.trunk/configs/.markdownlint.yaml b/.trunk/configs/.markdownlint.yaml
new file mode 100644
index 000000000..fb940393d
--- /dev/null
+++ b/.trunk/configs/.markdownlint.yaml
@@ -0,0 +1,10 @@
+# Autoformatter friendly markdownlint config (all formatting rules disabled)
+default: true
+blank_lines: false
+bullet: false
+html: false
+indentation: false
+line_length: false
+spaces: false
+url: false
+whitespace: false
diff --git a/.trunk/configs/.shellcheckrc b/.trunk/configs/.shellcheckrc
new file mode 100644
index 000000000..8c7b1ada8
--- /dev/null
+++ b/.trunk/configs/.shellcheckrc
@@ -0,0 +1,7 @@
+enable=all
+source-path=SCRIPTDIR
+disable=SC2154
+
+# If you're having issues with shellcheck following source, disable the errors via:
+# disable=SC1090
+# disable=SC1091
diff --git a/.trunk/configs/svgo.config.js b/.trunk/configs/svgo.config.js
new file mode 100644
index 000000000..b257d1349
--- /dev/null
+++ b/.trunk/configs/svgo.config.js
@@ -0,0 +1,14 @@
+module.exports = {
+ plugins: [
+ {
+ name: "preset-default",
+ params: {
+ overrides: {
+ removeViewBox: false, // https://github.com/svg/svgo/issues/1128
+ sortAttrs: true,
+ removeOffCanvasPaths: true,
+ },
+ },
+ },
+ ],
+};
diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml
new file mode 100644
index 000000000..e854e883a
--- /dev/null
+++ b/.trunk/trunk.yaml
@@ -0,0 +1,44 @@
+version: 0.1
+cli:
+ version: 1.4.1
+plugins:
+ sources:
+ - id: trunk
+ ref: v0.0.8
+ uri: https://github.com/trunk-io/plugins
+lint:
+ enabled:
+ - oxipng@8.0.0
+ - actionlint@1.6.23
+ - markdownlint@0.33.0
+ - shellcheck@0.9.0
+ - shfmt@3.5.0
+ - hadolint@2.12.0
+ - isort@5.12.0
+ - black@23.1.0
+ - svgo@3.0.2
+ - flake8@6.0.0
+ - git-diff-check
+ - gitleaks@8.15.3
+ - clang-format@14.0.0
+ - prettier@2.8.3
+ disabled:
+ - shellcheck@0.9.0
+ - shfmt@3.5.0
+ - oxipng@8.0.0
+ - actionlint@1.6.22
+ - markdownlint@0.33.0
+ - hadolint@2.12.0
+ - svgo@3.0.2
+runtimes:
+ enabled:
+ - python@3.10.8
+ - go@1.18.3
+ - node@18.12.1
+actions:
+ disabled:
+ - trunk-announce
+ - trunk-check-pre-push
+ - trunk-fmt-pre-commit
+ enabled:
+ - trunk-upgrade-available
diff --git a/arch/esp32/esp32s2.ini b/arch/esp32/esp32s2.ini
index ca4f576d6..beba16f3e 100644
--- a/arch/esp32/esp32s2.ini
+++ b/arch/esp32/esp32s2.ini
@@ -27,7 +27,7 @@ build_flags =
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
-DHAS_BLUETOOTH=0
- -DDEBUG_HEAP
+ -DDEBUG_HEAP
lib_deps =
${arduino_base.lib_deps}
diff --git a/arch/esp32/esp32s3.ini b/arch/esp32/esp32s3.ini
index b276ceff9..023d1ca84 100644
--- a/arch/esp32/esp32s3.ini
+++ b/arch/esp32/esp32s3.ini
@@ -26,7 +26,7 @@ build_flags =
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
- -DDEBUG_HEAP
+ -DDEBUG_HEAP
lib_deps =
${arduino_base.lib_deps}
diff --git a/arch/nrf52/nrf52.ini b/arch/nrf52/nrf52.ini
index 46f946530..9ee2c37b5 100644
--- a/arch/nrf52/nrf52.ini
+++ b/arch/nrf52/nrf52.ini
@@ -8,7 +8,7 @@ build_flags =
${arduino_base.build_flags} -Wno-unused-variable
-Isrc/platform/nrf52
build_src_filter =
- ${arduino_base.build_src_filter} - - - - - - - - -
+ ${arduino_base.build_src_filter} - - - - - - - - -
lib_ignore =
BluetoothOTA
diff --git a/arch/rp2040/rp2040.ini b/arch/rp2040/rp2040.ini
index cf898a60f..c41f92892 100644
--- a/arch/rp2040/rp2040.ini
+++ b/arch/rp2040/rp2040.ini
@@ -1,8 +1,6 @@
; Common settings for rp2040 Processor based targets
[rp2040_base]
-platform = https://github.com/maxgerhardt/platform-raspberrypi.git#20c7dbfcfe6677c5305fa28ecf5e3870321cb157
-platform_packages =
- earlephilhower/toolchain-rp2040-earlephilhower@^5.100300.221223
+platform = https://github.com/maxgerhardt/platform-raspberrypi.git#9f8c10e50b5acd18e7bfd32638199c655be73a5b
extends = arduino_base
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m
@@ -12,7 +10,7 @@ build_flags =
-D__PLAT_RP2040__
# -D _POSIX_THREADS
build_src_filter =
- ${arduino_base.build_src_filter} - - - - - - - - -
+ ${arduino_base.build_src_filter} - - - - - - - - -
lib_ignore =
BluetoothOTA
lib_deps =
diff --git a/arch/stm32/stm32wl5e.ini b/arch/stm32/stm32wl5e.ini
index 3fc7583ad..a38fb65e8 100644
--- a/arch/stm32/stm32wl5e.ini
+++ b/arch/stm32/stm32wl5e.ini
@@ -10,7 +10,7 @@ build_flags =
# Arduino/PlatformIO framework-arduinoststm32 package does not presently have SUBGHZSPI support
# -DPIN_SPI_MOSI=PINSUBGHZSPIMOSI -DPIN_SPI_MISO=PINSUBGHZSPIMISO -DPIN_SPI_SCK=PINSUBGHZSPISCK
build_src_filter =
- ${arduino_base.build_src_filter} - - - - - - - - - - - - - -
+ ${arduino_base.build_src_filter} - - - - - - - - - - - - - -
lib_deps =
${env.lib_deps}
https://github.com/kokke/tiny-AES-c.git#f06ac37fc31dfdaca2e0d9bec83f90d5663c319b
diff --git a/bin/readprops.py b/bin/readprops.py
index c23092e41..db8c8c011 100644
--- a/bin/readprops.py
+++ b/bin/readprops.py
@@ -1,9 +1,7 @@
-
-
-import subprocess
import configparser
-import traceback
+import subprocess
import sys
+import traceback
def readProps(prefsLoc):
@@ -11,27 +9,36 @@ def readProps(prefsLoc):
config = configparser.RawConfigParser()
config.read(prefsLoc)
- version = dict(config.items('VERSION'))
- verObj = dict(short = "{}.{}.{}".format(version["major"], version["minor"], version["build"]),
- long = "unset")
+ version = dict(config.items("VERSION"))
+ verObj = dict(
+ short="{}.{}.{}".format(version["major"], version["minor"], version["build"]),
+ long="unset",
+ )
# Try to find current build SHA if if the workspace is clean. This could fail if git is not installed
try:
- sha = subprocess.check_output(
- ['git', 'rev-parse', '--short', 'HEAD']).decode("utf-8").strip()
- isDirty = subprocess.check_output(
- ['git', 'diff', 'HEAD']).decode("utf-8").strip()
+ sha = (
+ subprocess.check_output(["git", "rev-parse", "--short", "HEAD"])
+ .decode("utf-8")
+ .strip()
+ )
+ isDirty = (
+ subprocess.check_output(["git", "diff", "HEAD"]).decode("utf-8").strip()
+ )
suffix = sha
- if isDirty:
- # short for 'dirty', we want to keep our verstrings source for protobuf reasons
- suffix = sha + "-d"
- verObj['long'] = "{}.{}.{}.{}".format(
- version["major"], version["minor"], version["build"], suffix)
+ # if isDirty:
+ # # short for 'dirty', we want to keep our verstrings source for protobuf reasons
+ # suffix = sha + "-d"
+ verObj["long"] = "{}.{}.{}.{}".format(
+ version["major"], version["minor"], version["build"], suffix
+ )
except:
# print("Unexpected error:", sys.exc_info()[0])
# traceback.print_exc()
- verObj['long'] = verObj['short']
+ verObj["long"] = verObj["short"]
# print("firmware version " + verStr)
return verObj
+
+
# print("path is" + ','.join(sys.path))
diff --git a/bin/regen-protos.bat b/bin/regen-protos.bat
index 5c576c5b2..aa2a2684f 100644
--- a/bin/regen-protos.bat
+++ b/bin/regen-protos.bat
@@ -1 +1,5 @@
-cd protobufs && ..\nanopb-0.4.7\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\protobufs *.proto
+cd protobufs && ..\nanopb-0.4.7\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\protobufs ..\protobufs\meshtastic\*.proto
+
+@REM cd ../src/mesh/generated/meshtastic
+@REM sed -i 's/#include "meshtastic/#include "./g' *
+@REM sed -i 's/meshtastic_//g' *
diff --git a/bin/regen-protos.sh b/bin/regen-protos.sh
index 133d587a3..5fa3ab049 100755
--- a/bin/regen-protos.sh
+++ b/bin/regen-protos.sh
@@ -8,7 +8,12 @@ echo "prebuilt binaries for your computer into nanopb-0.4.7"
# the nanopb tool seems to require that the .options file be in the current directory!
cd protobufs
-../nanopb-0.4.7/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated -I=../protobufs *.proto
+../nanopb-0.4.7/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated/ -I=../protobufs meshtastic/*.proto
+
+# cd ../src/mesh/generated/meshtastic
+# sed -i 's/#include "meshtastic/#include "./g' -- *
+
+# sed -i 's/meshtastic_//g' -- *
#echo "Regenerating protobuf documentation - if you see an error message"
#echo "you can ignore it unless doing a new protobuf release to github."
diff --git a/boards/eink0.1.json b/boards/eink0.1.json
index 1c5614896..28862c5d4 100644
--- a/boards/eink0.1.json
+++ b/boards/eink0.1.json
@@ -7,12 +7,7 @@
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_TTGO_EINK -DNRF52840_XXAA",
"f_cpu": "64000000L",
- "hwids": [
- [
- "0x239A",
- "0x4405"
- ]
- ],
+ "hwids": [["0x239A", "0x4405"]],
"usb_product": "TTGO_eink",
"mcu": "nrf52840",
"variant": "eink0.1",
@@ -30,19 +25,13 @@
"settings_addr": "0xFF000"
}
},
- "connectivity": [
- "bluetooth"
- ],
+ "connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
- "onboard_tools": [
- "jlink"
- ],
+ "onboard_tools": ["jlink"],
"svd_path": "nrf52840.svd"
},
- "frameworks": [
- "arduino"
- ],
+ "frameworks": ["arduino"],
"name": "TTGO eink (Adafruit BSP)",
"upload": {
"maximum_ram_size": 248832,
@@ -50,12 +39,8 @@
"require_upload_port": true,
"speed": 115200,
"protocol": "jlink",
- "protocols": [
- "jlink",
- "nrfjprog",
- "stlink"
- ]
+ "protocols": ["jlink", "nrfjprog", "stlink"]
},
"url": "FIXME",
"vendor": "TTGO"
-}
\ No newline at end of file
+}
diff --git a/boards/generic_wl5e.json b/boards/generic_wl5e.json
index 87e140435..433c55b59 100644
--- a/boards/generic_wl5e.json
+++ b/boards/generic_wl5e.json
@@ -9,9 +9,7 @@
"product_line": "STM32WLE5xx"
},
"debug": {
- "default_tools": [
- "stlink"
- ],
+ "default_tools": ["stlink"],
"jlink_device": "STM32WLE5CC",
"openocd_target": "stm32wlx",
"svd_path": "STM32WLE5_CM4.svd"
@@ -22,9 +20,7 @@
"maximum_ram_size": 65536,
"maximum_size": 262144,
"protocol": "cmsis-dap",
- "protocols": [
- "cmsis-dap"
- ]
+ "protocols": ["cmsis-dap"]
},
"url": "https://www.st.com/en/microcontrollers-microprocessors/stm32wl-series.html",
"vendor": "ST"
diff --git a/boards/lora_isp4520.json b/boards/lora_isp4520.json
index 180cd2fe7..971512b28 100644
--- a/boards/lora_isp4520.json
+++ b/boards/lora_isp4520.json
@@ -19,16 +19,12 @@
"sd_fwid": "0x00B7"
}
},
- "connectivity": [
- "bluetooth"
- ],
+ "connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52832_xxAA",
"svd_path": "nrf52.svd"
},
- "frameworks": [
- "arduino"
- ],
+ "frameworks": ["arduino"],
"name": "lora ISP4520",
"upload": {
"maximum_ram_size": 65536,
@@ -36,13 +32,8 @@
"require_upload_port": true,
"speed": 115200,
"protocol": "nrfutil",
- "protocols": [
- "jlink",
- "nrfjprog",
- "nrfutil",
- "stlink"
- ]
+ "protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"]
},
"url": "",
"vendor": "PsiSoft"
-}
\ No newline at end of file
+}
diff --git a/boards/nordic_pca10059.json b/boards/nordic_pca10059.json
index b3d2cc7bd..214c2851d 100644
--- a/boards/nordic_pca10059.json
+++ b/boards/nordic_pca10059.json
@@ -1,72 +1,51 @@
{
- "build": {
- "arduino": {
- "ldscript": "nrf52840_s140_v6.ld"
- },
- "core": "nRF5",
- "cpu": "cortex-m4",
- "extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
- "f_cpu": "64000000L",
- "hwids": [
- [
- "0x239A",
- "0x8029"
- ],
- [
- "0x239A",
- "0x0029"
- ],
- [
- "0x239A",
- "0x002A"
- ],
- [
- "0x239A",
- "0x802A"
- ]
- ],
- "usb_product": "PCA10059",
- "mcu": "nrf52840",
- "variant": "nRF52840 Dongle",
- "bsp": {
- "name": "adafruit"
- },
- "softdevice": {
- "sd_flags": "-DS140",
- "sd_name": "s140",
- "sd_version": "6.1.1",
- "sd_fwid": "0x00B6"
- },
- "bootloader": {
- "settings_addr": "0xFF000"
- }
+ "build": {
+ "arduino": {
+ "ldscript": "nrf52840_s140_v6.ld"
},
- "connectivity": [
- "bluetooth"
+ "core": "nRF5",
+ "cpu": "cortex-m4",
+ "extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
+ "f_cpu": "64000000L",
+ "hwids": [
+ ["0x239A", "0x8029"],
+ ["0x239A", "0x0029"],
+ ["0x239A", "0x002A"],
+ ["0x239A", "0x802A"]
],
- "debug": {
- "jlink_device": "nRF52840_xxAA",
- "svd_path": "nrf52840.svd"
+ "usb_product": "PCA10059",
+ "mcu": "nrf52840",
+ "variant": "nRF52840 Dongle",
+ "bsp": {
+ "name": "adafruit"
},
- "frameworks": [
- "arduino"
- ],
- "name": "nRF52840 Dongle",
- "upload": {
- "maximum_ram_size": 248832,
- "maximum_size": 815104,
- "speed": 115200,
- "protocol": "nrfutil",
- "protocols": [
- "jlink",
- "nrfjprog",
- "nrfutil",
- "stlink"
- ],
- "use_1200bps_touch": true,
- "require_upload_port": true,
- "wait_for_upload_port": true
+ "softdevice": {
+ "sd_flags": "-DS140",
+ "sd_name": "s140",
+ "sd_version": "6.1.1",
+ "sd_fwid": "0x00B6"
},
- "url": "https://www.nordicsemi.com/Products/Development-hardware/nrf52840-dongle",
- "vendor": "Nordic Semiconductor"
+ "bootloader": {
+ "settings_addr": "0xFF000"
+ }
+ },
+ "connectivity": ["bluetooth"],
+ "debug": {
+ "jlink_device": "nRF52840_xxAA",
+ "svd_path": "nrf52840.svd"
+ },
+ "frameworks": ["arduino"],
+ "name": "nRF52840 Dongle",
+ "upload": {
+ "maximum_ram_size": 248832,
+ "maximum_size": 815104,
+ "speed": 115200,
+ "protocol": "nrfutil",
+ "protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
+ "use_1200bps_touch": true,
+ "require_upload_port": true,
+ "wait_for_upload_port": true
+ },
+ "url": "https://www.nordicsemi.com/Products/Development-hardware/nrf52840-dongle",
+ "vendor": "Nordic Semiconductor"
}
diff --git a/boards/nrf52840_dk.json b/boards/nrf52840_dk.json
index 27824178c..8d07575bf 100644
--- a/boards/nrf52840_dk.json
+++ b/boards/nrf52840_dk.json
@@ -1,47 +1,46 @@
{
- "build": {
- "arduino": {
- "ldscript": "nrf52840_s140_v6.ld"
- },
- "core": "nRF5",
- "cpu": "cortex-m4",
- "extra_flags": "-DARDUINO_NRF52840_PCA10056 -DNRF52840_XXAA",
- "f_cpu": "64000000L",
- "hwids": [["0x239A", "0x4404"]],
- "usb_product": "nrf52840dk",
- "mcu": "nrf52840",
- "variant": "pca10056",
- "variants_dir": "variants",
- "bsp": {
- "name": "adafruit"
- },
- "softdevice": {
- "sd_flags": "-DS140",
- "sd_name": "s140",
- "sd_version": "6.1.1",
- "sd_fwid": "0x00B6"
- },
- "bootloader": {
- "settings_addr": "0xFF000"
- }
+ "build": {
+ "arduino": {
+ "ldscript": "nrf52840_s140_v6.ld"
},
- "connectivity": ["bluetooth"],
- "debug": {
- "jlink_device": "nRF52840_xxAA",
- "onboard_tools": ["jlink"],
- "svd_path": "nrf52840.svd"
+ "core": "nRF5",
+ "cpu": "cortex-m4",
+ "extra_flags": "-DARDUINO_NRF52840_PCA10056 -DNRF52840_XXAA",
+ "f_cpu": "64000000L",
+ "hwids": [["0x239A", "0x4404"]],
+ "usb_product": "nrf52840dk",
+ "mcu": "nrf52840",
+ "variant": "pca10056",
+ "variants_dir": "variants",
+ "bsp": {
+ "name": "adafruit"
},
- "frameworks": ["arduino"],
- "name": "A modified NRF52840-DK devboard (Adafruit BSP)",
- "upload": {
- "maximum_ram_size": 248832,
- "maximum_size": 815104,
- "require_upload_port": true,
- "speed": 115200,
- "protocol": "jlink",
- "protocols": ["jlink", "nrfjprog", "stlink"]
+ "softdevice": {
+ "sd_flags": "-DS140",
+ "sd_name": "s140",
+ "sd_version": "6.1.1",
+ "sd_fwid": "0x00B6"
},
- "url": "https://meshtastic.org/",
- "vendor": "Nordic Semi"
- }
-
\ No newline at end of file
+ "bootloader": {
+ "settings_addr": "0xFF000"
+ }
+ },
+ "connectivity": ["bluetooth"],
+ "debug": {
+ "jlink_device": "nRF52840_xxAA",
+ "onboard_tools": ["jlink"],
+ "svd_path": "nrf52840.svd"
+ },
+ "frameworks": ["arduino"],
+ "name": "A modified NRF52840-DK devboard (Adafruit BSP)",
+ "upload": {
+ "maximum_ram_size": 248832,
+ "maximum_size": 815104,
+ "require_upload_port": true,
+ "speed": 115200,
+ "protocol": "jlink",
+ "protocols": ["jlink", "nrfjprog", "stlink"]
+ },
+ "url": "https://meshtastic.org/",
+ "vendor": "Nordic Semi"
+}
diff --git a/boards/t-echo.json b/boards/t-echo.json
index da67ef05e..9cb48b41a 100644
--- a/boards/t-echo.json
+++ b/boards/t-echo.json
@@ -7,12 +7,7 @@
"cpu": "cortex-m4",
"extra_flags": "-DARDUINO_NRF52840_TTGO_EINK -DNRF52840_XXAA",
"f_cpu": "64000000L",
- "hwids": [
- [
- "0x239A",
- "0x4405"
- ]
- ],
+ "hwids": [["0x239A", "0x4405"]],
"usb_product": "TTGO_eink",
"mcu": "nrf52840",
"variant": "t-echo",
@@ -30,35 +25,24 @@
"settings_addr": "0xFF000"
}
},
- "connectivity": [
- "bluetooth"
- ],
+ "connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52840_xxAA",
- "onboard_tools": [
- "jlink"
- ],
+ "onboard_tools": ["jlink"],
"svd_path": "nrf52840.svd"
},
- "frameworks": [
- "arduino"
- ],
+ "frameworks": ["arduino"],
"name": "TTGO eink (Adafruit BSP)",
- "upload": {
- "maximum_ram_size": 248832,
- "maximum_size": 815104,
- "speed": 115200,
- "protocol": "nrfutil",
- "protocols": [
- "jlink",
- "nrfjprog",
- "nrfutil",
- "stlink"
- ],
- "use_1200bps_touch": true,
- "require_upload_port": true,
- "wait_for_upload_port": true
+ "upload": {
+ "maximum_ram_size": 248832,
+ "maximum_size": 815104,
+ "speed": 115200,
+ "protocol": "nrfutil",
+ "protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
+ "use_1200bps_touch": true,
+ "require_upload_port": true,
+ "wait_for_upload_port": true
},
"url": "FIXME",
"vendor": "TTGO"
-}
\ No newline at end of file
+}
diff --git a/boards/tbeam-s3-core.json b/boards/tbeam-s3-core.json
index 06d93c6a0..767791d35 100644
--- a/boards/tbeam-s3-core.json
+++ b/boards/tbeam-s3-core.json
@@ -15,24 +15,15 @@
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
- "hwids": [
- [
- "0X303A",
- "0x1001"
- ]
- ],
+ "hwids": [["0X303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "tbeam-s3-core"
},
- "connectivity": [
- "wifi"
- ],
+ "connectivity": ["wifi"],
"debug": {
"openocd_target": "esp32s3.cfg"
},
- "frameworks": [
- "arduino"
- ],
+ "frameworks": ["arduino"],
"name": "LilyGo TBeam-S3-Core",
"upload": {
"flash_size": "8MB",
@@ -43,4 +34,4 @@
},
"url": "http://www.lilygo.cn/",
"vendor": "LilyGo"
-}
\ No newline at end of file
+}
diff --git a/boards/tlora-t3s3-v1.json b/boards/tlora-t3s3-v1.json
index 36a54ad2b..5af53084f 100644
--- a/boards/tlora-t3s3-v1.json
+++ b/boards/tlora-t3s3-v1.json
@@ -14,25 +14,15 @@
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
- "hwids": [
- [
- "0X303A",
- "0x1001"
- ]
- ],
+ "hwids": [["0X303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "tlora-t3s3-v1"
},
- "connectivity": [
- "wifi"
- ],
+ "connectivity": ["wifi"],
"debug": {
"openocd_target": "esp32s3.cfg"
},
- "frameworks": [
- "arduino",
- "espidf"
- ],
+ "frameworks": ["arduino", "espidf"],
"name": "LilyGo TLora-T3S3-V1",
"upload": {
"flash_size": "4MB",
@@ -44,4 +34,4 @@
},
"url": "http://www.lilygo.cn/",
"vendor": "LilyGo"
-}
\ No newline at end of file
+}
diff --git a/boards/wiscore_rak11200.json b/boards/wiscore_rak11200.json
index 6d794b14a..33d16ba77 100644
--- a/boards/wiscore_rak11200.json
+++ b/boards/wiscore_rak11200.json
@@ -1,6 +1,6 @@
{
"build": {
- "arduino":{
+ "arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
@@ -11,26 +11,14 @@
"mcu": "esp32",
"variant": "WisCore_RAK11200_Board"
},
- "connectivity": [
- "wifi",
- "bluetooth",
- "ethernet",
- "can"
- ],
- "frameworks": [
- "arduino",
- "espidf"
- ],
+ "connectivity": ["wifi", "bluetooth", "ethernet", "can"],
+ "frameworks": ["arduino", "espidf"],
"name": "WisCore RAK11200 Board",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
- "protocols": [
- "esptool",
- "espota",
- "ftdi"
- ],
+ "protocols": ["esptool", "espota", "ftdi"],
"require_upload_port": true,
"speed": 460800
},
diff --git a/boards/wiscore_rak4600.json b/boards/wiscore_rak4600.json
index 56f73f4b5..9969ef26e 100644
--- a/boards/wiscore_rak4600.json
+++ b/boards/wiscore_rak4600.json
@@ -8,22 +8,10 @@
"extra_flags": "-DNRF52832_XXAA -DNRF52",
"f_cpu": "64000000L",
"hwids": [
- [
- "0x239A",
- "0x8029"
- ],
- [
- "0x239A",
- "0x0029"
- ],
- [
- "0x239A",
- "0x002A"
- ],
- [
- "0x239A",
- "0x802A"
- ]
+ ["0x239A", "0x8029"],
+ ["0x239A", "0x0029"],
+ ["0x239A", "0x002A"],
+ ["0x239A", "0x802A"]
],
"usb_product": "Feather nRF52832 Express",
"mcu": "nrf52832",
@@ -41,17 +29,12 @@
"variant": "nrf52_adafruit_feather"
}
},
- "connectivity": [
- "bluetooth"
- ],
+ "connectivity": ["bluetooth"],
"debug": {
"jlink_device": "nRF52832_xxAA",
"svd_path": "nrf52.svd"
},
- "frameworks": [
- "arduino",
- "zephyr"
- ],
+ "frameworks": ["arduino", "zephyr"],
"name": "Adafruit Bluefruit nRF52832 Feather",
"upload": {
"maximum_ram_size": 65536,
@@ -59,13 +42,8 @@
"require_upload_port": true,
"speed": 115200,
"protocol": "nrfutil",
- "protocols": [
- "jlink",
- "nrfjprog",
- "nrfutil",
- "stlink"
- ]
+ "protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"]
},
"url": "https://www.adafruit.com/product/3406",
"vendor": "Adafruit"
-}
\ No newline at end of file
+}
diff --git a/boards/wiscore_rak4631.json b/boards/wiscore_rak4631.json
index 40c93ff04..149492688 100644
--- a/boards/wiscore_rak4631.json
+++ b/boards/wiscore_rak4631.json
@@ -1,72 +1,51 @@
{
- "build": {
- "arduino": {
- "ldscript": "nrf52840_s140_v6.ld"
- },
- "core": "nRF5",
- "cpu": "cortex-m4",
- "extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
- "f_cpu": "64000000L",
- "hwids": [
- [
- "0x239A",
- "0x8029"
- ],
- [
- "0x239A",
- "0x0029"
- ],
- [
- "0x239A",
- "0x002A"
- ],
- [
- "0x239A",
- "0x802A"
- ]
- ],
- "usb_product": "WisCore RAK4631 Board",
- "mcu": "nrf52840",
- "variant": "WisCore_RAK4631_Board",
- "bsp": {
- "name": "adafruit"
- },
- "softdevice": {
- "sd_flags": "-DS140",
- "sd_name": "s140",
- "sd_version": "6.1.1",
- "sd_fwid": "0x00B6"
- },
- "bootloader": {
- "settings_addr": "0xFF000"
- }
+ "build": {
+ "arduino": {
+ "ldscript": "nrf52840_s140_v6.ld"
},
- "connectivity": [
- "bluetooth"
+ "core": "nRF5",
+ "cpu": "cortex-m4",
+ "extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
+ "f_cpu": "64000000L",
+ "hwids": [
+ ["0x239A", "0x8029"],
+ ["0x239A", "0x0029"],
+ ["0x239A", "0x002A"],
+ ["0x239A", "0x802A"]
],
- "debug": {
- "jlink_device": "nRF52840_xxAA",
- "svd_path": "nrf52840.svd"
+ "usb_product": "WisCore RAK4631 Board",
+ "mcu": "nrf52840",
+ "variant": "WisCore_RAK4631_Board",
+ "bsp": {
+ "name": "adafruit"
},
- "frameworks": [
- "arduino"
- ],
- "name": "WisCore RAK4631 Board",
- "upload": {
- "maximum_ram_size": 248832,
- "maximum_size": 815104,
- "speed": 115200,
- "protocol": "nrfutil",
- "protocols": [
- "jlink",
- "nrfjprog",
- "nrfutil",
- "stlink"
- ],
- "use_1200bps_touch": true,
- "require_upload_port": true,
- "wait_for_upload_port": true
+ "softdevice": {
+ "sd_flags": "-DS140",
+ "sd_name": "s140",
+ "sd_version": "6.1.1",
+ "sd_fwid": "0x00B6"
},
- "url": "https://www.rakwireless.com",
- "vendor": "RAKwireless"
-}
\ No newline at end of file
+ "bootloader": {
+ "settings_addr": "0xFF000"
+ }
+ },
+ "connectivity": ["bluetooth"],
+ "debug": {
+ "jlink_device": "nRF52840_xxAA",
+ "svd_path": "nrf52840.svd"
+ },
+ "frameworks": ["arduino"],
+ "name": "WisCore RAK4631 Board",
+ "upload": {
+ "maximum_ram_size": 248832,
+ "maximum_size": 815104,
+ "speed": 115200,
+ "protocol": "nrfutil",
+ "protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
+ "use_1200bps_touch": true,
+ "require_upload_port": true,
+ "wait_for_upload_port": true
+ },
+ "url": "https://www.rakwireless.com",
+ "vendor": "RAKwireless"
+}
diff --git a/docker-compose.yml b/docker-compose.yml
index 33af95fd2..82f2647e8 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -8,6 +8,6 @@ services:
replicas: 4
networks:
- mesh
-
+
networks:
- mesh:
\ No newline at end of file
+ mesh:
diff --git a/platformio.ini b/platformio.ini
index e58656dd2..1d8083f70 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -39,7 +39,7 @@ extra_scripts = bin/platformio-custom.py
; The Radiolib stuff will speed up building considerably. Exclud all the stuff we dont need.
build_flags = -Wno-missing-field-initializers
-Wno-format
- -Isrc -Isrc/mesh -Isrc/gps -Isrc/buzz -Wl,-Map,.pio/build/output.map
+ -Isrc -Isrc/mesh -Isrc/mesh/generated -Isrc/gps -Isrc/buzz -Wl,-Map,.pio/build/output.map
-DUSE_THREAD_NAMES
-DTINYGPS_OPTION_NO_CUSTOM_FIELDS
-DPB_ENABLE_MALLOC=1
@@ -58,7 +58,7 @@ build_flags = -Wno-missing-field-initializers
monitor_speed = 115200
lib_deps =
- https://github.com/meshtastic/esp8266-oled-ssd1306.git#53580644255b48ebb7a737343c6b4e71c7e11cf2 ; ESP8266_SSD1306
+ https://github.com/meshtastic/esp8266-oled-ssd1306.git#da1ede4dfcd91074283b029080759fd744120909 ; ESP8266_SSD1306
mathertel/OneButton@^2.0.3 ; OneButton library for non-blocking button debounce
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
https://github.com/meshtastic/TinyGPSPlus.git#127ad674ef85f0201cb68a065879653ed94792c4
@@ -66,7 +66,7 @@ lib_deps =
nanopb/Nanopb@^0.4.6
erriez/ErriezCRC32@^1.0.1
; jgromes/RadioLib@^5.5.1
- https://github.com/jgromes/RadioLib.git#395844922c5d88d5db0481a9c91479931172428d
+ https://github.com/jgromes/RadioLib.git#1afa947030c5637f71f6563bc22aa75032e53a57
; Used for the code analysis in PIO Home / Inspect
check_tool = cppcheck
diff --git a/protobufs b/protobufs
index 3b0d871ca..b9953ff48 160000
--- a/protobufs
+++ b/protobufs
@@ -1 +1 @@
-Subproject commit 3b0d871ca1e0f8a2ed823f0696e2d7cf31ed2ebd
+Subproject commit b9953ff48b81a06e062e35ff3c2ea6de862ee144
diff --git a/src/BluetoothCommon.cpp b/src/BluetoothCommon.cpp
index 728b6f360..53faae997 100644
--- a/src/BluetoothCommon.cpp
+++ b/src/BluetoothCommon.cpp
@@ -1,5 +1,5 @@
-#include "configuration.h"
#include "BluetoothCommon.h"
+#include "configuration.h"
// NRF52 wants these constants as byte arrays
// Generated here https://yupana-engineering.com/online-uuid-to-c-array-converter - but in REVERSE BYTE ORDER
diff --git a/src/ButtonThread.h b/src/ButtonThread.h
index d94b6a769..5bb856027 100644
--- a/src/ButtonThread.h
+++ b/src/ButtonThread.h
@@ -115,8 +115,7 @@ class ButtonThread : public concurrency::OSThread
{
// LOG_DEBUG("press!\n");
#ifdef BUTTON_PIN
- if ((BUTTON_PIN != moduleConfig.canned_message.inputbroker_pin_press) ||
- !moduleConfig.canned_message.enabled) {
+ if ((BUTTON_PIN != moduleConfig.canned_message.inputbroker_pin_press) || !moduleConfig.canned_message.enabled) {
powerFSM.trigger(EVENT_PRESS);
}
#endif
@@ -144,10 +143,10 @@ class ButtonThread : public concurrency::OSThread
#ifdef PIN_LED1
ledOff(PIN_LED1);
#endif
-#ifdef PIN_LED2
+#ifdef PIN_LED2
ledOff(PIN_LED2);
#endif
-#ifdef PIN_LED3
+#ifdef PIN_LED3
ledOff(PIN_LED3);
#endif
shutdown_on_long_stop = true;
@@ -160,28 +159,25 @@ class ButtonThread : public concurrency::OSThread
static void userButtonDoublePressed()
{
- #if defined(USE_EINK) && defined(PIN_EINK_EN)
+#if defined(USE_EINK) && defined(PIN_EINK_EN)
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
- #endif
- #if defined(GPS_POWER_TOGGLE)
- if(config.position.gps_enabled)
- {
- LOG_DEBUG("Flag set to false for gps power\n");
- }
- else
- {
- LOG_DEBUG("Flag set to true to restore power\n");
- }
- config.position.gps_enabled = !(config.position.gps_enabled);
- doGPSpowersave(config.position.gps_enabled);
- #endif
+#endif
+ screen->print("Sent ad-hoc ping\n");
+ service.refreshMyNodeInfo();
+ service.sendNetworkPing(NODENUM_BROADCAST, true);
}
static void userButtonMultiPressed()
{
- screen->print("Sent ad-hoc ping\n");
- service.refreshMyNodeInfo();
- service.sendNetworkPing(NODENUM_BROADCAST, true);
+#if defined(GPS_POWER_TOGGLE)
+ if (config.position.gps_enabled) {
+ LOG_DEBUG("Flag set to false for gps power\n");
+ } else {
+ LOG_DEBUG("Flag set to true to restore power\n");
+ }
+ config.position.gps_enabled = !(config.position.gps_enabled);
+ doGPSpowersave(config.position.gps_enabled);
+#endif
}
static void userButtonPressedLongStart()
diff --git a/src/FSCommon.cpp b/src/FSCommon.cpp
index 73d5d92b3..32e5d7e28 100644
--- a/src/FSCommon.cpp
+++ b/src/FSCommon.cpp
@@ -1,26 +1,24 @@
-#include "configuration.h"
#include "FSCommon.h"
+#include "configuration.h"
#ifdef HAS_SDCARD
-#include
#include
+#include
-
-#ifdef SDCARD_USE_SPI1
+#ifdef SDCARD_USE_SPI1
SPIClass SPI1(HSPI);
#define SDHandler SPI1
#endif
+#endif // HAS_SDCARD
-#endif //HAS_SDCARD
-
-bool copyFile(const char* from, const char* to)
+bool copyFile(const char *from, const char *to)
{
#ifdef FSCom
unsigned char cbuffer[16];
-
+
File f1 = FSCom.open(from, FILE_O_READ);
- if (!f1){
+ if (!f1) {
LOG_ERROR("Failed to open source file %s\n", from);
return false;
}
@@ -30,92 +28,92 @@ bool copyFile(const char* from, const char* to)
LOG_ERROR("Failed to open destination file %s\n", to);
return false;
}
-
+
while (f1.available() > 0) {
byte i = f1.read(cbuffer, 16);
f2.write(cbuffer, i);
}
-
+
f2.close();
f1.close();
return true;
#endif
}
-bool renameFile(const char* pathFrom, const char* pathTo)
+bool renameFile(const char *pathFrom, const char *pathTo)
{
#ifdef FSCom
#ifdef ARCH_ESP32
// rename was fixed for ESP32 IDF LittleFS in April
return FSCom.rename(pathFrom, pathTo);
#else
- if (copyFile(pathFrom, pathTo) && FSCom.remove(pathFrom) ) {
+ if (copyFile(pathFrom, pathTo) && FSCom.remove(pathFrom)) {
return true;
- } else{
+ } else {
return false;
}
#endif
#endif
}
-void listDir(const char * dirname, uint8_t levels, boolean del = false)
+void listDir(const char *dirname, uint8_t levels, boolean del = false)
{
#ifdef FSCom
#if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
char buffer[255];
#endif
File root = FSCom.open(dirname, FILE_O_READ);
- if(!root){
+ if (!root) {
return;
}
- if(!root.isDirectory()){
+ if (!root.isDirectory()) {
return;
}
File file = root.openNextFile();
- while(file){
- if(file.isDirectory() && !String(file.name()).endsWith(".")) {
- if(levels){
+ while (file) {
+ if (file.isDirectory() && !String(file.name()).endsWith(".")) {
+ if (levels) {
#ifdef ARCH_ESP32
- listDir(file.path(), levels -1, del);
- if(del) {
+ listDir(file.path(), levels - 1, del);
+ if (del) {
LOG_DEBUG("Removing %s\n", file.path());
- strcpy(buffer, file.path());
+ strncpy(buffer, file.path(), sizeof(buffer));
file.close();
FSCom.rmdir(buffer);
} else {
file.close();
}
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
- listDir(file.name(), levels -1, del);
- if(del) {
+ listDir(file.name(), levels - 1, del);
+ if (del) {
LOG_DEBUG("Removing %s\n", file.name());
- strcpy(buffer, file.name());
+ strncpy(buffer, file.name(), sizeof(buffer));
file.close();
FSCom.rmdir(buffer);
} else {
file.close();
- }
+ }
#else
- listDir(file.name(), levels -1, del);
+ listDir(file.name(), levels - 1, del);
file.close();
#endif
}
} else {
#ifdef ARCH_ESP32
- if(del) {
+ if (del) {
LOG_DEBUG("Deleting %s\n", file.path());
- strcpy(buffer, file.path());
+ strncpy(buffer, file.path(), sizeof(buffer));
file.close();
FSCom.remove(buffer);
} else {
- LOG_DEBUG(" %s (%i Bytes)\n", file.path(), file.size());
+ LOG_DEBUG(" %s (%i Bytes)\n", file.path(), file.size());
file.close();
}
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
- if(del) {
+ if (del) {
LOG_DEBUG("Deleting %s\n", file.name());
- strcpy(buffer, file.name());
+ strncpy(buffer, file.name(), sizeof(buffer));
file.close();
FSCom.remove(buffer);
} else {
@@ -125,23 +123,23 @@ void listDir(const char * dirname, uint8_t levels, boolean del = false)
#else
LOG_DEBUG(" %s (%i Bytes)\n", file.name(), file.size());
file.close();
-#endif
+#endif
}
file = root.openNextFile();
}
-#ifdef ARCH_ESP32
- if(del) {
+#ifdef ARCH_ESP32
+ if (del) {
LOG_DEBUG("Removing %s\n", root.path());
- strcpy(buffer, root.path());
+ strncpy(buffer, root.path(), sizeof(buffer));
root.close();
FSCom.rmdir(buffer);
} else {
root.close();
}
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
- if(del) {
+ if (del) {
LOG_DEBUG("Removing %s\n", root.name());
- strcpy(buffer, root.name());
+ strncpy(buffer, root.name(), sizeof(buffer));
root.close();
FSCom.rmdir(buffer);
} else {
@@ -153,7 +151,7 @@ void listDir(const char * dirname, uint8_t levels, boolean del = false)
#endif
}
-void rmDir(const char * dirname)
+void rmDir(const char *dirname)
{
#ifdef FSCom
#if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
@@ -168,10 +166,9 @@ void rmDir(const char * dirname)
void fsInit()
{
#ifdef FSCom
- if (!FSBegin())
- {
- LOG_ERROR("Filesystem mount Failed. Formatting...\n");
- assert(0); // FIXME - report failure to phone
+ if (!FSBegin()) {
+ LOG_ERROR("Filesystem mount Failed.\n");
+ // assert(0); This auto-formats the partition, so no need to fail here.
}
#ifdef ARCH_ESP32
LOG_DEBUG("Filesystem files (%d/%d Bytes):\n", FSCom.usedBytes(), FSCom.totalBytes());
@@ -182,7 +179,6 @@ void fsInit()
#endif
}
-
void setupSDCard()
{
#ifdef HAS_SDCARD
@@ -190,12 +186,12 @@ void setupSDCard()
if (!SD.begin(SDCARD_CS, SDHandler)) {
LOG_DEBUG("No SD_MMC card detected\n");
- return ;
+ return;
}
uint8_t cardType = SD.cardType();
if (cardType == CARD_NONE) {
LOG_DEBUG("No SD_MMC card attached\n");
- return ;
+ return;
}
LOG_DEBUG("SD_MMC Card Type: ");
if (cardType == CARD_MMC) {
@@ -214,6 +210,3 @@ void setupSDCard()
LOG_DEBUG("Used space: %llu MB\n", SD.usedBytes() / (1024 * 1024));
#endif
}
-
-
-
diff --git a/src/FSCommon.h b/src/FSCommon.h
index e304a455b..98d3911d7 100644
--- a/src/FSCommon.h
+++ b/src/FSCommon.h
@@ -17,7 +17,7 @@
// RP2040
#include "LittleFS.h"
#define FSCom LittleFS
-#define FSBegin() FSCom.begin()
+#define FSBegin() FSCom.begin() // set autoformat
#define FILE_O_WRITE "w"
#define FILE_O_READ "r"
#endif
@@ -26,7 +26,7 @@
// ESP32 version
#include "LittleFS.h"
#define FSCom LittleFS
-#define FSBegin() FSCom.begin(true)
+#define FSBegin() FSCom.begin(true) // format on failure
#define FILE_O_WRITE "w"
#define FILE_O_READ "r"
#endif
@@ -35,13 +35,13 @@
// NRF52 version
#include "InternalFileSystem.h"
#define FSCom InternalFS
-#define FSBegin() FSCom.begin()
+#define FSBegin() FSCom.begin() // InternalFS formats on failure
using namespace Adafruit_LittleFS_Namespace;
#endif
void fsInit();
-bool copyFile(const char* from, const char* to);
-bool renameFile(const char* pathFrom, const char* pathTo);
-void listDir(const char * dirname, uint8_t levels, boolean del);
-void rmDir(const char * dirname);
+bool copyFile(const char *from, const char *to);
+bool renameFile(const char *pathFrom, const char *pathTo);
+void listDir(const char *dirname, uint8_t levels, boolean del);
+void rmDir(const char *dirname);
void setupSDCard();
\ No newline at end of file
diff --git a/src/GPSStatus.h b/src/GPSStatus.h
index c76b66103..bdfce36ff 100644
--- a/src/GPSStatus.h
+++ b/src/GPSStatus.h
@@ -20,15 +20,15 @@ class GPSStatus : public Status
bool hasLock = false; // default to false, until we complete our first read
bool isConnected = false; // Do we have a GPS we are talking to
- bool isPowerSaving = false; //Are we in power saving state
+ bool isPowerSaving = false; // Are we in power saving state
- Position p = Position_init_default;
+ meshtastic_Position p = meshtastic_Position_init_default;
public:
GPSStatus() { statusType = STATUS_TYPE_GPS; }
// preferred method
- GPSStatus(bool hasLock, bool isConnected, bool isPowerSaving, const Position &pos) : Status()
+ GPSStatus(bool hasLock, bool isConnected, bool isPowerSaving, const meshtastic_Position &pos) : Status()
{
this->hasLock = hasLock;
this->isConnected = isConnected;
@@ -47,7 +47,7 @@ class GPSStatus : public Status
bool getIsConnected() const { return isConnected; }
- bool getIsPowerSaving() const { return isPowerSaving;}
+ bool getIsPowerSaving() const { return isPowerSaving; }
int32_t getLatitude() const
{
@@ -55,7 +55,7 @@ class GPSStatus : public Status
#ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed latitude\n");
#endif
- NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
+ meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
return node->position.latitude_i;
} else {
return p.latitude_i;
@@ -68,7 +68,7 @@ class GPSStatus : public Status
#ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed longitude\n");
#endif
- NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
+ meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
return node->position.longitude_i;
} else {
return p.longitude_i;
@@ -81,29 +81,38 @@ class GPSStatus : public Status
#ifdef GPS_EXTRAVERBOSE
LOG_WARN("Using fixed altitude\n");
#endif
- NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
+ meshtastic_NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
return node->position.altitude;
} else {
return p.altitude;
}
}
- uint32_t getDOP() const { return p.PDOP; }
+ uint32_t getDOP() const
+ {
+ return p.PDOP;
+ }
- uint32_t getHeading() const { return p.ground_track; }
+ uint32_t getHeading() const
+ {
+ return p.ground_track;
+ }
- uint32_t getNumSatellites() const { return p.sats_in_view; }
+ uint32_t getNumSatellites() const
+ {
+ return p.sats_in_view;
+ }
bool matches(const GPSStatus *newStatus) const
{
#ifdef GPS_EXTRAVERBOSE
LOG_DEBUG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.pos_timestamp, p.pos_timestamp);
#endif
- return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected || newStatus->isPowerSaving !=isPowerSaving ||
- newStatus->p.latitude_i != p.latitude_i || newStatus->p.longitude_i != p.longitude_i ||
- newStatus->p.altitude != p.altitude || newStatus->p.altitude_hae != p.altitude_hae ||
- newStatus->p.PDOP != p.PDOP || newStatus->p.ground_track != p.ground_track ||
- newStatus->p.ground_speed != p.ground_speed ||
+ return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected ||
+ newStatus->isPowerSaving != isPowerSaving || newStatus->p.latitude_i != p.latitude_i ||
+ newStatus->p.longitude_i != p.longitude_i || newStatus->p.altitude != p.altitude ||
+ newStatus->p.altitude_hae != p.altitude_hae || newStatus->p.PDOP != p.PDOP ||
+ newStatus->p.ground_track != p.ground_track || newStatus->p.ground_speed != p.ground_speed ||
newStatus->p.sats_in_view != p.sats_in_view);
}
diff --git a/src/NodeStatus.h b/src/NodeStatus.h
index 7c0477cf6..e6bf31aed 100644
--- a/src/NodeStatus.h
+++ b/src/NodeStatus.h
@@ -1,83 +1,68 @@
#pragma once
-#include
#include "Status.h"
#include "configuration.h"
+#include
-namespace meshtastic {
+namespace meshtastic
+{
- /// Describes the state of the NodeDB system.
- class NodeStatus : public Status
+/// Describes the state of the NodeDB system.
+class NodeStatus : public Status
+{
+
+ private:
+ CallbackObserver statusObserver =
+ CallbackObserver(this, &NodeStatus::updateStatus);
+
+ uint8_t numOnline = 0;
+ uint8_t numTotal = 0;
+
+ uint8_t lastNumTotal = 0;
+
+ public:
+ bool forceUpdate = false;
+
+ NodeStatus() { statusType = STATUS_TYPE_NODE; }
+ NodeStatus(uint8_t numOnline, uint8_t numTotal, bool forceUpdate = false) : Status()
{
+ this->forceUpdate = forceUpdate;
+ this->numOnline = numOnline;
+ this->numTotal = numTotal;
+ }
+ NodeStatus(const NodeStatus &);
+ NodeStatus &operator=(const NodeStatus &);
- private:
- CallbackObserver statusObserver = CallbackObserver(this, &NodeStatus::updateStatus);
+ void observe(Observable *source) { statusObserver.observe(source); }
- uint8_t numOnline = 0;
- uint8_t numTotal = 0;
+ uint8_t getNumOnline() const { return numOnline; }
- uint8_t lastNumTotal = 0;
+ uint8_t getNumTotal() const { return numTotal; }
- public:
- bool forceUpdate = false;
+ uint8_t getLastNumTotal() const { return lastNumTotal; }
- NodeStatus() {
- statusType = STATUS_TYPE_NODE;
- }
- NodeStatus( uint8_t numOnline, uint8_t numTotal, bool forceUpdate = false ) : Status()
+ bool matches(const NodeStatus *newStatus) const
+ {
+ return (newStatus->getNumOnline() != numOnline || newStatus->getNumTotal() != numTotal);
+ }
+ int updateStatus(const NodeStatus *newStatus)
+ {
+ // Only update the status if values have actually changed
+ lastNumTotal = numTotal;
+ bool isDirty;
{
- this->forceUpdate = forceUpdate;
- this->numOnline = numOnline;
- this->numTotal = numTotal;
+ isDirty = matches(newStatus);
+ initialized = true;
+ numOnline = newStatus->getNumOnline();
+ numTotal = newStatus->getNumTotal();
}
- NodeStatus(const NodeStatus &);
- NodeStatus &operator=(const NodeStatus &);
-
- void observe(Observable *source)
- {
- statusObserver.observe(source);
+ if (isDirty || newStatus->forceUpdate) {
+ LOG_DEBUG("Node status update: %d online, %d total\n", numOnline, numTotal);
+ onNewStatus.notifyObservers(this);
}
+ return 0;
+ }
+};
- uint8_t getNumOnline() const
- {
- return numOnline;
- }
-
- uint8_t getNumTotal() const
- {
- return numTotal;
- }
-
- uint8_t getLastNumTotal() const
- {
- return lastNumTotal;
- }
-
- bool matches(const NodeStatus *newStatus) const
- {
- return (
- newStatus->getNumOnline() != numOnline ||
- newStatus->getNumTotal() != numTotal
- );
- }
- int updateStatus(const NodeStatus *newStatus) {
- // Only update the status if values have actually changed
- lastNumTotal = numTotal;
- bool isDirty;
- {
- isDirty = matches(newStatus);
- initialized = true;
- numOnline = newStatus->getNumOnline();
- numTotal = newStatus->getNumTotal();
- }
- if(isDirty || newStatus->forceUpdate) {
- LOG_DEBUG("Node status update: %d online, %d total\n", numOnline, numTotal);
- onNewStatus.notifyObservers(this);
- }
- return 0;
- }
-
- };
-
-}
+} // namespace meshtastic
extern meshtastic::NodeStatus *nodeStatus;
\ No newline at end of file
diff --git a/src/OSTimer.cpp b/src/OSTimer.cpp
index a0161cd42..0f7177a87 100644
--- a/src/OSTimer.cpp
+++ b/src/OSTimer.cpp
@@ -1,5 +1,5 @@
-#include "configuration.h"
#include "OSTimer.h"
+#include "configuration.h"
/**
* Schedule a callback to run. The callback must _not_ block, though it is called from regular thread level (not ISR)
diff --git a/src/Observer.cpp b/src/Observer.cpp
index 6d1124684..bc938d965 100644
--- a/src/Observer.cpp
+++ b/src/Observer.cpp
@@ -1,3 +1,2 @@
-#include "configuration.h"
#include "Observer.h"
-
+#include "configuration.h"
diff --git a/src/Observer.h b/src/Observer.h
index ccc7f37b6..555dcd1e9 100644
--- a/src/Observer.h
+++ b/src/Observer.h
@@ -1,7 +1,6 @@
#pragma once
#include
-#include
#include
template class Observable;
@@ -11,7 +10,7 @@ template class Observable;
*/
template class Observer
{
- std::list *> observed;
+ std::list *> observed;
public:
virtual ~Observer();
@@ -88,7 +87,7 @@ template class Observable
template Observer::~Observer()
{
for (typename std::list *>::const_iterator iterator = observed.begin(); iterator != observed.end();
- ++iterator) {
+ ++iterator) {
(*iterator)->removeObserver(this);
}
observed.clear();
diff --git a/src/Power.cpp b/src/Power.cpp
index 1ea5b72b3..082c05181 100644
--- a/src/Power.cpp
+++ b/src/Power.cpp
@@ -1,16 +1,16 @@
#include "power.h"
#include "NodeDB.h"
#include "PowerFSM.h"
+#include "buzz/buzz.h"
#include "configuration.h"
#include "main.h"
#include "sleep.h"
#include "utils.h"
-#include "buzz/buzz.h"
#ifdef HAS_PMU
-#include "XPowersLibInterface.hpp"
-#include "XPowersAXP2101.tpp"
#include "XPowersAXP192.tpp"
+#include "XPowersAXP2101.tpp"
+#include "XPowersLibInterface.hpp"
XPowersLibInterface *PMU = NULL;
#else
// Copy of the base class defined in axp20x.h.
@@ -108,20 +108,20 @@ class AnalogBatteryLevel : public HasBatteryLevel
#ifdef BATTERY_PIN
// Override variant or default ADC_MULTIPLIER if we have the override pref
- float operativeAdcMultiplier = config.power.adc_multiplier_override > 0
- ? config.power.adc_multiplier_override
- : ADC_MULTIPLIER;
+ float operativeAdcMultiplier =
+ config.power.adc_multiplier_override > 0 ? config.power.adc_multiplier_override : ADC_MULTIPLIER;
// Do not call analogRead() often.
const uint32_t min_read_interval = 5000;
if (millis() - last_read_time_ms > min_read_interval) {
last_read_time_ms = millis();
-//Set the number of samples, it has an effect of increasing sensitivity, especially in complex electromagnetic environment.
+ // Set the number of samples, it has an effect of increasing sensitivity, especially in complex electromagnetic
+ // environment.
uint32_t raw = 0;
- for(uint32_t i=0; i chargingVolt; }
+ virtual bool isVbusIn() override
+ {
+ return getBattVoltage() > chargingVolt;
+ }
/// Assume charging if we have a battery and external power is connected.
/// we can't be smart enough to say 'full'?
- virtual bool isCharging() override { return isBatteryConnect() && isVbusIn(); }
+ virtual bool isCharging() override
+ {
+ return isBatteryConnect() && isVbusIn();
+ }
private:
/// If we see a battery voltage higher than physics allows - assume charger is pumping
@@ -159,16 +168,16 @@ class AnalogBatteryLevel : public HasBatteryLevel
#ifndef BAT_FULLVOLT
#define BAT_FULLVOLT 4200
-#endif
+#endif
#ifndef BAT_EMPTYVOLT
#define BAT_EMPTYVOLT 3270
-#endif
+#endif
#ifndef BAT_CHARGINGVOLT
#define BAT_CHARGINGVOLT 4210
-#endif
+#endif
#ifndef BAT_NOBATVOLT
#define BAT_NOBATVOLT 2230
-#endif
+#endif
/// For heltecs with no battery connected, the measured voltage is 2204, so raising to 2230 from 2100
const float fullVolt = BAT_FULLVOLT, emptyVolt = BAT_EMPTYVOLT, chargingVolt = BAT_CHARGINGVOLT, noBatVolt = BAT_NOBATVOLT;
@@ -238,12 +247,12 @@ void Power::shutdown()
{
screen->setOn(false);
#if defined(USE_EINK) && defined(PIN_EINK_EN)
- digitalWrite(PIN_EINK_EN, LOW); //power off backlight first
+ digitalWrite(PIN_EINK_EN, LOW); // power off backlight first
#endif
#ifdef HAS_PMU
LOG_INFO("Shutting down\n");
- if(PMU) {
+ if (PMU) {
PMU->setChargingLedMode(XPOWERS_CHG_LED_OFF);
PMU->shutdown();
}
@@ -290,15 +299,16 @@ void Power::readPowerStatus()
if (lastheap != ESP.getFreeHeap()) {
LOG_DEBUG("Threads running:");
int running = 0;
- for(int i = 0; i < MAX_THREADS; i++){
+ for (int i = 0; i < MAX_THREADS; i++) {
auto thread = concurrency::mainController.get(i);
- if((thread != nullptr) && (thread->enabled)) {
+ if ((thread != nullptr) && (thread->enabled)) {
LOG_DEBUG(" %s", thread->ThreadName.c_str());
running++;
}
}
LOG_DEBUG("\n");
- LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads\n", ESP.getFreeHeap(), ESP.getHeapSize(), ESP.getFreeHeap() - lastheap, running, concurrency::mainController.size(false));
+ LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads\n", ESP.getFreeHeap(), ESP.getHeapSize(),
+ ESP.getFreeHeap() - lastheap, running, concurrency::mainController.size(false));
lastheap = ESP.getFreeHeap();
}
#endif
@@ -312,7 +322,7 @@ void Power::readPowerStatus()
LOG_DEBUG("Warning RAK4631 Low voltage counter: %d/10\n", low_voltage_counter);
if (low_voltage_counter > 10) {
// We can't trigger deep sleep on NRF52, it's freezing the board
- //powerFSM.trigger(EVENT_LOW_BATTERY);
+ // powerFSM.trigger(EVENT_LOW_BATTERY);
LOG_DEBUG("Low voltage detected, but not triggering deep sleep\n");
}
} else {
@@ -338,11 +348,11 @@ int32_t Power::runOnce()
#ifdef HAS_PMU
// WE no longer use the IRQ line to wake the CPU (due to false wakes from sleep), but we do poll
// the IRQ status by reading the registers over I2C
- if(PMU) {
+ if (PMU) {
PMU->getIrqStatus();
- if(PMU->isVbusRemoveIrq()){
+ if (PMU->isVbusRemoveIrq()) {
LOG_INFO("USB unplugged\n");
powerFSM.trigger(EVENT_POWER_DISCONNECTED);
}
@@ -388,24 +398,24 @@ int32_t Power::runOnce()
share the same i2c bus, instead use ssd1306 sleep mode DCDC2 -> unused DCDC3 0.7-3.5V @ 700mA max -> ESP32 (keep this on!) LDO1
30mA -> charges GPS backup battery // charges the tiny J13 battery by the GPS to power the GPS ram (for a couple of days), can
not be turned off LDO2 200mA -> LORA LDO3 200mA -> GPS
- *
+ *
*/
bool Power::axpChipInit()
{
#ifdef HAS_PMU
- TwoWire * w = NULL;
+ TwoWire *w = NULL;
// Use macro to distinguish which wire is used by PMU
#ifdef PMU_USE_WIRE1
- w = &Wire1;
+ w = &Wire1;
#else
- w = &Wire;
+ w = &Wire;
#endif
/**
- * It is not necessary to specify the wire pin,
+ * It is not necessary to specify the wire pin,
* just input the wire, because the wire has been initialized in main.cpp
*/
if (!PMU) {
@@ -431,11 +441,11 @@ bool Power::axpChipInit()
}
if (!PMU) {
- /*
- * In XPowersLib, if the XPowersAXPxxx object is released, Wire.end() will be called at the same time.
- * In order not to affect other devices, if the initialization of the PMU fails, Wire needs to be re-initialized once,
- * if there are multiple devices sharing the bus.
- * * */
+ /*
+ * In XPowersLib, if the XPowersAXPxxx object is released, Wire.end() will be called at the same time.
+ * In order not to affect other devices, if the initialization of the PMU fails, Wire needs to be re-initialized once,
+ * if there are multiple devices sharing the bus.
+ * * */
#ifndef PMU_USE_WIRE1
w->begin(I2C_SDA, I2C_SCL);
#endif
@@ -445,48 +455,45 @@ bool Power::axpChipInit()
batteryLevel = PMU;
if (PMU->getChipModel() == XPOWERS_AXP192) {
-
+
// lora radio power channel
PMU->setPowerChannelVoltage(XPOWERS_LDO2, 3300);
PMU->enablePowerOutput(XPOWERS_LDO2);
-
// oled module power channel,
- // disable it will cause abnormal communication between boot and AXP power supply,
+ // disable it will cause abnormal communication between boot and AXP power supply,
// do not turn it off
PMU->setPowerChannelVoltage(XPOWERS_DCDC1, 3300);
// enable oled power
PMU->enablePowerOutput(XPOWERS_DCDC1);
-
// gnss module power channel - now turned on in setGpsPower
PMU->setPowerChannelVoltage(XPOWERS_LDO3, 3300);
// PMU->enablePowerOutput(XPOWERS_LDO3);
-
- //protected oled power source
+ // protected oled power source
PMU->setProtectedChannel(XPOWERS_DCDC1);
- //protected esp32 power source
+ // protected esp32 power source
PMU->setProtectedChannel(XPOWERS_DCDC3);
- //disable not use channel
+ // disable not use channel
PMU->disablePowerOutput(XPOWERS_DCDC2);
- //disable all axp chip interrupt
+ // disable all axp chip interrupt
PMU->disableIRQ(XPOWERS_AXP192_ALL_IRQ);
// Set constant current charging current
PMU->setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_450MA);
- //Set up the charging voltage
+ // Set up the charging voltage
PMU->setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2);
} else if (PMU->getChipModel() == XPOWERS_AXP2101) {
- // t-beam s3 core
+ // t-beam s3 core
/**
- * gnss module power channel
+ * gnss module power channel
* The default ALDO4 is off, you need to turn on the GNSS power first, otherwise it will be invalid during initialization
*/
PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300);
@@ -496,51 +503,50 @@ bool Power::axpChipInit()
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO3);
- // m.2 interface
+ // m.2 interface
PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300);
PMU->enablePowerOutput(XPOWERS_DCDC3);
/**
- * ALDO2 cannot be turned off.
- * It is a necessary condition for sensor communication.
- * It must be turned on to properly access the sensor and screen
- * It is also responsible for the power supply of PCF8563
- */
+ * ALDO2 cannot be turned off.
+ * It is a necessary condition for sensor communication.
+ * It must be turned on to properly access the sensor and screen
+ * It is also responsible for the power supply of PCF8563
+ */
PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO2);
- // 6-axis , magnetometer ,bme280 , oled screen power channel
+ // 6-axis , magnetometer ,bme280 , oled screen power channel
PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300);
PMU->enablePowerOutput(XPOWERS_ALDO1);
- // sdcard power channle
+ // sdcard power channle
PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300);
PMU->enablePowerOutput(XPOWERS_BLDO1);
-
+
// PMU->setPowerChannelVoltage(XPOWERS_DCDC4, 3300);
// PMU->enablePowerOutput(XPOWERS_DCDC4);
- //not use channel
- PMU->disablePowerOutput(XPOWERS_DCDC2); //not elicited
- PMU->disablePowerOutput(XPOWERS_DCDC5); //not elicited
- PMU->disablePowerOutput(XPOWERS_DLDO1); //Invalid power channel, it does not exist
- PMU->disablePowerOutput(XPOWERS_DLDO2); //Invalid power channel, it does not exist
+ // not use channel
+ PMU->disablePowerOutput(XPOWERS_DCDC2); // not elicited
+ PMU->disablePowerOutput(XPOWERS_DCDC5); // not elicited
+ PMU->disablePowerOutput(XPOWERS_DLDO1); // Invalid power channel, it does not exist
+ PMU->disablePowerOutput(XPOWERS_DLDO2); // Invalid power channel, it does not exist
PMU->disablePowerOutput(XPOWERS_VBACKUP);
- //disable all axp chip interrupt
+ // disable all axp chip interrupt
PMU->disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
- //Set the constant current charging current of AXP2101, temporarily use 500mA by default
+ // Set the constant current charging current of AXP2101, temporarily use 500mA by default
PMU->setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_500MA);
- //Set up the charging voltage
+ // Set up the charging voltage
PMU->setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2);
}
-
PMU->clearIrqStatus();
- // TBeam1.1 /T-Beam S3-Core has no external TS detection,
+ // TBeam1.1 /T-Beam S3-Core has no external TS detection,
// it needs to be disabled, otherwise it will cause abnormal charging
PMU->disableTSPinMeasure();
@@ -550,40 +556,52 @@ bool Power::axpChipInit()
LOG_DEBUG("=======================================================================\n");
if (PMU->isChannelAvailable(XPOWERS_DCDC1)) {
- LOG_DEBUG("DC1 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC1));
+ LOG_DEBUG("DC1 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-",
+ PMU->getPowerChannelVoltage(XPOWERS_DCDC1));
}
if (PMU->isChannelAvailable(XPOWERS_DCDC2)) {
- LOG_DEBUG("DC2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC2));
+ LOG_DEBUG("DC2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-",
+ PMU->getPowerChannelVoltage(XPOWERS_DCDC2));
}
if (PMU->isChannelAvailable(XPOWERS_DCDC3)) {
- LOG_DEBUG("DC3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC3));
+ LOG_DEBUG("DC3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-",
+ PMU->getPowerChannelVoltage(XPOWERS_DCDC3));
}
if (PMU->isChannelAvailable(XPOWERS_DCDC4)) {
- LOG_DEBUG("DC4 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC4));
+ LOG_DEBUG("DC4 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-",
+ PMU->getPowerChannelVoltage(XPOWERS_DCDC4));
}
if (PMU->isChannelAvailable(XPOWERS_LDO2)) {
- LOG_DEBUG("LDO2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO2));
+ LOG_DEBUG("LDO2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-",
+ PMU->getPowerChannelVoltage(XPOWERS_LDO2));
}
if (PMU->isChannelAvailable(XPOWERS_LDO3)) {
- LOG_DEBUG("LDO3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO3));
+ LOG_DEBUG("LDO3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-",
+ PMU->getPowerChannelVoltage(XPOWERS_LDO3));
}
if (PMU->isChannelAvailable(XPOWERS_ALDO1)) {
- LOG_DEBUG("ALDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO1));
+ LOG_DEBUG("ALDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-",
+ PMU->getPowerChannelVoltage(XPOWERS_ALDO1));
}
if (PMU->isChannelAvailable(XPOWERS_ALDO2)) {
- LOG_DEBUG("ALDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO2));
+ LOG_DEBUG("ALDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-",
+ PMU->getPowerChannelVoltage(XPOWERS_ALDO2));
}
if (PMU->isChannelAvailable(XPOWERS_ALDO3)) {
- LOG_DEBUG("ALDO3: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO3));
+ LOG_DEBUG("ALDO3: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-",
+ PMU->getPowerChannelVoltage(XPOWERS_ALDO3));
}
if (PMU->isChannelAvailable(XPOWERS_ALDO4)) {
- LOG_DEBUG("ALDO4: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO4));
+ LOG_DEBUG("ALDO4: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-",
+ PMU->getPowerChannelVoltage(XPOWERS_ALDO4));
}
if (PMU->isChannelAvailable(XPOWERS_BLDO1)) {
- LOG_DEBUG("BLDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO1));
+ LOG_DEBUG("BLDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-",
+ PMU->getPowerChannelVoltage(XPOWERS_BLDO1));
}
if (PMU->isChannelAvailable(XPOWERS_BLDO2)) {
- LOG_DEBUG("BLDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO2));
+ LOG_DEBUG("BLDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-",
+ PMU->getPowerChannelVoltage(XPOWERS_BLDO2));
}
LOG_DEBUG("=======================================================================\n");
@@ -597,30 +615,29 @@ bool Power::axpChipInit()
PMU->setSysPowerDownVoltage(2600);
#endif
-
#ifdef PMU_IRQ
- uint64_t pmuIrqMask = 0;
+ uint64_t pmuIrqMask = 0;
- if (PMU->getChipModel() == XPOWERS_AXP192) {
- pmuIrqMask = XPOWERS_AXP192_VBUS_INSERT_IRQ | XPOWERS_AXP192_BAT_INSERT_IRQ | XPOWERS_AXP192_PKEY_SHORT_IRQ;
- } else if (PMU->getChipModel() == XPOWERS_AXP2101) {
- pmuIrqMask = XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_PKEY_SHORT_IRQ;
- }
+ if (PMU->getChipModel() == XPOWERS_AXP192) {
+ pmuIrqMask = XPOWERS_AXP192_VBUS_INSERT_IRQ | XPOWERS_AXP192_BAT_INSERT_IRQ | XPOWERS_AXP192_PKEY_SHORT_IRQ;
+ } else if (PMU->getChipModel() == XPOWERS_AXP2101) {
+ pmuIrqMask = XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_PKEY_SHORT_IRQ;
+ }
- pinMode(PMU_IRQ, INPUT);
- attachInterrupt(
- PMU_IRQ, [] { pmu_irq = true; }, FALLING);
+ pinMode(PMU_IRQ, INPUT);
+ attachInterrupt(
+ PMU_IRQ, [] { pmu_irq = true; }, FALLING);
- // we do not look for AXPXXX_CHARGING_FINISHED_IRQ & AXPXXX_CHARGING_IRQ because it occurs repeatedly while there is
- // no battery also it could cause inadvertent waking from light sleep just because the battery filled
- // we don't look for AXPXXX_BATT_REMOVED_IRQ because it occurs repeatedly while no battery installed
- // we don't look at AXPXXX_VBUS_REMOVED_IRQ because we don't have anything hooked to vbus
- PMU->enableIRQ(pmuIrqMask);
+ // we do not look for AXPXXX_CHARGING_FINISHED_IRQ & AXPXXX_CHARGING_IRQ because it occurs repeatedly while there is
+ // no battery also it could cause inadvertent waking from light sleep just because the battery filled
+ // we don't look for AXPXXX_BATT_REMOVED_IRQ because it occurs repeatedly while no battery installed
+ // we don't look at AXPXXX_VBUS_REMOVED_IRQ because we don't have anything hooked to vbus
+ PMU->enableIRQ(pmuIrqMask);
- PMU->clearIrqStatus();
+ PMU->clearIrqStatus();
#endif /*PMU_IRQ*/
- readPowerStatus();
+ readPowerStatus();
pmu_found = true;
diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp
index d5235c00b..c36c65efc 100644
--- a/src/PowerFSM.cpp
+++ b/src/PowerFSM.cpp
@@ -11,12 +11,12 @@
/// Should we behave as if we have AC power now?
static bool isPowered()
{
- // Circumvent the battery sensing logic and assumes constant power if no battery pin or power mgmt IC
- #if !defined(BATTERY_PIN) && !defined(HAS_AXP192) && !defined(HAS_AXP2101)
- return true;
- #endif
+// Circumvent the battery sensing logic and assumes constant power if no battery pin or power mgmt IC
+#if !defined(BATTERY_PIN) && !defined(HAS_AXP192) && !defined(HAS_AXP2101)
+ return true;
+#endif
- bool isRouter = (config.device.role == Config_DeviceConfig_Role_ROUTER ? 1 : 0);
+ bool isRouter = (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ? 1 : 0);
// If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON
// We assume routers might be powered all the time, but from a low current (solar) source
@@ -199,7 +199,8 @@ static void onEnter()
uint32_t now = millis();
- if ((now - lastPingMs) > 30 * 1000) { // if more than a minute since our last press, ask node we are looking at to update their state
+ if ((now - lastPingMs) >
+ 30 * 1000) { // if more than a minute since our last press, ask node we are looking at to update their state
if (displayedNodeNum)
service.sendNetworkPing(displayedNodeNum, true); // Refresh the currently displayed node
lastPingMs = now;
@@ -237,7 +238,7 @@ Fsm powerFSM(&stateBOOT);
void PowerFSM_setup()
{
- bool isRouter = (config.device.role == Config_DeviceConfig_Role_ROUTER ? 1 : 0);
+ bool isRouter = (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ? 1 : 0);
bool hasPower = isPowered();
LOG_INFO("PowerFSM init, USB power=%d\n", hasPower ? 1 : 0);
@@ -249,7 +250,8 @@ void PowerFSM_setup()
// We need this transition, because we might not transition if we were waiting to enter light-sleep, because when we wake from
// light sleep we _always_ transition to NB or dark and
- powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, exiting light sleep");
+ powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_PACKET_FOR_PHONE, NULL,
+ "Received packet, exiting light sleep");
powerFSM.add_transition(&stateNB, &stateNB, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, resetting win wake");
// Handle press events - note: we ignore button presses when in API mode
@@ -258,7 +260,8 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateDARK, &stateON, EVENT_PRESS, NULL, "Press");
powerFSM.add_transition(&statePOWER, &statePOWER, EVENT_PRESS, screenPress, "Press");
powerFSM.add_transition(&stateON, &stateON, EVENT_PRESS, screenPress, "Press"); // reenter On to restart our timers
- powerFSM.add_transition(&stateSERIAL, &stateSERIAL, EVENT_PRESS, screenPress, "Press"); // Allow button to work while in serial API
+ powerFSM.add_transition(&stateSERIAL, &stateSERIAL, EVENT_PRESS, screenPress,
+ "Press"); // Allow button to work while in serial API
// Handle critically low power battery by forcing deep sleep
powerFSM.add_transition(&stateBOOT, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
@@ -324,7 +327,9 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateDARK, &stateDARK, EVENT_CONTACT_FROM_PHONE, NULL, "Contact from phone");
- powerFSM.add_timed_transition(&stateON, &stateDARK, getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL, "Screen-on timeout");
+ powerFSM.add_timed_transition(&stateON, &stateDARK,
+ getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
+ "Screen-on timeout");
#ifdef ARCH_ESP32
State *lowPowerState = &stateLS;
@@ -332,14 +337,18 @@ void PowerFSM_setup()
// See: https://github.com/meshtastic/firmware/issues/1071
if (isRouter || config.power.is_power_saving) {
- powerFSM.add_timed_transition(&stateNB, &stateLS, getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL, "Min wake timeout");
- powerFSM.add_timed_transition(&stateDARK, &stateLS, getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs), NULL, "Bluetooth timeout");
+ powerFSM.add_timed_transition(&stateNB, &stateLS,
+ getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL,
+ "Min wake timeout");
+ powerFSM.add_timed_transition(&stateDARK, &stateLS,
+ getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs),
+ NULL, "Bluetooth timeout");
}
if (config.power.sds_secs != UINT32_MAX)
- powerFSM.add_timed_transition(lowPowerState, &stateSDS, getConfiguredOrDefaultMs(config.power.sds_secs), NULL, "mesh timeout");
+ powerFSM.add_timed_transition(lowPowerState, &stateSDS, getConfiguredOrDefaultMs(config.power.sds_secs), NULL,
+ "mesh timeout");
#endif
-
powerFSM.run_machine(); // run one interation of the state machine, so we run our on enter tasks for the initial DARK state
}
diff --git a/src/PowerFSM.h b/src/PowerFSM.h
index 63506337d..6692172f4 100644
--- a/src/PowerFSM.h
+++ b/src/PowerFSM.h
@@ -19,8 +19,8 @@
#define EVENT_POWER_CONNECTED 13
#define EVENT_POWER_DISCONNECTED 14
#define EVENT_FIRMWARE_UPDATE 15 // We just received a new firmware update packet from the phone
-#define EVENT_SHUTDOWN 16 //force a full shutdown now (not just sleep)
-#define EVENT_INPUT 17 // input broker wants something, we need to wake up and enable screen
+#define EVENT_SHUTDOWN 16 // force a full shutdown now (not just sleep)
+#define EVENT_INPUT 17 // input broker wants something, we need to wake up and enable screen
extern Fsm powerFSM;
extern State statePOWER, stateSERIAL;
diff --git a/src/PowerFSMThread.h b/src/PowerFSMThread.h
index f45eec2f7..4ebc14a1e 100644
--- a/src/PowerFSMThread.h
+++ b/src/PowerFSMThread.h
@@ -26,9 +26,10 @@ class PowerFSMThread : public OSThread
if (powerStatus->getHasUSB()) {
timeLastPowered = millis();
- } else if (config.power.on_battery_shutdown_after_secs > 0 &&
- config.power.on_battery_shutdown_after_secs != UINT32_MAX &&
- millis() > (timeLastPowered + getConfiguredOrDefaultMs(config.power.on_battery_shutdown_after_secs))) { // shutdown after 30 minutes unpowered
+ } else if (config.power.on_battery_shutdown_after_secs > 0 && config.power.on_battery_shutdown_after_secs != UINT32_MAX &&
+ millis() > (timeLastPowered +
+ getConfiguredOrDefaultMs(
+ config.power.on_battery_shutdown_after_secs))) { // shutdown after 30 minutes unpowered
powerFSM.trigger(EVENT_SHUTDOWN);
}
diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp
index e7f305e19..f316785f0 100644
--- a/src/RedirectablePrint.cpp
+++ b/src/RedirectablePrint.cpp
@@ -1,13 +1,12 @@
-#include "configuration.h"
#include "RedirectablePrint.h"
-#include "RTC.h"
#include "NodeDB.h"
+#include "RTC.h"
#include "concurrency/OSThread.h"
-// #include "wifi/WiFiServerAPI.h"
+#include "configuration.h"
#include
+#include
#include
#include
-#include
/**
* A printer that doesn't go anywhere
@@ -27,10 +26,6 @@ size_t RedirectablePrint::write(uint8_t c)
SEGGER_RTT_PutChar(SEGGER_STDOUT_CH, c);
#endif
- // FIXME - clean this up, the whole relationship of this class to SerialConsole to TCP/bluetooth debug log output is kinda messed up. But for now, just have this hack to
- // optionally send chars to TCP also
- //WiFiServerPort::debugOut(c);
-
if (!config.has_lora || config.device.serial_enabled)
dest->write(c);
@@ -47,7 +42,8 @@ size_t RedirectablePrint::vprintf(const char *format, va_list arg)
size_t len = vsnprintf(printBuf, sizeof(printBuf), format, copy);
va_end(copy);
- // If the resulting string is longer than sizeof(printBuf)-1 characters, the remaining characters are still counted for the return value
+ // If the resulting string is longer than sizeof(printBuf)-1 characters, the remaining characters are still counted for the
+ // return value
if (len > sizeof(printBuf) - 1) {
len = sizeof(printBuf) - 1;
@@ -108,3 +104,35 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...)
return r;
}
+
+void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16_t len)
+{
+ const char alphabet[17] = "0123456789abcdef";
+ log(logLevel, " +------------------------------------------------+ +----------------+\n");
+ log(logLevel, " |.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f | | ASCII |\n");
+ for (uint16_t i = 0; i < len; i += 16) {
+ if (i % 128 == 0)
+ log(logLevel, " +------------------------------------------------+ +----------------+\n");
+ char s[] = "| | | |\n";
+ uint8_t ix = 1, iy = 52;
+ for (uint8_t j = 0; j < 16; j++) {
+ if (i + j < len) {
+ uint8_t c = buf[i + j];
+ s[ix++] = alphabet[(c >> 4) & 0x0F];
+ s[ix++] = alphabet[c & 0x0F];
+ ix++;
+ if (c > 31 && c < 128)
+ s[iy++] = c;
+ else
+ s[iy++] = '.';
+ }
+ }
+ uint8_t index = i / 16;
+ if (i < 256)
+ log(logLevel, " ");
+ log(logLevel, "%02x", index);
+ log(logLevel, ".");
+ log(logLevel, s);
+ }
+ log(logLevel, " +------------------------------------------------+ +----------------+\n");
+}
diff --git a/src/RedirectablePrint.h b/src/RedirectablePrint.h
index 8fabd4a72..659b6e10d 100644
--- a/src/RedirectablePrint.h
+++ b/src/RedirectablePrint.h
@@ -29,15 +29,17 @@ class RedirectablePrint : public Print
/**
* Debug logging print message
- *
+ *
* If the provide format string ends with a newline we assume it is the final print of a single
* log message. Otherwise we assume more prints will come before the log message ends. This
* allows you to call logDebug a few times to build up a single log message line if you wish.
*/
- size_t log(const char *logLevel, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
+ size_t log(const char *logLevel, const char *format, ...) __attribute__((format(printf, 3, 4)));
/** like printf but va_list based */
size_t vprintf(const char *format, va_list arg);
+
+ void hexDump(const char *logLevel, unsigned char *buf, uint16_t len);
};
class NoopPrint : public Print
diff --git a/src/SPILock.cpp b/src/SPILock.cpp
index 06163f67a..13fa556fc 100644
--- a/src/SPILock.cpp
+++ b/src/SPILock.cpp
@@ -1,5 +1,5 @@
-#include "configuration.h"
#include "SPILock.h"
+#include "configuration.h"
#include
#include
diff --git a/src/SerialConsole.cpp b/src/SerialConsole.cpp
index b66eae455..91b4e2826 100644
--- a/src/SerialConsole.cpp
+++ b/src/SerialConsole.cpp
@@ -49,7 +49,8 @@ int32_t SerialConsole::runOnce()
return runOncePart();
}
-void SerialConsole::flush() {
+void SerialConsole::flush()
+{
Port.flush();
}
@@ -74,7 +75,7 @@ bool SerialConsole::handleToRadio(const uint8_t *buf, size_t len)
canWrite = true;
return StreamAPI::handleToRadio(buf, len);
- }else{
+ } else {
return false;
}
}
\ No newline at end of file
diff --git a/src/SerialConsole.h b/src/SerialConsole.h
index f5e2077ba..f8891ba14 100644
--- a/src/SerialConsole.h
+++ b/src/SerialConsole.h
@@ -29,7 +29,6 @@ class SerialConsole : public StreamAPI, public RedirectablePrint, private concur
void flush();
protected:
-
/// Check the current underlying physical link to see if the client is currently connected
virtual bool checkIsConnected() override;
};
diff --git a/src/Status.h b/src/Status.h
index 4f0c71445..65f3a252f 100644
--- a/src/Status.h
+++ b/src/Status.h
@@ -8,65 +8,49 @@
#define STATUS_TYPE_GPS 2
#define STATUS_TYPE_NODE 3
-
namespace meshtastic
{
- // A base class for observable status
- class Status
+// A base class for observable status
+class Status
+{
+ protected:
+ // Allows us to observe an Observable
+ CallbackObserver statusObserver =
+ CallbackObserver(this, &Status::updateStatus);
+ bool initialized = false;
+ // Workaround for no typeid support
+ int statusType = 0;
+
+ public:
+ // Allows us to generate observable events
+ Observable onNewStatus;
+
+ // Enable polymorphism ?
+ virtual ~Status() = default;
+
+ Status()
{
- protected:
- // Allows us to observe an Observable
- CallbackObserver statusObserver = CallbackObserver(this, &Status::updateStatus);
- bool initialized = false;
- // Workaround for no typeid support
- int statusType = 0;
-
- public:
- // Allows us to generate observable events
- Observable onNewStatus;
-
- // Enable polymorphism ?
- virtual ~Status() = default;
-
- Status() {
- if (!statusType)
- {
- statusType = STATUS_TYPE_BASE;
- }
+ if (!statusType) {
+ statusType = STATUS_TYPE_BASE;
}
+ }
- // Prevent object copy/move
- Status(const Status &) = delete;
- Status &operator=(const Status &) = delete;
+ // Prevent object copy/move
+ Status(const Status &) = delete;
+ Status &operator=(const Status &) = delete;
- // Start observing a source of data
- void observe(Observable *source)
- {
- statusObserver.observe(source);
- }
+ // Start observing a source of data
+ void observe(Observable *source) { statusObserver.observe(source); }
- // Determines whether or not existing data matches the data in another Status instance
- bool matches(const Status *otherStatus) const
- {
- return true;
- }
+ // Determines whether or not existing data matches the data in another Status instance
+ bool matches(const Status *otherStatus) const { return true; }
- bool isInitialized() const
- {
- return initialized;
- }
+ bool isInitialized() const { return initialized; }
- int getStatusType() const
- {
- return statusType;
- }
+ int getStatusType() const { return statusType; }
- // Called when the Observable we're observing generates a new notification
- int updateStatus(const Status *newStatus)
- {
- return 0;
- }
-
- };
+ // Called when the Observable we're observing generates a new notification
+ int updateStatus(const Status *newStatus) { return 0; }
};
+}; // namespace meshtastic
diff --git a/src/airtime.cpp b/src/airtime.cpp
index c72a21d54..7be4c5b0d 100644
--- a/src/airtime.cpp
+++ b/src/airtime.cpp
@@ -34,11 +34,13 @@ uint8_t AirTime::currentPeriodIndex()
return ((getSecondsSinceBoot() / SECONDS_PER_PERIOD) % PERIODS_TO_LOG);
}
-uint8_t AirTime::getPeriodUtilMinute() {
+uint8_t AirTime::getPeriodUtilMinute()
+{
return (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS;
}
-uint8_t AirTime::getPeriodUtilHour() {
+uint8_t AirTime::getPeriodUtilHour()
+{
return (getSecondsSinceBoot() / 60) % MINUTES_IN_HOUR;
}
@@ -117,22 +119,45 @@ float AirTime::utilizationTXPercent()
return (float(sum) / float(MS_IN_HOUR)) * 100;
}
+bool AirTime::isTxAllowedChannelUtil(bool polite)
+{
+ uint8_t percentage = (polite ? polite_channel_util_percent : max_channel_util_percent);
+ if (channelUtilizationPercent() < percentage) {
+ return true;
+ } else {
+ LOG_WARN("Channel utilization is >%d percent. Skipping this opportunity to send.\n", percentage);
+ return false;
+ }
+}
+
+bool AirTime::isTxAllowedAirUtil()
+{
+ if (!config.lora.override_duty_cycle && myRegion->dutyCycle < 100) {
+ if (utilizationTXPercent() < myRegion->dutyCycle * polite_duty_cycle_percent / 100) {
+ return true;
+ } else {
+ LOG_WARN("Tx air utilization is >%f percent. Skipping this opportunity to send.\n",
+ myRegion->dutyCycle * polite_duty_cycle_percent / 100);
+ return false;
+ }
+ }
+ return true;
+}
+
// Get the amount of minutes we have to be silent before we can send again
-uint8_t AirTime::getSilentMinutes(float txPercent, float dutyCycle)
-{
- float newTxPercent = txPercent;
- for (int8_t i = MINUTES_IN_HOUR-1; i >= 0; --i) {
- newTxPercent -= ((float)this->utilizationTX[i] / (MS_IN_MINUTE * MINUTES_IN_HOUR / 100));
- if (newTxPercent < dutyCycle)
- return MINUTES_IN_HOUR-1-i;
- }
+uint8_t AirTime::getSilentMinutes(float txPercent, float dutyCycle)
+{
+ float newTxPercent = txPercent;
+ for (int8_t i = MINUTES_IN_HOUR - 1; i >= 0; --i) {
+ newTxPercent -= ((float)this->utilizationTX[i] / (MS_IN_MINUTE * MINUTES_IN_HOUR / 100));
+ if (newTxPercent < dutyCycle)
+ return MINUTES_IN_HOUR - 1 - i;
+ }
- return MINUTES_IN_HOUR;
+ return MINUTES_IN_HOUR;
}
-
-AirTime::AirTime() : concurrency::OSThread("AirTime"),airtimes({}) {
-}
+AirTime::AirTime() : concurrency::OSThread("AirTime"), airtimes({}) {}
int32_t AirTime::runOnce()
{
@@ -188,14 +213,14 @@ int32_t AirTime::runOnce()
// Update channel_utilization every second.
myNodeInfo.air_util_tx = airTime->utilizationTXPercent();
}
-/*
- LOG_DEBUG("utilPeriodTX %d TX Airtime %3.2f%\n", utilPeriodTX, airTime->utilizationTXPercent());
- for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
- LOG_DEBUG(
- "%d,", this->utilizationTX[i]
- );
- }
- LOG_DEBUG("\n");
-*/
+ /*
+ LOG_DEBUG("utilPeriodTX %d TX Airtime %3.2f%\n", utilPeriodTX, airTime->utilizationTXPercent());
+ for (uint32_t i = 0; i < MINUTES_IN_HOUR; i++) {
+ LOG_DEBUG(
+ "%d,", this->utilizationTX[i]
+ );
+ }
+ LOG_DEBUG("\n");
+ */
return (1000 * 1);
}
diff --git a/src/airtime.h b/src/airtime.h
index 3f38f39f8..cb5f8bf6d 100644
--- a/src/airtime.h
+++ b/src/airtime.h
@@ -1,5 +1,6 @@
#pragma once
+#include "MeshRadio.h"
#include "concurrency/OSThread.h"
#include "configuration.h"
#include
@@ -32,7 +33,6 @@
#define MS_IN_MINUTE (SECONDS_IN_MINUTE * 1000)
#define MS_IN_HOUR (MINUTES_IN_HOUR * SECONDS_IN_MINUTE * 1000)
-
enum reportTypes { TX_LOG, RX_LOG, RX_ALL_LOG };
void logAirtime(reportTypes reportType, uint32_t airtime_ms);
@@ -59,12 +59,17 @@ class AirTime : private concurrency::OSThread
uint32_t getSecondsSinceBoot();
uint32_t *airtimeReport(reportTypes reportType);
uint8_t getSilentMinutes(float txPercent, float dutyCycle);
+ bool isTxAllowedChannelUtil(bool polite = false);
+ bool isTxAllowedAirUtil();
private:
bool firstTime = true;
uint8_t lastUtilPeriod = 0;
uint8_t lastUtilPeriodTX = 0;
uint32_t secSinceBoot = 0;
+ uint8_t max_channel_util_percent = 40;
+ uint8_t polite_channel_util_percent = 25;
+ uint8_t polite_duty_cycle_percent = 50; // half of Duty Cycle allowance is ok for metadata
struct airtimeStruct {
uint32_t periodTX[PERIODS_TO_LOG]; // AirTime transmitted
diff --git a/src/buzz/buzz.cpp b/src/buzz/buzz.cpp
index 262cd20b9..e42a9c203 100644
--- a/src/buzz/buzz.cpp
+++ b/src/buzz/buzz.cpp
@@ -1,6 +1,6 @@
#include "buzz.h"
-#include "configuration.h"
#include "NodeDB.h"
+#include "configuration.h"
#if !defined(ARCH_ESP32) && !defined(ARCH_RP2040) && !defined(ARCH_PORTDUINO)
#include "Tone.h"
@@ -11,8 +11,8 @@ extern "C" void delay(uint32_t dwMs);
#endif
struct ToneDuration {
- int frequency_khz;
- int duration_ms;
+ int frequency_khz;
+ int duration_ms;
};
// Some common frequencies.
@@ -30,40 +30,39 @@ struct ToneDuration {
#define NOTE_B3 247
#define NOTE_CS4 277
-const int DURATION_1_8 = 125; // 1/8 note
-const int DURATION_1_4 = 250; // 1/4 note
+const int DURATION_1_8 = 125; // 1/8 note
+const int DURATION_1_4 = 250; // 1/4 note
-void playTones(const ToneDuration *tone_durations, int size) {
+void playTones(const ToneDuration *tone_durations, int size)
+{
#ifdef PIN_BUZZER
- if (!config.device.buzzer_gpio)
- config.device.buzzer_gpio = PIN_BUZZER;
+ if (!config.device.buzzer_gpio)
+ config.device.buzzer_gpio = PIN_BUZZER;
#endif
- if (config.device.buzzer_gpio) {
- for (int i = 0; i < size; i++) {
- const auto &tone_duration = tone_durations[i];
- tone(config.device.buzzer_gpio, tone_duration.frequency_khz, tone_duration.duration_ms);
- // to distinguish the notes, set a minimum time between them.
- delay(1.3 * tone_duration.duration_ms);
+ if (config.device.buzzer_gpio) {
+ for (int i = 0; i < size; i++) {
+ const auto &tone_duration = tone_durations[i];
+ tone(config.device.buzzer_gpio, tone_duration.frequency_khz, tone_duration.duration_ms);
+ // to distinguish the notes, set a minimum time between them.
+ delay(1.3 * tone_duration.duration_ms);
+ }
}
- }
}
-
-void playBeep() {
- ToneDuration melody[] = {{NOTE_B3, DURATION_1_4}};
- playTones(melody, sizeof(melody) / sizeof(ToneDuration));
+void playBeep()
+{
+ ToneDuration melody[] = {{NOTE_B3, DURATION_1_4}};
+ playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}
-void playStartMelody() {
- ToneDuration melody[] = {{NOTE_FS3, DURATION_1_8},
- {NOTE_AS3, DURATION_1_8},
- {NOTE_CS4, DURATION_1_4}};
- playTones(melody, sizeof(melody) / sizeof(ToneDuration));
+void playStartMelody()
+{
+ ToneDuration melody[] = {{NOTE_FS3, DURATION_1_8}, {NOTE_AS3, DURATION_1_8}, {NOTE_CS4, DURATION_1_4}};
+ playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}
-void playShutdownMelody() {
- ToneDuration melody[] = {{NOTE_CS4, DURATION_1_8},
- {NOTE_AS3, DURATION_1_8},
- {NOTE_FS3, DURATION_1_4}};
- playTones(melody, sizeof(melody) / sizeof(ToneDuration));
+void playShutdownMelody()
+{
+ ToneDuration melody[] = {{NOTE_CS4, DURATION_1_8}, {NOTE_AS3, DURATION_1_8}, {NOTE_FS3, DURATION_1_4}};
+ playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}
diff --git a/src/commands.h b/src/commands.h
index b52ed5db4..7c7595143 100644
--- a/src/commands.h
+++ b/src/commands.h
@@ -4,15 +4,15 @@
*/
enum class Cmd {
- INVALID,
- SET_ON,
- SET_OFF,
- ON_PRESS,
- START_BLUETOOTH_PIN_SCREEN,
- START_FIRMWARE_UPDATE_SCREEN,
- STOP_BLUETOOTH_PIN_SCREEN,
- STOP_BOOT_SCREEN,
- PRINT,
- START_SHUTDOWN_SCREEN,
- START_REBOOT_SCREEN,
+ INVALID,
+ SET_ON,
+ SET_OFF,
+ ON_PRESS,
+ START_BLUETOOTH_PIN_SCREEN,
+ START_FIRMWARE_UPDATE_SCREEN,
+ STOP_BLUETOOTH_PIN_SCREEN,
+ STOP_BOOT_SCREEN,
+ PRINT,
+ START_SHUTDOWN_SCREEN,
+ START_REBOOT_SCREEN,
};
\ No newline at end of file
diff --git a/src/concurrency/BinarySemaphoreFreeRTOS.cpp b/src/concurrency/BinarySemaphoreFreeRTOS.cpp
index 4d6d40d78..36e55eae7 100644
--- a/src/concurrency/BinarySemaphoreFreeRTOS.cpp
+++ b/src/concurrency/BinarySemaphoreFreeRTOS.cpp
@@ -1,5 +1,5 @@
-#include "configuration.h"
#include "concurrency/BinarySemaphoreFreeRTOS.h"
+#include "configuration.h"
#include
#ifdef HAS_FREE_RTOS
diff --git a/src/concurrency/BinarySemaphorePosix.cpp b/src/concurrency/BinarySemaphorePosix.cpp
index 0de52b322..dc49a489b 100644
--- a/src/concurrency/BinarySemaphorePosix.cpp
+++ b/src/concurrency/BinarySemaphorePosix.cpp
@@ -1,18 +1,14 @@
-#include "configuration.h"
#include "concurrency/BinarySemaphorePosix.h"
+#include "configuration.h"
#ifndef HAS_FREE_RTOS
namespace concurrency
{
-BinarySemaphorePosix::BinarySemaphorePosix()
-{
-}
+BinarySemaphorePosix::BinarySemaphorePosix() {}
-BinarySemaphorePosix::~BinarySemaphorePosix()
-{
-}
+BinarySemaphorePosix::~BinarySemaphorePosix() {}
/**
* Returns false if we timed out
@@ -23,13 +19,9 @@ bool BinarySemaphorePosix::take(uint32_t msec)
return false;
}
-void BinarySemaphorePosix::give()
-{
-}
+void BinarySemaphorePosix::give() {}
-IRAM_ATTR void BinarySemaphorePosix::giveFromISR(BaseType_t *pxHigherPriorityTaskWoken)
-{
-}
+IRAM_ATTR void BinarySemaphorePosix::giveFromISR(BaseType_t *pxHigherPriorityTaskWoken) {}
} // namespace concurrency
diff --git a/src/concurrency/InterruptableDelay.cpp b/src/concurrency/InterruptableDelay.cpp
index 7bddea68d..b9606e23a 100644
--- a/src/concurrency/InterruptableDelay.cpp
+++ b/src/concurrency/InterruptableDelay.cpp
@@ -1,5 +1,5 @@
-#include "configuration.h"
#include "concurrency/InterruptableDelay.h"
+#include "configuration.h"
namespace concurrency
{
diff --git a/src/concurrency/InterruptableDelay.h b/src/concurrency/InterruptableDelay.h
index b0d4b009f..2b499073a 100644
--- a/src/concurrency/InterruptableDelay.h
+++ b/src/concurrency/InterruptableDelay.h
@@ -2,7 +2,6 @@
#include "../freertosinc.h"
-
#ifdef HAS_FREE_RTOS
#include "concurrency/BinarySemaphoreFreeRTOS.h"
#define BinarySemaphore BinarySemaphoreFreeRTOS
diff --git a/src/concurrency/Lock.cpp b/src/concurrency/Lock.cpp
index 50ce6a00f..11501359b 100644
--- a/src/concurrency/Lock.cpp
+++ b/src/concurrency/Lock.cpp
@@ -1,5 +1,5 @@
-#include "configuration.h"
#include "Lock.h"
+#include "configuration.h"
#include
namespace concurrency
diff --git a/src/concurrency/LockGuard.cpp b/src/concurrency/LockGuard.cpp
index 1c4d9e2e6..d855266cb 100644
--- a/src/concurrency/LockGuard.cpp
+++ b/src/concurrency/LockGuard.cpp
@@ -1,7 +1,8 @@
-#include "configuration.h"
#include "LockGuard.h"
+#include "configuration.h"
-namespace concurrency {
+namespace concurrency
+{
LockGuard::LockGuard(Lock *lock) : lock(lock)
{
diff --git a/src/concurrency/LockGuard.h b/src/concurrency/LockGuard.h
index 89c288f6a..647e7960d 100644
--- a/src/concurrency/LockGuard.h
+++ b/src/concurrency/LockGuard.h
@@ -2,7 +2,8 @@
#include "Lock.h"
-namespace concurrency {
+namespace concurrency
+{
/**
* @brief RAII lock guard
diff --git a/src/concurrency/NotifiedWorkerThread.cpp b/src/concurrency/NotifiedWorkerThread.cpp
index ac6428f07..39a594c5a 100644
--- a/src/concurrency/NotifiedWorkerThread.cpp
+++ b/src/concurrency/NotifiedWorkerThread.cpp
@@ -1,7 +1,6 @@
-#include "configuration.h"
#include "NotifiedWorkerThread.h"
+#include "configuration.h"
#include "main.h"
-#include
namespace concurrency
{
@@ -81,11 +80,9 @@ void NotifiedWorkerThread::checkNotification()
}
}
-
-
int32_t NotifiedWorkerThread::runOnce()
{
- enabled = false; // Only run once per notification
+ enabled = false; // Only run once per notification
checkNotification();
return RUN_SAME;
diff --git a/src/concurrency/NotifiedWorkerThread.h b/src/concurrency/NotifiedWorkerThread.h
index 83e73a571..7a150b0b0 100644
--- a/src/concurrency/NotifiedWorkerThread.h
+++ b/src/concurrency/NotifiedWorkerThread.h
@@ -41,9 +41,9 @@ class NotifiedWorkerThread : public OSThread
/// just calls checkNotification()
virtual int32_t runOnce() override;
- /// Sometimes we might want to check notifications independently of when our thread was getting woken up (i.e. if we are about to change
- /// radio transmit/receive modes we want to handle any pending interrupts first). You can call this method and if any notifications are currently
- /// pending they will be handled immediately.
+ /// Sometimes we might want to check notifications independently of when our thread was getting woken up (i.e. if we are about
+ /// to change radio transmit/receive modes we want to handle any pending interrupts first). You can call this method and if
+ /// any notifications are currently pending they will be handled immediately.
void checkNotification();
private:
diff --git a/src/concurrency/OSThread.cpp b/src/concurrency/OSThread.cpp
index 2e5ee0ba8..af50d28f5 100644
--- a/src/concurrency/OSThread.cpp
+++ b/src/concurrency/OSThread.cpp
@@ -1,5 +1,5 @@
-#include "configuration.h"
#include "OSThread.h"
+#include "configuration.h"
#include
namespace concurrency
@@ -76,7 +76,7 @@ void OSThread::run()
{
#ifdef DEBUG_HEAP
auto heap = ESP.getFreeHeap();
-#endif
+#endif
currentThread = this;
auto newDelay = runOnce();
#ifdef DEBUG_HEAP
@@ -95,11 +95,11 @@ void OSThread::run()
currentThread = NULL;
}
-int32_t OSThread::disable()
+int32_t OSThread::disable()
{
enabled = false;
setInterval(INT32_MAX);
-
+
return INT32_MAX;
}
diff --git a/src/configuration.h b/src/configuration.h
index 67862609a..6181034a5 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -27,10 +27,10 @@ along with this program. If not, see .
#include
#ifdef RV3028_RTC
- #include "Melopero_RV3028.h"
+#include "Melopero_RV3028.h"
#endif
#ifdef PCF8563_RTC
- #include "pcf8563.h"
+#include "pcf8563.h"
#endif
// -----------------------------------------------------------------------------
@@ -42,7 +42,8 @@ along with this program. If not, see .
#error APP_VERSION must be set by the build environment
#endif
-// FIXME: This is still needed by the Bluetooth Stack and needs to be replaced by something better. Remnant of the old versioning system.
+// FIXME: This is still needed by the Bluetooth Stack and needs to be replaced by something better. Remnant of the old versioning
+// system.
#ifndef HW_VERSION
#define HW_VERSION "1.0"
#endif
@@ -64,13 +65,13 @@ along with this program. If not, see .
// Nop definition for these attributes that are specific to ESP32
#ifndef EXT_RAM_ATTR
- #define EXT_RAM_ATTR
+#define EXT_RAM_ATTR
#endif
#ifndef IRAM_ATTR
- #define IRAM_ATTR
+#define IRAM_ATTR
#endif
#ifndef RTC_DATA_ATTR
- #define RTC_DATA_ATTR
+#define RTC_DATA_ATTR
#endif
// -----------------------------------------------------------------------------
@@ -80,7 +81,7 @@ along with this program. If not, see .
// Disable use of the NTP library and related features
// #define DISABLE_NTP
-// Disable the welcome screen and allow
+// Disable the welcome screen and allow
//#define DISABLE_WELCOME_UNSET
// -----------------------------------------------------------------------------
@@ -135,49 +136,49 @@ along with this program. If not, see .
/* Step #1: offer chance for variant-specific defines */
#include "variant.h"
-/* Step #2: follow with defines common to the architecture;
+/* Step #2: follow with defines common to the architecture;
also enable HAS_ option not specifically disabled by variant.h */
#include "architecture.h"
/* Step #3: mop up with disabled values for HAS_ options not handled by the above two */
#ifndef HAS_WIFI
- #define HAS_WIFI 0
+#define HAS_WIFI 0
#endif
#ifndef HAS_ETHERNET
- #define HAS_ETHERNET 0
+#define HAS_ETHERNET 0
#endif
#ifndef HAS_SCREEN
- #define HAS_SCREEN 0
+#define HAS_SCREEN 0
#endif
#ifndef HAS_WIRE
- #define HAS_WIRE 0
+#define HAS_WIRE 0
#endif
#ifndef HAS_GPS
- #define HAS_GPS 0
+#define HAS_GPS 0
#endif
#ifndef HAS_BUTTON
- #define HAS_BUTTON 0
+#define HAS_BUTTON 0
#endif
#ifndef HAS_TELEMETRY
- #define HAS_TELEMETRY 0
+#define HAS_TELEMETRY 0
#endif
#ifndef HAS_RADIO
- #define HAS_RADIO 0
+#define HAS_RADIO 0
#endif
#ifndef HAS_RTC
- #define HAS_RTC 0
+#define HAS_RTC 0
#endif
#ifndef HAS_CPU_SHUTDOWN
- #define HAS_CPU_SHUTDOWN 0
+#define HAS_CPU_SHUTDOWN 0
#endif
#ifndef HAS_BLUETOOTH
- #define HAS_BLUETOOTH 0
+#define HAS_BLUETOOTH 0
#endif
-#include "RF95Configuration.h"
#include "DebugConfiguration.h"
+#include "RF95Configuration.h"
#ifndef HW_VENDOR
- #error HW_VENDOR must be defined
+#error HW_VENDOR must be defined
#endif
diff --git a/src/detect/einkScan.h b/src/detect/einkScan.h
index a7a855709..8d82f4f81 100644
--- a/src/detect/einkScan.h
+++ b/src/detect/einkScan.h
@@ -6,42 +6,49 @@
void d_writeCommand(uint8_t c)
{
- SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
- if (PIN_EINK_DC >= 0) digitalWrite(PIN_EINK_DC, LOW);
- if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, LOW);
- SPI1.transfer(c);
- if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, HIGH);
- if (PIN_EINK_DC >= 0) digitalWrite(PIN_EINK_DC, HIGH);
- SPI1.endTransaction();
+ SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
+ if (PIN_EINK_DC >= 0)
+ digitalWrite(PIN_EINK_DC, LOW);
+ if (PIN_EINK_CS >= 0)
+ digitalWrite(PIN_EINK_CS, LOW);
+ SPI1.transfer(c);
+ if (PIN_EINK_CS >= 0)
+ digitalWrite(PIN_EINK_CS, HIGH);
+ if (PIN_EINK_DC >= 0)
+ digitalWrite(PIN_EINK_DC, HIGH);
+ SPI1.endTransaction();
}
void d_writeData(uint8_t d)
{
- SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
- if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, LOW);
- SPI1.transfer(d);
- if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, HIGH);
- SPI1.endTransaction();
+ SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
+ if (PIN_EINK_CS >= 0)
+ digitalWrite(PIN_EINK_CS, LOW);
+ SPI1.transfer(d);
+ if (PIN_EINK_CS >= 0)
+ digitalWrite(PIN_EINK_CS, HIGH);
+ SPI1.endTransaction();
}
unsigned long d_waitWhileBusy(uint16_t busy_time)
{
- if (PIN_EINK_BUSY >= 0)
- {
- delay(1); // add some margin to become active
- unsigned long start = micros();
- while (1)
- {
- if (digitalRead(PIN_EINK_BUSY) != HIGH) break;
- delay(1);
- if (digitalRead(PIN_EINK_BUSY) != HIGH) break;
- if (micros() - start > 10000000) break;
- }
- unsigned long elapsed = micros() - start;
- (void) start;
- return elapsed;
- }
- else return busy_time;
+ if (PIN_EINK_BUSY >= 0) {
+ delay(1); // add some margin to become active
+ unsigned long start = micros();
+ while (1) {
+ if (digitalRead(PIN_EINK_BUSY) != HIGH)
+ break;
+ delay(1);
+ if (digitalRead(PIN_EINK_BUSY) != HIGH)
+ break;
+ if (micros() - start > 10000000)
+ break;
+ }
+ unsigned long elapsed = micros() - start;
+ (void)start;
+ return elapsed;
+ } else
+ return busy_time;
}
void scanEInkDevice(void)
@@ -51,10 +58,10 @@ void scanEInkDevice(void)
d_writeData(0x83);
d_writeCommand(0x20);
eink_found = (d_waitWhileBusy(150) > 0) ? true : false;
- if(eink_found)
- LOG_DEBUG("EInk display found\n");
+ if (eink_found)
+ LOG_DEBUG("EInk display found\n");
else
- LOG_DEBUG("EInk display not found\n");
+ LOG_DEBUG("EInk display not found\n");
SPI1.end();
}
#endif
diff --git a/src/detect/i2cScan.h b/src/detect/i2cScan.h
index 77d1fff17..87ca55957 100644
--- a/src/detect/i2cScan.h
+++ b/src/detect/i2cScan.h
@@ -1,11 +1,11 @@
#include "../configuration.h"
#include "../main.h"
+#include "mesh/generated/meshtastic/telemetry.pb.h"
#include
-#include "mesh/generated/telemetry.pb.h"
// AXP192 and AXP2101 have the same device address, we just need to identify it in Power.cpp
#ifndef XPOWERS_AXP192_AXP2101_ADDRESS
-#define XPOWERS_AXP192_AXP2101_ADDRESS 0x34
+#define XPOWERS_AXP192_AXP2101_ADDRESS 0x34
#endif
#if HAS_WIRE
@@ -16,27 +16,27 @@ void printATECCInfo()
atecc.readConfigZone(false);
LOG_DEBUG("ATECC608B Serial Number: ");
- for (int i = 0 ; i < 9 ; i++) {
- LOG_DEBUG("%02x",atecc.serialNumber[i]);
+ for (int i = 0; i < 9; i++) {
+ LOG_DEBUG("%02x", atecc.serialNumber[i]);
}
LOG_DEBUG(", Rev Number: ");
- for (int i = 0 ; i < 4 ; i++) {
- LOG_DEBUG("%02x",atecc.revisionNumber[i]);
+ for (int i = 0; i < 4; i++) {
+ LOG_DEBUG("%02x", atecc.revisionNumber[i]);
}
LOG_DEBUG("\n");
- LOG_DEBUG("ATECC608B Config %s",atecc.configLockStatus ? "Locked" : "Unlocked");
- LOG_DEBUG(", Data %s",atecc.dataOTPLockStatus ? "Locked" : "Unlocked");
- LOG_DEBUG(", Slot 0 %s\n",atecc.slot0LockStatus ? "Locked" : "Unlocked");
+ LOG_DEBUG("ATECC608B Config %s", atecc.configLockStatus ? "Locked" : "Unlocked");
+ LOG_DEBUG(", Data %s", atecc.dataOTPLockStatus ? "Locked" : "Unlocked");
+ LOG_DEBUG(", Slot 0 %s\n", atecc.slot0LockStatus ? "Locked" : "Unlocked");
if (atecc.configLockStatus && atecc.dataOTPLockStatus && atecc.slot0LockStatus) {
if (atecc.generatePublicKey() == false) {
LOG_DEBUG("ATECC608B Error generating public key\n");
} else {
LOG_DEBUG("ATECC608B Public Key: ");
- for (int i = 0 ; i < 64 ; i++) {
- LOG_DEBUG("%02x",atecc.publicKey64Bytes[i]);
+ for (int i = 0; i < 64; i++) {
+ LOG_DEBUG("%02x", atecc.publicKey64Bytes[i]);
}
LOG_DEBUG("\n");
}
@@ -44,7 +44,8 @@ void printATECCInfo()
#endif
}
-uint16_t getRegisterValue(uint8_t address, uint8_t reg, uint8_t length) {
+uint16_t getRegisterValue(uint8_t address, uint8_t reg, uint8_t length)
+{
uint16_t value = 0x00;
Wire.beginTransmission(address);
Wire.write(reg);
@@ -54,7 +55,7 @@ uint16_t getRegisterValue(uint8_t address, uint8_t reg, uint8_t length) {
LOG_DEBUG("Wire.available() = %d\n", Wire.available());
if (Wire.available() == 2) {
// Read MSB, then LSB
- value = (uint16_t)Wire.read() << 8;
+ value = (uint16_t)Wire.read() << 8;
value |= Wire.read();
} else if (Wire.available()) {
value = Wire.read();
@@ -81,7 +82,7 @@ uint8_t oled_probe(byte addr)
if (r == 0x08 || r == 0x00) {
o_probe = 2; // SH1106
- } else if ( r == 0x03 || r == 0x04 || r == 0x06 || r == 0x07) {
+ } else if (r == 0x03 || r == 0x04 || r == 0x06 || r == 0x07) {
o_probe = 1; // SSD1306
}
c++;
@@ -126,17 +127,17 @@ void scanI2Cdevice()
}
#endif
#ifdef RV3028_RTC
- if (addr == RV3028_RTC){
+ if (addr == RV3028_RTC) {
rtc_found = addr;
LOG_INFO("RV3028 RTC found\n");
Melopero_RV3028 rtc;
rtc.initI2C();
- rtc.writeToRegister(0x35,0x07); // no Clkout
- rtc.writeToRegister(0x37,0xB4);
+ rtc.writeToRegister(0x35, 0x07); // no Clkout
+ rtc.writeToRegister(0x37, 0xB4);
}
#endif
#ifdef PCF8563_RTC
- if (addr == PCF8563_RTC){
+ if (addr == PCF8563_RTC) {
rtc_found = addr;
LOG_INFO("PCF8563 RTC found\n");
}
@@ -167,13 +168,13 @@ void scanI2Cdevice()
registerValue = getRegisterValue(addr, 0xD0, 1); // GET_ID
if (registerValue == 0x61) {
LOG_INFO("BME-680 sensor found at address 0x%x\n", (uint8_t)addr);
- nodeTelemetrySensorsMap[TelemetrySensorType_BME680] = addr;
+ nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_BME680] = addr;
} else if (registerValue == 0x60) {
LOG_INFO("BME-280 sensor found at address 0x%x\n", (uint8_t)addr);
- nodeTelemetrySensorsMap[TelemetrySensorType_BME280] = addr;
+ nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_BME280] = addr;
} else {
LOG_INFO("BMP-280 sensor found at address 0x%x\n", (uint8_t)addr);
- nodeTelemetrySensorsMap[TelemetrySensorType_BMP280] = addr;
+ nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_BMP280] = addr;
}
}
if (addr == INA_ADDR || addr == INA_ADDR_ALTERNATE) {
@@ -181,41 +182,41 @@ void scanI2Cdevice()
LOG_DEBUG("Register MFG_UID: 0x%x\n", registerValue);
if (registerValue == 0x5449) {
LOG_INFO("INA260 sensor found at address 0x%x\n", (uint8_t)addr);
- nodeTelemetrySensorsMap[TelemetrySensorType_INA260] = addr;
+ nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260] = addr;
} else { // Assume INA219 if INA260 ID is not found
LOG_INFO("INA219 sensor found at address 0x%x\n", (uint8_t)addr);
- nodeTelemetrySensorsMap[TelemetrySensorType_INA219] = addr;
+ nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219] = addr;
}
}
if (addr == MCP9808_ADDR) {
- nodeTelemetrySensorsMap[TelemetrySensorType_MCP9808] = addr;
+ nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MCP9808] = addr;
LOG_INFO("MCP9808 sensor found\n");
}
if (addr == SHT31_ADDR) {
LOG_INFO("SHT31 sensor found\n");
- nodeTelemetrySensorsMap[TelemetrySensorType_SHT31] = addr;
+ nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_SHT31] = addr;
}
if (addr == SHTC3_ADDR) {
LOG_INFO("SHTC3 sensor found\n");
- nodeTelemetrySensorsMap[TelemetrySensorType_SHTC3] = addr;
+ nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_SHTC3] = addr;
}
if (addr == LPS22HB_ADDR || addr == LPS22HB_ADDR_ALT) {
LOG_INFO("LPS22HB sensor found\n");
- nodeTelemetrySensorsMap[TelemetrySensorType_LPS22] = addr;
+ nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_LPS22] = addr;
}
// High rate sensors, will be processed internally
if (addr == QMC6310_ADDR) {
LOG_INFO("QMC6310 Highrate 3-Axis magnetic sensor found\n");
- nodeTelemetrySensorsMap[TelemetrySensorType_QMC6310] = addr;
+ nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_QMC6310] = addr;
}
if (addr == QMI8658_ADDR) {
LOG_INFO("QMI8658 Highrate 6-Axis inertial measurement sensor found\n");
- nodeTelemetrySensorsMap[TelemetrySensorType_QMI8658] = addr;
+ nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_QMI8658] = addr;
}
if (addr == QMC5883L_ADDR) {
LOG_INFO("QMC5883L Highrate 3-Axis magnetic sensor found\n");
- nodeTelemetrySensorsMap[TelemetrySensorType_QMC5883L] = addr;
+ nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_QMC5883L] = addr;
}
} else if (err == 4) {
LOG_ERROR("Unknow error at address 0x%x\n", addr);
@@ -225,7 +226,7 @@ void scanI2Cdevice()
if (nDevices == 0)
LOG_INFO("No I2C devices found\n");
else
- LOG_INFO("%i I2C devices found\n",nDevices);
+ LOG_INFO("%i I2C devices found\n", nDevices);
}
#else
void scanI2Cdevice() {}
diff --git a/src/error.h b/src/error.h
index e57407bf8..fc0707cd6 100644
--- a/src/error.h
+++ b/src/error.h
@@ -2,10 +2,11 @@
#include
-#include "mesh/generated/mesh.pb.h" // For CriticalErrorCode
+#include "mesh/generated/meshtastic/mesh.pb.h" // For CriticalErrorCode
/// A macro that include filename and line
#define RECORD_CRITICALERROR(code) recordCriticalError(code, __LINE__, __FILE__)
/// Record an error that should be reported via analytics
-void recordCriticalError(CriticalErrorCode code = CriticalErrorCode_UNSPECIFIED, uint32_t address = 0, const char *filename = NULL);
+void recordCriticalError(meshtastic_CriticalErrorCode code = meshtastic_CriticalErrorCode_UNSPECIFIED, uint32_t address = 0,
+ const char *filename = NULL);
diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp
index 7eec13228..1b7c8511f 100644
--- a/src/gps/GPS.cpp
+++ b/src/gps/GPS.cpp
@@ -3,7 +3,6 @@
#include "RTC.h"
#include "configuration.h"
#include "sleep.h"
-#include
// If we have a serial GPS port it will not be null
#ifdef GPS_SERIAL_NUM
@@ -22,45 +21,45 @@ GPS *gps;
/// only init that port once.
static bool didSerialInit;
-bool GPS::getACK(uint8_t c, uint8_t i) {
- uint8_t b;
- uint8_t ack = 0;
- const uint8_t ackP[2] = {c, i};
- uint8_t buf[10] = {0xB5, 0x62, 0x05, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};
- unsigned long startTime = millis();
+bool GPS::getACK(uint8_t c, uint8_t i)
+{
+ uint8_t b;
+ uint8_t ack = 0;
+ const uint8_t ackP[2] = {c, i};
+ uint8_t buf[10] = {0xB5, 0x62, 0x05, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};
+ unsigned long startTime = millis();
- for (int j = 2; j < 6; j++) {
- buf[8] += buf[j];
- buf[9] += buf[8];
- }
+ for (int j = 2; j < 6; j++) {
+ buf[8] += buf[j];
+ buf[9] += buf[8];
+ }
- for (int j = 0; j < 2; j++) {
- buf[6 + j] = ackP[j];
- buf[8] += buf[6 + j];
- buf[9] += buf[8];
- }
+ for (int j = 0; j < 2; j++) {
+ buf[6 + j] = ackP[j];
+ buf[8] += buf[6 + j];
+ buf[9] += buf[8];
+ }
- while (1) {
- if (ack > 9) {
- return true;
+ while (1) {
+ if (ack > 9) {
+ return true;
+ }
+ if (millis() - startTime > 1000) {
+ return false;
+ }
+ if (_serial_gps->available()) {
+ b = _serial_gps->read();
+ if (b == buf[ack]) {
+ ack++;
+ } else {
+ ack = 0;
+ }
+ }
}
- if (millis() - startTime > 1000) {
- return false;
- }
- if (_serial_gps->available()) {
- b = _serial_gps->read();
- if (b == buf[ack]) {
- ack++;
- }
- else {
- ack = 0;
- }
- }
- }
}
/**
- * @brief
+ * @brief
* @note New method, this method can wait for the specified class and message ID, and return the payload
* @param *buffer: The message buffer, if there is a response payload message, it will be returned through the buffer parameter
* @param size: size of buffer
@@ -70,22 +69,22 @@ bool GPS::getACK(uint8_t c, uint8_t i) {
*/
int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID)
{
- uint16_t ubxFrameCounter = 0;
- uint32_t startTime = millis();
- uint16_t needRead;
+ uint16_t ubxFrameCounter = 0;
+ uint32_t startTime = millis();
+ uint16_t needRead;
while (millis() - startTime < 800) {
while (_serial_gps->available()) {
int c = _serial_gps->read();
switch (ubxFrameCounter) {
case 0:
- //ubxFrame 'μ'
- if (c == 0xB5) {
+ // ubxFrame 'μ'
+ if (c == 0xB5) {
ubxFrameCounter++;
}
break;
case 1:
- //ubxFrame 'b'
+ // ubxFrame 'b'
if (c == 0x62) {
ubxFrameCounter++;
} else {
@@ -93,7 +92,7 @@ int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
}
break;
case 2:
- //Class
+ // Class
if (c == requestedClass) {
ubxFrameCounter++;
} else {
@@ -101,7 +100,7 @@ int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
}
break;
case 3:
- //Message ID
+ // Message ID
if (c == requestedID) {
ubxFrameCounter++;
} else {
@@ -109,13 +108,13 @@ int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
}
break;
case 4:
- //Payload lenght lsb
+ // Payload lenght lsb
needRead = c;
ubxFrameCounter++;
break;
case 5:
- //Payload lenght msb
- needRead |= (c << 8);
+ // Payload lenght msb
+ needRead |= (c << 8);
ubxFrameCounter++;
break;
case 6:
@@ -146,41 +145,41 @@ bool GPS::setupGPS()
didSerialInit = true;
#ifdef ARCH_ESP32
- // In esp32 framework, setRxBufferSize needs to be initialized before Serial
- _serial_gps->setRxBufferSize(2048); // the default is 256
+ // In esp32 framework, setRxBufferSize needs to be initialized before Serial
+ _serial_gps->setRxBufferSize(2048); // the default is 256
#endif
-// if the overrides are not dialled in, set them from the board definitions, if they exist
+ // if the overrides are not dialled in, set them from the board definitions, if they exist
#if defined(GPS_RX_PIN)
-if (!config.position.rx_gpio)
- config.position.rx_gpio = GPS_RX_PIN;
+ if (!config.position.rx_gpio)
+ config.position.rx_gpio = GPS_RX_PIN;
#endif
#if defined(GPS_TX_PIN)
-if (!config.position.tx_gpio)
- config.position.tx_gpio = GPS_TX_PIN;
+ if (!config.position.tx_gpio)
+ config.position.tx_gpio = GPS_TX_PIN;
#endif
// ESP32 has a special set of parameters vs other arduino ports
#if defined(ARCH_ESP32)
- if(config.position.rx_gpio)
+ if (config.position.rx_gpio)
_serial_gps->begin(GPS_BAUDRATE, SERIAL_8N1, config.position.rx_gpio, config.position.tx_gpio);
#else
_serial_gps->begin(GPS_BAUDRATE);
#endif
/*
- * T-Beam-S3-Core will be preset to use gps Probe here, and other boards will not be changed first
- */
- gnssModel = probe();
+ * T-Beam-S3-Core will be preset to use gps Probe here, and other boards will not be changed first
+ */
+ gnssModel = probe();
- if(gnssModel == GNSS_MODEL_MTK){
+ if (gnssModel == GNSS_MODEL_MTK) {
/*
- * t-beam-s3-core uses the same L76K GNSS module as t-echo.
- * Unlike t-echo, L76K uses 9600 baud rate for communication by default.
- * */
- // _serial_gps->begin(9600); //The baud rate of 9600 has been initialized at the beginning of setupGPS, this line is the redundant part
- // delay(250);
+ * t-beam-s3-core uses the same L76K GNSS module as t-echo.
+ * Unlike t-echo, L76K uses 9600 baud rate for communication by default.
+ * */
+ // _serial_gps->begin(9600); //The baud rate of 9600 has been initialized at the beginning of setupGPS, this line
+ // is the redundant part delay(250);
// Initialize the L76K Chip, use GPS + GLONASS
_serial_gps->write("$PCAS04,5*1C\r\n");
@@ -191,11 +190,10 @@ if (!config.position.tx_gpio)
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
_serial_gps->write("$PCAS11,3*1E\r\n");
delay(250);
-
- }else if(gnssModel == GNSS_MODEL_UBLOX){
+ } else if (gnssModel == GNSS_MODEL_UBLOX) {
/*
- tips: NMEA Only should not be set here, otherwise initializing Ublox gnss module again after
+ tips: NMEA Only should not be set here, otherwise initializing Ublox gnss module again after
setting will not output command messages in UART1, resulting in unrecognized module information
// Set the UART port to output NMEA only
@@ -205,13 +203,14 @@ if (!config.position.tx_gpio)
if (!getACK(0x06, 0x00)) {
LOG_WARN("Unable to enable NMEA Mode.\n");
return true;
- }
+ }
*/
- // ublox-M10S can be compatible with UBLOX traditional protocol, so the following sentence settings are also valid
+ // ublox-M10S can be compatible with UBLOX traditional protocol, so the following sentence settings are also valid
// disable GGL
- byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x05, 0x3A};
+ byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01,
+ 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x05, 0x3A};
_serial_gps->write(_message_GGL, sizeof(_message_GGL));
if (!getACK(0x06, 0x01)) {
LOG_WARN("Unable to disable NMEA GGL.\n");
@@ -219,7 +218,8 @@ if (!config.position.tx_gpio)
}
// disable GSA
- byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x41};
+ byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02,
+ 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x41};
_serial_gps->write(_message_GSA, sizeof(_message_GSA));
if (!getACK(0x06, 0x01)) {
LOG_WARN("Unable to disable NMEA GSA.\n");
@@ -227,7 +227,8 @@ if (!config.position.tx_gpio)
}
// disable GSV
- byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x48};
+ byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03,
+ 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x48};
_serial_gps->write(_message_GSV, sizeof(_message_GSV));
if (!getACK(0x06, 0x01)) {
LOG_WARN("Unable to disable NMEA GSV.\n");
@@ -235,7 +236,8 @@ if (!config.position.tx_gpio)
}
// disable VTG
- byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x09, 0x56};
+ byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05,
+ 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x09, 0x56};
_serial_gps->write(_message_VTG, sizeof(_message_VTG));
if (!getACK(0x06, 0x01)) {
LOG_WARN("Unable to disable NMEA VTG.\n");
@@ -243,7 +245,8 @@ if (!config.position.tx_gpio)
}
// enable RMC
- byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09, 0x54};
+ byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09, 0x54};
_serial_gps->write(_message_RMC, sizeof(_message_RMC));
if (!getACK(0x06, 0x01)) {
LOG_WARN("Unable to enable NMEA RMC.\n");
@@ -251,7 +254,8 @@ if (!config.position.tx_gpio)
}
// enable GGA
- byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x38};
+ byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x38};
_serial_gps->write(_message_GGA, sizeof(_message_GGA));
if (!getACK(0x06, 0x01)) {
LOG_WARN("Unable to enable NMEA GGA.\n");
@@ -271,9 +275,9 @@ bool GPS::setup()
#endif
#ifdef HAS_PMU
-if(config.position.gps_enabled){
- setGPSPower(true);
-}
+ if (config.position.gps_enabled) {
+ setGPSPower(true);
+ }
#endif
#ifdef PIN_GPS_RESET
@@ -290,7 +294,8 @@ if(config.position.gps_enabled){
notifyDeepSleepObserver.observe(¬ifyDeepSleep);
notifyGPSSleepObserver.observe(¬ifyGPSSleep);
}
- if (config.position.gps_enabled==false) {
+
+ if (config.position.gps_enabled == false && config.position.fixed_position == false) {
setAwake(false);
doGPSpowersave(false);
}
@@ -397,12 +402,13 @@ uint32_t GPS::getSleepTime() const
uint32_t t = config.position.gps_update_interval;
bool gps_enabled = config.position.gps_enabled;
- if (!gps_enabled)
+ // We'll not need the GPS thread to wake up again after first acq. with fixed position.
+ if (!gps_enabled || config.position.fixed_position)
t = UINT32_MAX; // Sleep forever now
if (t == UINT32_MAX)
return t; // already maxint
-
+
return t * 1000;
}
@@ -422,16 +428,21 @@ void GPS::publishUpdate()
int32_t GPS::runOnce()
{
+ // Repeaters have no need for GPS
+ if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER)
+ disable();
+
if (whileIdle()) {
// if we have received valid NMEA claim we are connected
setConnected();
} else {
- if((config.position.gps_enabled == 1) && (gnssModel == GNSS_MODEL_UBLOX)){
+ if ((config.position.gps_enabled == 1) && (gnssModel == GNSS_MODEL_UBLOX)) {
// reset the GPS on next bootup
- if(devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) {
+ if (devicestate.did_gps_reset && (millis() > 60000) && !hasFlow()) {
LOG_DEBUG("GPS is not communicating, trying factory reset on next bootup.\n");
devicestate.did_gps_reset = false;
nodeDB.saveDeviceStateToDisk();
+ disable(); // Stop the GPS thread as it can do nothing useful until next reboot.
}
}
}
@@ -481,7 +492,7 @@ int32_t GPS::runOnce()
if (hasValidLocation) {
LOG_DEBUG("hasValidLocation FALLING EDGE (last read: %d)\n", gotLoc);
}
- p = Position_init_default;
+ p = meshtastic_Position_init_default;
hasValidLocation = false;
}
@@ -493,6 +504,14 @@ int32_t GPS::runOnce()
// If state has changed do a publish
publishUpdate();
+ if (!(fixeddelayCtr >= 20) && config.position.fixed_position && hasValidLocation) {
+ fixeddelayCtr++;
+ // LOG_DEBUG("Our delay counter is %d\n", fixeddelayCtr);
+ if (fixeddelayCtr >= 20) {
+ doGPSpowersave(false);
+ forceWake(false);
+ }
+ }
// 9600bps is approx 1 byte per msec, so considering our buffer size we never need to wake more often than 200ms
// if not awake we can run super infrquently (once every 5 secs?) to see if we need to wake.
return isAwake ? GPS_THREAD_INTERVAL : 5000;
@@ -545,10 +564,10 @@ GnssModel_t GPS::probe()
// we use autodetect, only T-BEAM S3 for now...
uint8_t buffer[256];
/*
- * The GNSS module information variable is temporarily placed inside the function body,
- * if it needs to be used elsewhere, it can be moved to the outside
- * */
- struct uBloxGnssModelInfo info ;
+ * The GNSS module information variable is temporarily placed inside the function body,
+ * if it needs to be used elsewhere, it can be moved to the outside
+ * */
+ struct uBloxGnssModelInfo info;
memset(&info, 0, sizeof(struct uBloxGnssModelInfo));
@@ -562,10 +581,10 @@ GnssModel_t GPS::probe()
while (millis() < startTimeout) {
if (_serial_gps->available()) {
String ver = _serial_gps->readStringUntil('\r');
- // Get module info , If the correct header is returned,
+ // Get module info , If the correct header is returned,
// it can be determined that it is the MTK chip
int index = ver.indexOf("$");
- if(index != -1){
+ if (index != -1) {
ver = ver.substring(index);
if (ver.startsWith("$GPTXT,01,01,02")) {
LOG_INFO("L76K GNSS init succeeded, using L76K GNSS Module\n");
@@ -574,7 +593,6 @@ GnssModel_t GPS::probe()
}
}
}
-
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x0E, 0x30};
_serial_gps->write(cfg_rate, sizeof(cfg_rate));
@@ -582,10 +600,10 @@ GnssModel_t GPS::probe()
if (!getAck(buffer, 256, 0x06, 0x08)) {
LOG_WARN("Failed to find UBlox & MTK GNSS Module\n");
return GNSS_MODEL_UNKONW;
- }
+ }
// Get Ublox gnss module hardware and software info
- uint8_t cfg_get_hw[] = {0xB5, 0x62, 0x0A, 0x04, 0x00, 0x00, 0x0E, 0x34};
+ uint8_t cfg_get_hw[] = {0xB5, 0x62, 0x0A, 0x04, 0x00, 0x00, 0x0E, 0x34};
_serial_gps->write(cfg_get_hw, sizeof(cfg_get_hw));
uint16_t len = getAck(buffer, 256, 0x0A, 0x04);
@@ -612,27 +630,27 @@ GnssModel_t GPS::probe()
}
LOG_DEBUG("Module Info : \n");
- LOG_DEBUG("Soft version: %s\n",info.swVersion);
- LOG_DEBUG("Hard version: %s\n",info.hwVersion);
- LOG_DEBUG("Extensions:%d\n",info.extensionNo);
+ LOG_DEBUG("Soft version: %s\n", info.swVersion);
+ LOG_DEBUG("Hard version: %s\n", info.hwVersion);
+ LOG_DEBUG("Extensions:%d\n", info.extensionNo);
for (int i = 0; i < info.extensionNo; i++) {
- LOG_DEBUG(" %s\n",info.extension[i]);
+ LOG_DEBUG(" %s\n", info.extension[i]);
}
- memset(buffer,0,sizeof(buffer));
+ memset(buffer, 0, sizeof(buffer));
- //tips: extensionNo field is 0 on some 6M GNSS modules
+ // tips: extensionNo field is 0 on some 6M GNSS modules
for (int i = 0; i < info.extensionNo; ++i) {
if (!strncmp(info.extension[i], "OD=", 3)) {
- strcpy((char *)buffer, &(info.extension[i][3]));
- LOG_DEBUG("GetModel:%s\n",(char *)buffer);
+ strncpy((char *)buffer, &(info.extension[i][3]), sizeof(buffer));
+ LOG_DEBUG("GetModel:%s\n", (char *)buffer);
}
}
}
- if (strlen((char*)buffer)) {
- LOG_INFO("UBlox GNSS init succeeded, using UBlox %s GNSS Module\n" , buffer);
- }else{
+ if (strlen((char *)buffer)) {
+ LOG_INFO("UBlox GNSS init succeeded, using UBlox %s GNSS Module\n", buffer);
+ } else {
LOG_INFO("UBlox GNSS init succeeded, using UBlox GNSS Module\n");
}
@@ -663,8 +681,7 @@ GPS *createGps()
new_gps->setup();
return new_gps;
}
- }
- else{
+ } else {
GPS *new_gps = new NMEAGPS();
new_gps->setup();
return new_gps;
diff --git a/src/gps/GPS.h b/src/gps/GPS.h
index 5d24268d7..a5f5f2ff4 100644
--- a/src/gps/GPS.h
+++ b/src/gps/GPS.h
@@ -4,19 +4,18 @@
#include "Observer.h"
#include "concurrency/OSThread.h"
-
-struct uBloxGnssModelInfo {
- char swVersion[30];
- char hwVersion[10];
+struct uBloxGnssModelInfo {
+ char swVersion[30];
+ char hwVersion[10];
uint8_t extensionNo;
- char extension[10][30];
-} ;
+ char extension[10][30];
+};
-typedef enum{
- GNSS_MODEL_MTK,
- GNSS_MODEL_UBLOX,
- GNSS_MODEL_UNKONW,
-}GnssModel_t;
+typedef enum {
+ GNSS_MODEL_MTK,
+ GNSS_MODEL_UBLOX,
+ GNSS_MODEL_UNKONW,
+} GnssModel_t;
// Generate a string representation of DOP
const char *getDOPString(uint32_t dop);
@@ -55,7 +54,7 @@ class GPS : private concurrency::OSThread
/** If !NULL we will use this serial port to construct our GPS */
static HardwareSerial *_serial_gps;
- Position p = Position_init_default;
+ meshtastic_Position p = meshtastic_Position_init_default;
GPS() : concurrency::OSThread("GPS") {}
@@ -78,7 +77,7 @@ class GPS : private concurrency::OSThread
/// Return true if we are connected to a GPS
bool isConnected() const { return hasGPS; }
- bool isPowerSaving() const { return !config.position.gps_enabled;}
+ bool isPowerSaving() const { return !config.position.gps_enabled; }
/**
* Restart our lock attempt - try to get and broadcast a GPS reading ASAP
@@ -164,17 +163,20 @@ class GPS : private concurrency::OSThread
virtual int32_t runOnce() override;
- // Get GNSS model
+ // Get GNSS model
GnssModel_t probe();
int getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID);
+ // delay counter to allow more sats before fixed position stops GPS thread
+ uint8_t fixeddelayCtr = 0;
+
protected:
GnssModel_t gnssModel = GNSS_MODEL_UNKONW;
};
-// Creates an instance of the GPS class.
+// Creates an instance of the GPS class.
// Returns the new instance or null if the GPS is not present.
-GPS* createGps();
+GPS *createGps();
extern GPS *gps;
diff --git a/src/gps/GeoCoord.cpp b/src/gps/GeoCoord.cpp
index 13c24b701..9d5e6315e 100644
--- a/src/gps/GeoCoord.cpp
+++ b/src/gps/GeoCoord.cpp
@@ -1,21 +1,25 @@
#include "GeoCoord.h"
-GeoCoord::GeoCoord() {
+GeoCoord::GeoCoord()
+{
_dirty = true;
}
-GeoCoord::GeoCoord (int32_t lat, int32_t lon, int32_t alt) : _latitude(lat), _longitude(lon), _altitude(alt) {
+GeoCoord::GeoCoord(int32_t lat, int32_t lon, int32_t alt) : _latitude(lat), _longitude(lon), _altitude(alt)
+{
GeoCoord::setCoords();
}
-GeoCoord::GeoCoord (float lat, float lon, int32_t alt) : _altitude(alt) {
+GeoCoord::GeoCoord(float lat, float lon, int32_t alt) : _altitude(alt)
+{
// Change decimial reprsentation to int32_t. I.e., 12.345 becomes 123450000
_latitude = int32_t(lat * 1e+7);
_longitude = int32_t(lon * 1e+7);
GeoCoord::setCoords();
}
-GeoCoord::GeoCoord(double lat, double lon, int32_t alt): _altitude(alt) {
+GeoCoord::GeoCoord(double lat, double lon, int32_t alt) : _altitude(alt)
+{
// Change decimial reprsentation to int32_t. I.e., 12.345 becomes 123450000
_latitude = int32_t(lat * 1e+7);
_longitude = int32_t(lon * 1e+7);
@@ -23,7 +27,8 @@ GeoCoord::GeoCoord(double lat, double lon, int32_t alt): _altitude(alt) {
}
// Initialize all the coordinate systems
-void GeoCoord::setCoords() {
+void GeoCoord::setCoords()
+{
double lat = _latitude * 1e-7;
double lon = _longitude * 1e-7;
GeoCoord::latLongToDMS(lat, lon, _dms);
@@ -34,9 +39,10 @@ void GeoCoord::setCoords() {
_dirty = false;
}
-void GeoCoord::updateCoords(int32_t lat, int32_t lon, int32_t alt) {
+void GeoCoord::updateCoords(int32_t lat, int32_t lon, int32_t alt)
+{
// If marked dirty or new coordiantes
- if(_dirty || _latitude != lat || _longitude != lon || _altitude != alt) {
+ if (_dirty || _latitude != lat || _longitude != lon || _altitude != alt) {
_dirty = true;
_latitude = lat;
_longitude = lon;
@@ -45,25 +51,26 @@ void GeoCoord::updateCoords(int32_t lat, int32_t lon, int32_t alt) {
}
}
-void GeoCoord::updateCoords(const double lat, const double lon, const int32_t alt) {
+void GeoCoord::updateCoords(const double lat, const double lon, const int32_t alt)
+{
int32_t iLat = lat * 1e+7;
int32_t iLon = lon * 1e+7;
// If marked dirty or new coordiantes
- if(_dirty || _latitude != iLat || _longitude != iLon || _altitude != alt) {
+ if (_dirty || _latitude != iLat || _longitude != iLon || _altitude != alt) {
_dirty = true;
_latitude = iLat;
_longitude = iLon;
_altitude = alt;
setCoords();
}
-
}
-void GeoCoord::updateCoords(const float lat, const float lon, const int32_t alt) {
+void GeoCoord::updateCoords(const float lat, const float lon, const int32_t alt)
+{
int32_t iLat = lat * 1e+7;
int32_t iLon = lon * 1e+7;
// If marked dirty or new coordiantes
- if(_dirty || _latitude != iLat || _longitude != iLon || _altitude != alt) {
+ if (_dirty || _latitude != iLat || _longitude != iLon || _altitude != alt) {
_dirty = true;
_latitude = iLat;
_longitude = iLon;
@@ -73,12 +80,15 @@ void GeoCoord::updateCoords(const float lat, const float lon, const int32_t alt)
}
/**
- * Converts lat long coordinates from decimal degrees to degrees minutes seconds format.
+ * Converts lat long coordinates from decimal degrees to degrees minutes seconds format.
* DD°MM'SS"C DDD°MM'SS"C
*/
-void GeoCoord::latLongToDMS(const double lat, const double lon, DMS &dms) {
- if (lat < 0) dms.latCP = 'S';
- else dms.latCP = 'N';
+void GeoCoord::latLongToDMS(const double lat, const double lon, DMS &dms)
+{
+ if (lat < 0)
+ dms.latCP = 'S';
+ else
+ dms.latCP = 'N';
double latDeg = lat;
@@ -90,8 +100,10 @@ void GeoCoord::latLongToDMS(const double lat, const double lon, DMS &dms) {
dms.latMin = floor(latMin);
dms.latSec = (latMin - dms.latMin) * 60;
- if (lon < 0) dms.lonCP = 'W';
- else dms.lonCP = 'E';
+ if (lon < 0)
+ dms.lonCP = 'W';
+ else
+ dms.lonCP = 'E';
double lonDeg = lon;
@@ -108,52 +120,64 @@ void GeoCoord::latLongToDMS(const double lat, const double lon, DMS &dms) {
* Converts lat long coordinates to UTM.
* based on this: https://github.com/walvok/LatLonToUTM/blob/master/latlon_utm.ino
*/
-void GeoCoord::latLongToUTM(const double lat, const double lon, UTM &utm) {
+void GeoCoord::latLongToUTM(const double lat, const double lon, UTM &utm)
+{
const std::string latBands = "CDEFGHJKLMNPQRSTUVWXX";
- utm.zone = int((lon + 180)/6 + 1);
- utm.band = latBands[int(lat/8 + 10)];
- double a = 6378137; // WGS84 - equatorial radius
- double k0 = 0.9996; // UTM point scale on the central meridian
- double eccSquared = 0.00669438; // eccentricity squared
- double lonTemp = (lon + 180) - int((lon + 180)/360) * 360 - 180; //Make sure the longitude is between -180.00 .. 179.9
+ utm.zone = int((lon + 180) / 6 + 1);
+ utm.band = latBands[int(lat / 8 + 10)];
+ double a = 6378137; // WGS84 - equatorial radius
+ double k0 = 0.9996; // UTM point scale on the central meridian
+ double eccSquared = 0.00669438; // eccentricity squared
+ double lonTemp = (lon + 180) - int((lon + 180) / 360) * 360 - 180; // Make sure the longitude is between -180.00 .. 179.9
double latRad = toRadians(lat);
double lonRad = toRadians(lonTemp);
// Special Zones for Norway and Svalbard
- if( lat >= 56.0 && lat < 64.0 && lonTemp >= 3.0 && lonTemp < 12.0 ) // Norway
+ if (lat >= 56.0 && lat < 64.0 && lonTemp >= 3.0 && lonTemp < 12.0) // Norway
utm.zone = 32;
- if( lat >= 72.0 && lat < 84.0 ) { // Svalbard
- if ( lonTemp >= 0.0 && lonTemp < 9.0 ) utm.zone = 31;
- else if( lonTemp >= 9.0 && lonTemp < 21.0 ) utm.zone = 33;
- else if( lonTemp >= 21.0 && lonTemp < 33.0 ) utm.zone = 35;
- else if( lonTemp >= 33.0 && lonTemp < 42.0 ) utm.zone = 37;
+ if (lat >= 72.0 && lat < 84.0) { // Svalbard
+ if (lonTemp >= 0.0 && lonTemp < 9.0)
+ utm.zone = 31;
+ else if (lonTemp >= 9.0 && lonTemp < 21.0)
+ utm.zone = 33;
+ else if (lonTemp >= 21.0 && lonTemp < 33.0)
+ utm.zone = 35;
+ else if (lonTemp >= 33.0 && lonTemp < 42.0)
+ utm.zone = 37;
}
-
- double lonOrigin = (utm.zone - 1)*6 - 180 + 3; // puts origin in middle of zone
+
+ double lonOrigin = (utm.zone - 1) * 6 - 180 + 3; // puts origin in middle of zone
double lonOriginRad = toRadians(lonOrigin);
- double eccPrimeSquared = (eccSquared)/(1 - eccSquared);
- double N = a/sqrt(1 - eccSquared*sin(latRad)*sin(latRad));
- double T = tan(latRad)*tan(latRad);
- double C = eccPrimeSquared*cos(latRad)*cos(latRad);
- double A = cos(latRad)*(lonRad - lonOriginRad);
- double M = a*((1 - eccSquared/4 - 3*eccSquared*eccSquared/64 - 5*eccSquared*eccSquared*eccSquared/256)*latRad
- - (3*eccSquared/8 + 3*eccSquared*eccSquared/32 + 45*eccSquared*eccSquared*eccSquared/1024)*sin(2*latRad)
- + (15*eccSquared*eccSquared/256 + 45*eccSquared*eccSquared*eccSquared/1024)*sin(4*latRad)
- - (35*eccSquared*eccSquared*eccSquared/3072)*sin(6*latRad));
- utm.easting = (double)(k0*N*(A+(1-T+C)*pow(A, 3)/6 + (5-18*T+T*T+72*C-58*eccPrimeSquared)*A*A*A*A*A/120)
- + 500000.0);
- utm.northing = (double)(k0*(M+N*tan(latRad)*(A*A/2+(5-T+9*C+4*C*C)*A*A*A*A/24
- + (61-58*T+T*T+600*C-330*eccPrimeSquared)*A*A*A*A*A*A/720)));
-
- if(lat < 0)
- utm.northing += 10000000.0; //10000000 meter offset for southern hemisphere
+ double eccPrimeSquared = (eccSquared) / (1 - eccSquared);
+ double N = a / sqrt(1 - eccSquared * sin(latRad) * sin(latRad));
+ double T = tan(latRad) * tan(latRad);
+ double C = eccPrimeSquared * cos(latRad) * cos(latRad);
+ double A = cos(latRad) * (lonRad - lonOriginRad);
+ double M =
+ a * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256) * latRad -
+ (3 * eccSquared / 8 + 3 * eccSquared * eccSquared / 32 + 45 * eccSquared * eccSquared * eccSquared / 1024) *
+ sin(2 * latRad) +
+ (15 * eccSquared * eccSquared / 256 + 45 * eccSquared * eccSquared * eccSquared / 1024) * sin(4 * latRad) -
+ (35 * eccSquared * eccSquared * eccSquared / 3072) * sin(6 * latRad));
+ utm.easting = (double)(k0 * N *
+ (A + (1 - T + C) * pow(A, 3) / 6 +
+ (5 - 18 * T + T * T + 72 * C - 58 * eccPrimeSquared) * A * A * A * A * A / 120) +
+ 500000.0);
+ utm.northing =
+ (double)(k0 * (M + N * tan(latRad) *
+ (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24 +
+ (61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared) * A * A * A * A * A * A / 720)));
+
+ if (lat < 0)
+ utm.northing += 10000000.0; // 10000000 meter offset for southern hemisphere
}
// Converts lat long coordinates to an MGRS.
-void GeoCoord::latLongToMGRS(const double lat, const double lon, MGRS &mgrs) {
- const std::string e100kLetters[3] = { "ABCDEFGH", "JKLMNPQR", "STUVWXYZ" };
- const std::string n100kLetters[2] = { "ABCDEFGHJKLMNPQRSTUV", "FGHJKLMNPQRSTUVABCDE" };
+void GeoCoord::latLongToMGRS(const double lat, const double lon, MGRS &mgrs)
+{
+ const std::string e100kLetters[3] = {"ABCDEFGH", "JKLMNPQR", "STUVWXYZ"};
+ const std::string n100kLetters[2] = {"ABCDEFGHJKLMNPQRSTUV", "FGHJKLMNPQRSTUVABCDE"};
UTM utm;
latLongToUTM(lat, lon, utm);
mgrs.zone = utm.zone;
@@ -161,7 +185,7 @@ void GeoCoord::latLongToMGRS(const double lat, const double lon, MGRS &mgrs) {
double col = floor(utm.easting / 100000);
mgrs.east100k = e100kLetters[(mgrs.zone - 1) % 3][col - 1];
double row = (int32_t)floor(utm.northing / 100000.0) % 20;
- mgrs.north100k = n100kLetters[(mgrs.zone-1)%2][row];
+ mgrs.north100k = n100kLetters[(mgrs.zone - 1) % 2][row];
mgrs.easting = (int32_t)utm.easting % 100000;
mgrs.northing = (int32_t)utm.northing % 100000;
}
@@ -170,52 +194,54 @@ void GeoCoord::latLongToMGRS(const double lat, const double lon, MGRS &mgrs) {
* Converts lat long coordinates to Ordnance Survey Grid Reference (UK National Grid Ref).
* Based on: https://www.movable-type.co.uk/scripts/latlong-os-gridref.html
*/
-void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr) {
+void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr)
+{
const char letter[] = "ABCDEFGHJKLMNOPQRSTUVWXYZ"; // No 'I' in OSGR
- double a = 6377563.396; // Airy 1830 semi-major axis
- double b = 6356256.909; // Airy 1830 semi-minor axis
- double f0 = 0.9996012717; // National Grid point scale factor on the central meridian
- double phi0 = toRadians(49);
+ double a = 6377563.396; // Airy 1830 semi-major axis
+ double b = 6356256.909; // Airy 1830 semi-minor axis
+ double f0 = 0.9996012717; // National Grid point scale factor on the central meridian
+ double phi0 = toRadians(49);
double lambda0 = toRadians(-2);
double n0 = -100000;
double e0 = 400000;
- double e2 = 1 - (b*b)/(a*a); // eccentricity squared
- double n = (a - b)/(a + b);
-
+ double e2 = 1 - (b * b) / (a * a); // eccentricity squared
+ double n = (a - b) / (a + b);
+
double osgb_Latitude;
double osgb_Longitude;
convertWGS84ToOSGB36(lat, lon, osgb_Latitude, osgb_Longitude);
- double phi = osgb_Latitude; // already in radians
+ double phi = osgb_Latitude; // already in radians
double lambda = osgb_Longitude; // already in radians
double v = a * f0 / sqrt(1 - e2 * sin(phi) * sin(phi));
double rho = a * f0 * (1 - e2) / pow(1 - e2 * sin(phi) * sin(phi), 1.5);
double eta2 = v / rho - 1;
- double mA = (1 + n + (5/4)*n*n + (5/4)*n*n*n) * (phi - phi0);
- double mB = (3*n + 3*n*n + (21/8)*n*n*n) * sin(phi - phi0) * cos(phi + phi0);
+ double mA = (1 + n + (5 / 4) * n * n + (5 / 4) * n * n * n) * (phi - phi0);
+ double mB = (3 * n + 3 * n * n + (21 / 8) * n * n * n) * sin(phi - phi0) * cos(phi + phi0);
// loss of precision in mC & mD due to floating point rounding can cause innaccuracy of northing by a few meters
- double mC = (15/8*n*n + 15/8*n*n*n) * sin(2*(phi - phi0)) * cos(2*(phi + phi0));
- double mD = (35/24)*n*n*n * sin(3*(phi - phi0)) * cos(3*(phi + phi0));
- double m = b*f0*(mA - mB + mC - mD);
+ double mC = (15 / 8 * n * n + 15 / 8 * n * n * n) * sin(2 * (phi - phi0)) * cos(2 * (phi + phi0));
+ double mD = (35 / 24) * n * n * n * sin(3 * (phi - phi0)) * cos(3 * (phi + phi0));
+ double m = b * f0 * (mA - mB + mC - mD);
- double cos3Phi = cos(phi)*cos(phi)*cos(phi);
- double cos5Phi = cos3Phi*cos(phi)*cos(phi);
- double tan2Phi = tan(phi)*tan(phi);
- double tan4Phi = tan2Phi*tan2Phi;
+ double cos3Phi = cos(phi) * cos(phi) * cos(phi);
+ double cos5Phi = cos3Phi * cos(phi) * cos(phi);
+ double tan2Phi = tan(phi) * tan(phi);
+ double tan4Phi = tan2Phi * tan2Phi;
double I = m + n0;
- double II = (v/2)*sin(phi)*cos(phi);
- double III = (v/24)*sin(phi)*cos3Phi*(5 - tan2Phi + 9*eta2);
- double IIIA = (v/720)*sin(phi)*cos5Phi*(61 - 58*tan2Phi + tan4Phi);
- double IV = v*cos(phi);
- double V = (v/6)*cos3Phi*(v/rho - tan2Phi);
- double VI = (v/120)*cos5Phi*(5 - 18*tan2Phi + tan4Phi + 14*eta2 - 58*tan2Phi*eta2);
+ double II = (v / 2) * sin(phi) * cos(phi);
+ double III = (v / 24) * sin(phi) * cos3Phi * (5 - tan2Phi + 9 * eta2);
+ double IIIA = (v / 720) * sin(phi) * cos5Phi * (61 - 58 * tan2Phi + tan4Phi);
+ double IV = v * cos(phi);
+ double V = (v / 6) * cos3Phi * (v / rho - tan2Phi);
+ double VI = (v / 120) * cos5Phi * (5 - 18 * tan2Phi + tan4Phi + 14 * eta2 - 58 * tan2Phi * eta2);
double deltaLambda = lambda - lambda0;
- double deltaLambda2 = deltaLambda*deltaLambda;
- double northing = I + II*deltaLambda2 + III*deltaLambda2*deltaLambda2 + IIIA*deltaLambda2*deltaLambda2*deltaLambda2;
- double easting = e0 + IV*deltaLambda + V*deltaLambda2*deltaLambda + VI*deltaLambda2*deltaLambda2*deltaLambda;
+ double deltaLambda2 = deltaLambda * deltaLambda;
+ double northing =
+ I + II * deltaLambda2 + III * deltaLambda2 * deltaLambda2 + IIIA * deltaLambda2 * deltaLambda2 * deltaLambda2;
+ double easting = e0 + IV * deltaLambda + V * deltaLambda2 * deltaLambda + VI * deltaLambda2 * deltaLambda2 * deltaLambda;
if (easting < 0 || easting > 700000 || northing < 0 || northing > 1300000) // Check if out of boundaries
- osgr = { 'I', 'I', 0, 0 };
+ osgr = {'I', 'I', 0, 0};
else {
uint32_t e100k = floor(easting / 100000);
uint32_t n100k = floor(northing / 100000);
@@ -232,7 +258,8 @@ void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr) {
* Converts lat long coordinates to Open Location Code.
* Based on: https://github.com/google/open-location-code/blob/main/c/src/olc.c
*/
-void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc) {
+void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc)
+{
char tempCode[] = "1234567890abc";
const char kAlphabet[] = "23456789CFGHJMPQRVWX";
double latitude;
@@ -258,7 +285,7 @@ void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc) {
lat_val += latitude * 2.5e7;
lng_val += longitude * 8.192e6;
size_t pos = OLC_CODE_LEN;
-
+
if (OLC_CODE_LEN > 10) { // Compute grid part of code if needed
for (size_t i = 0; i < 5; i++) {
int lat_digit = lat_val % 5;
@@ -272,9 +299,9 @@ void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc) {
lat_val /= pow(5, 5);
lng_val /= pow(4, 5);
}
-
+
pos = 10;
-
+
for (size_t i = 0; i < 5; i++) { // Compute pair section of code
int lat_ndx = lat_val % 20;
int lng_ndx = lng_val % 20;
@@ -286,7 +313,7 @@ void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc) {
if (i == 0)
tempCode[pos--] = '+';
}
-
+
if (OLC_CODE_LEN < 9) { // Add padding if needed
for (size_t i = OLC_CODE_LEN; i < 9; i++)
tempCode[i] = '0';
@@ -300,50 +327,52 @@ void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc) {
for (size_t i = 0; i < char_count; i++) {
olc.code[i] = tempCode[i];
}
- olc.code[char_count] = '\0';
+ olc.code[char_count] = '\0';
}
// Converts the coordinate in WGS84 datum to the OSGB36 datum.
-void GeoCoord::convertWGS84ToOSGB36(const double lat, const double lon, double &osgb_Latitude, double &osgb_Longitude) {
+void GeoCoord::convertWGS84ToOSGB36(const double lat, const double lon, double &osgb_Latitude, double &osgb_Longitude)
+{
// Convert lat long to cartesian
double phi = toRadians(lat);
double lambda = toRadians(lon);
- double h = 0.0; // No OSTN height data used, some loss of accuracy (up to 5m)
- double wgsA = 6378137; // WGS84 datum semi major axis
+ double h = 0.0; // No OSTN height data used, some loss of accuracy (up to 5m)
+ double wgsA = 6378137; // WGS84 datum semi major axis
double wgsF = 1 / 298.257223563; // WGS84 datum flattening
- double ecc = 2*wgsF - wgsF*wgsF;
+ double ecc = 2 * wgsF - wgsF * wgsF;
double vee = wgsA / sqrt(1 - ecc * pow(sin(phi), 2));
double wgsX = (vee + h) * cos(phi) * cos(lambda);
double wgsY = (vee + h) * cos(phi) * sin(lambda);
double wgsZ = ((1 - ecc) * vee + h) * sin(phi);
// 7-parameter Helmert transform
- double tx = -446.448; // x shift in meters
- double ty = 125.157; // y shift in meters
- double tz = -542.060; // z shift in meters
- double s = 20.4894/1e6 + 1; // scale normalized parts per million to (s + 1)
- double rx = toRadians(-0.1502/3600); // x rotation normalize arcseconds to radians
- double ry = toRadians(-0.2470/3600); // y rotation normalize arcseconds to radians
- double rz = toRadians(-0.8421/3600); // z rotation normalize arcseconds to radians
- double osgbX = tx + wgsX*s - wgsY*rz + wgsZ*ry;
- double osgbY = ty + wgsX*rz + wgsY*s - wgsZ*rx;
- double osgbZ = tz - wgsX*ry + wgsY*rx + wgsZ*s;
+ double tx = -446.448; // x shift in meters
+ double ty = 125.157; // y shift in meters
+ double tz = -542.060; // z shift in meters
+ double s = 20.4894 / 1e6 + 1; // scale normalized parts per million to (s + 1)
+ double rx = toRadians(-0.1502 / 3600); // x rotation normalize arcseconds to radians
+ double ry = toRadians(-0.2470 / 3600); // y rotation normalize arcseconds to radians
+ double rz = toRadians(-0.8421 / 3600); // z rotation normalize arcseconds to radians
+ double osgbX = tx + wgsX * s - wgsY * rz + wgsZ * ry;
+ double osgbY = ty + wgsX * rz + wgsY * s - wgsZ * rx;
+ double osgbZ = tz - wgsX * ry + wgsY * rx + wgsZ * s;
// Convert cartesian to lat long
- double airyA = 6377563.396; // Airy1830 datum semi major axis
- double airyB = 6356256.909; // Airy1830 datum semi minor axis
- double airyF = 1/ 299.3249646; // Airy1830 datum flattening
- double airyEcc = 2*airyF - airyF*airyF;
+ double airyA = 6377563.396; // Airy1830 datum semi major axis
+ double airyB = 6356256.909; // Airy1830 datum semi minor axis
+ double airyF = 1 / 299.3249646; // Airy1830 datum flattening
+ double airyEcc = 2 * airyF - airyF * airyF;
double airyEcc2 = airyEcc / (1 - airyEcc);
- double p = sqrt(osgbX*osgbX + osgbY*osgbY);
- double R = sqrt(p*p + osgbZ*osgbZ);
- double tanBeta = (airyB*osgbZ) / (airyA*p) * (1 + airyEcc2*airyB/R);
- double sinBeta = tanBeta / sqrt(1 + tanBeta*tanBeta);
+ double p = sqrt(osgbX * osgbX + osgbY * osgbY);
+ double R = sqrt(p * p + osgbZ * osgbZ);
+ double tanBeta = (airyB * osgbZ) / (airyA * p) * (1 + airyEcc2 * airyB / R);
+ double sinBeta = tanBeta / sqrt(1 + tanBeta * tanBeta);
double cosBeta = sinBeta / tanBeta;
- osgb_Latitude = atan2(osgbZ + airyEcc2*airyB*sinBeta*sinBeta*sinBeta, p - airyEcc*airyA*cosBeta*cosBeta*cosBeta); // leave in radians
- osgb_Longitude = atan2(osgbY, osgbX); // leave in radians
- //osgb height = p*cos(osgb.latitude) + osgbZ*sin(osgb.latitude) -
- //(airyA*airyA/(airyA / sqrt(1 - airyEcc*sin(osgb.latitude)*sin(osgb.latitude)))); // Not used, no OSTN data
+ osgb_Latitude = atan2(osgbZ + airyEcc2 * airyB * sinBeta * sinBeta * sinBeta,
+ p - airyEcc * airyA * cosBeta * cosBeta * cosBeta); // leave in radians
+ osgb_Longitude = atan2(osgbY, osgbX); // leave in radians
+ // osgb height = p*cos(osgb.latitude) + osgbZ*sin(osgb.latitude) -
+ //(airyA*airyA/(airyA / sqrt(1 - airyEcc*sin(osgb.latitude)*sin(osgb.latitude)))); // Not used, no OSTN data
}
/// Ported from my old java code, returns distance in meters along the globe
@@ -397,12 +426,13 @@ float GeoCoord::bearing(double lat1, double lon1, double lat2, double lon2)
* @brief Convert from meters to range in radians on a great circle
* @param range_meters
* The range in meters
- * @return range in radians on a great circle
+ * @return range in radians on a great circle
*/
-float GeoCoord::rangeMetersToRadians(double range_meters) {
+float GeoCoord::rangeMetersToRadians(double range_meters)
+{
// 1 nm is 1852 meters
double distance_nm = range_meters * 1852;
- return (PI / (180 * 60)) *distance_nm;
+ return (PI / (180 * 60)) * distance_nm;
}
/**
@@ -410,22 +440,27 @@ float GeoCoord::rangeMetersToRadians(double range_meters) {
* @brief Convert from radians to range in meters on a great circle
* @param range_radians
* The range in radians
- * @return Range in meters on a great circle
+ * @return Range in meters on a great circle
*/
-float GeoCoord::rangeRadiansToMeters(double range_radians) {
+float GeoCoord::rangeRadiansToMeters(double range_radians)
+{
double distance_nm = ((180 * 60) / PI) * range_radians;
// 1 meter is 0.000539957 nm
return distance_nm * 0.000539957;
}
// Find distance from point to passed in point
-int32_t GeoCoord::distanceTo(const GeoCoord& pointB) {
- return latLongToMeter(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7, pointB.getLongitude() * 1e-7);
+int32_t GeoCoord::distanceTo(const GeoCoord &pointB)
+{
+ return latLongToMeter(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7,
+ pointB.getLongitude() * 1e-7);
}
// Find bearing from point to passed in point
-int32_t GeoCoord::bearingTo(const GeoCoord& pointB) {
- return bearing(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7, pointB.getLongitude() * 1e-7);
+int32_t GeoCoord::bearingTo(const GeoCoord &pointB)
+{
+ return bearing(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7,
+ pointB.getLongitude() * 1e-7);
}
/**
@@ -436,8 +471,9 @@ int32_t GeoCoord::bearingTo(const GeoCoord& pointB) {
* @param range_meters
* range in meters
* @return GeoCoord object of point at bearing and range from initial point
-*/
-std::shared_ptr GeoCoord::pointAtDistance(double bearing, double range_meters) {
+ */
+std::shared_ptr GeoCoord::pointAtDistance(double bearing, double range_meters)
+{
double range_radians = rangeMetersToRadians(range_meters);
double lat1 = this->getLatitude() * 1e-7;
double lon1 = this->getLongitude() * 1e-7;
@@ -446,5 +482,4 @@ std::shared_ptr GeoCoord::pointAtDistance(double bearing, double range
double lon = fmod(lon1 - dlon + PI, 2 * PI) - PI;
return std::make_shared(double(lat), double(lon), this->getAltitude());
-
}
diff --git a/src/gps/GeoCoord.h b/src/gps/GeoCoord.h
index 02980ea05..28e9e14e9 100644
--- a/src/gps/GeoCoord.h
+++ b/src/gps/GeoCoord.h
@@ -1,26 +1,27 @@
#pragma once
#include
-#include
-#include
#include
+#include
#include
-#include
-#include
#include
+#include
+#include
+#include
#define PI 3.1415926535897932384626433832795
#define OLC_CODE_LEN 11
// Helper functions
// Raises a number to an exponent, handling negative exponents.
-static inline double pow_neg(double base, double exponent) {
- if (exponent == 0) {
- return 1;
- } else if (exponent > 0) {
- return pow(base, exponent);
- }
- return 1 / pow(base, -exponent);
+static inline double pow_neg(double base, double exponent)
+{
+ if (exponent == 0) {
+ return 1;
+ } else if (exponent > 0) {
+ return pow(base, exponent);
+ }
+ return 1 / pow(base, -exponent);
}
static inline double toRadians(double deg)
@@ -35,8 +36,7 @@ static inline double toDegrees(double r)
// GeoCoord structs/classes
// A struct to hold the data for a DMS coordinate.
-struct DMS
-{
+struct DMS {
uint8_t latDeg;
uint8_t latMin;
uint32_t latSec;
@@ -48,8 +48,7 @@ struct DMS
};
// A struct to hold the data for a UTM coordinate, this is also used when creating an MGRS coordinate.
-struct UTM
-{
+struct UTM {
uint8_t zone;
char band;
uint32_t easting;
@@ -57,8 +56,7 @@ struct UTM
};
// A struct to hold the data for a MGRS coordinate.
-struct MGRS
-{
+struct MGRS {
uint8_t zone;
char band;
char east100k;
@@ -80,85 +78,85 @@ struct OLC {
char code[OLC_CODE_LEN + 1]; // +1 for null termination
};
-class GeoCoord {
- private:
- int32_t _latitude = 0;
- int32_t _longitude = 0;
- int32_t _altitude = 0;
+class GeoCoord
+{
+ private:
+ int32_t _latitude = 0;
+ int32_t _longitude = 0;
+ int32_t _altitude = 0;
- DMS _dms = {};
- UTM _utm = {};
- MGRS _mgrs = {};
- OSGR _osgr = {};
- OLC _olc = {};
+ DMS _dms = {};
+ UTM _utm = {};
+ MGRS _mgrs = {};
+ OSGR _osgr = {};
+ OLC _olc = {};
- bool _dirty = true;
+ bool _dirty = true;
- void setCoords();
+ void setCoords();
- public:
- GeoCoord();
- GeoCoord(int32_t lat, int32_t lon, int32_t alt);
- GeoCoord(double lat, double lon, int32_t alt);
- GeoCoord(float lat, float lon, int32_t alt);
+ public:
+ GeoCoord();
+ GeoCoord(int32_t lat, int32_t lon, int32_t alt);
+ GeoCoord(double lat, double lon, int32_t alt);
+ GeoCoord(float lat, float lon, int32_t alt);
- void updateCoords(const int32_t lat, const int32_t lon, const int32_t alt);
- void updateCoords(const double lat, const double lon, const int32_t alt);
- void updateCoords(const float lat, const float lon, const int32_t alt);
+ void updateCoords(const int32_t lat, const int32_t lon, const int32_t alt);
+ void updateCoords(const double lat, const double lon, const int32_t alt);
+ void updateCoords(const float lat, const float lon, const int32_t alt);
- // Conversions
- static void latLongToDMS(const double lat, const double lon, DMS &dms);
- static void latLongToUTM(const double lat, const double lon, UTM &utm);
- static void latLongToMGRS(const double lat, const double lon, MGRS &mgrs);
- static void latLongToOSGR(const double lat, const double lon, OSGR &osgr);
- static void latLongToOLC(const double lat, const double lon, OLC &olc);
- static void convertWGS84ToOSGB36(const double lat, const double lon, double &osgb_Latitude, double &osgb_Longitude);
- static float latLongToMeter(double lat_a, double lng_a, double lat_b, double lng_b);
- static float bearing(double lat1, double lon1, double lat2, double lon2);
- static float rangeRadiansToMeters(double range_radians);
- static float rangeMetersToRadians(double range_meters);
+ // Conversions
+ static void latLongToDMS(const double lat, const double lon, DMS &dms);
+ static void latLongToUTM(const double lat, const double lon, UTM &utm);
+ static void latLongToMGRS(const double lat, const double lon, MGRS &mgrs);
+ static void latLongToOSGR(const double lat, const double lon, OSGR &osgr);
+ static void latLongToOLC(const double lat, const double lon, OLC &olc);
+ static void convertWGS84ToOSGB36(const double lat, const double lon, double &osgb_Latitude, double &osgb_Longitude);
+ static float latLongToMeter(double lat_a, double lng_a, double lat_b, double lng_b);
+ static float bearing(double lat1, double lon1, double lat2, double lon2);
+ static float rangeRadiansToMeters(double range_radians);
+ static float rangeMetersToRadians(double range_meters);
- // Point to point conversions
- int32_t distanceTo(const GeoCoord& pointB);
- int32_t bearingTo(const GeoCoord& pointB);
- std::shared_ptr pointAtDistance(double bearing, double range);
+ // Point to point conversions
+ int32_t distanceTo(const GeoCoord &pointB);
+ int32_t bearingTo(const GeoCoord &pointB);
+ std::shared_ptr pointAtDistance(double bearing, double range);
- // Lat lon alt getters
- int32_t getLatitude() const { return _latitude; }
- int32_t getLongitude() const { return _longitude; }
- int32_t getAltitude() const { return _altitude; }
+ // Lat lon alt getters
+ int32_t getLatitude() const { return _latitude; }
+ int32_t getLongitude() const { return _longitude; }
+ int32_t getAltitude() const { return _altitude; }
- // DMS getters
- uint8_t getDMSLatDeg() const { return _dms.latDeg; }
- uint8_t getDMSLatMin() const { return _dms.latMin; }
- uint32_t getDMSLatSec() const { return _dms.latSec; }
- char getDMSLatCP() const { return _dms.latCP; }
- uint8_t getDMSLonDeg() const { return _dms.lonDeg; }
- uint8_t getDMSLonMin() const { return _dms.lonMin; }
- uint32_t getDMSLonSec() const { return _dms.lonSec; }
- char getDMSLonCP() const { return _dms.lonCP; }
+ // DMS getters
+ uint8_t getDMSLatDeg() const { return _dms.latDeg; }
+ uint8_t getDMSLatMin() const { return _dms.latMin; }
+ uint32_t getDMSLatSec() const { return _dms.latSec; }
+ char getDMSLatCP() const { return _dms.latCP; }
+ uint8_t getDMSLonDeg() const { return _dms.lonDeg; }
+ uint8_t getDMSLonMin() const { return _dms.lonMin; }
+ uint32_t getDMSLonSec() const { return _dms.lonSec; }
+ char getDMSLonCP() const { return _dms.lonCP; }
- // UTM getters
- uint8_t getUTMZone() const { return _utm.zone; }
- char getUTMBand() const { return _utm.band; }
- uint32_t getUTMEasting() const { return _utm.easting; }
- uint32_t getUTMNorthing() const { return _utm.northing; }
+ // UTM getters
+ uint8_t getUTMZone() const { return _utm.zone; }
+ char getUTMBand() const { return _utm.band; }
+ uint32_t getUTMEasting() const { return _utm.easting; }
+ uint32_t getUTMNorthing() const { return _utm.northing; }
- // MGRS getters
- uint8_t getMGRSZone() const { return _mgrs.zone; }
- char getMGRSBand() const { return _mgrs.band; }
- char getMGRSEast100k() const { return _mgrs.east100k; }
- char getMGRSNorth100k() const { return _mgrs.north100k; }
- uint32_t getMGRSEasting() const { return _mgrs.easting; }
- uint32_t getMGRSNorthing() const { return _mgrs.northing; }
+ // MGRS getters
+ uint8_t getMGRSZone() const { return _mgrs.zone; }
+ char getMGRSBand() const { return _mgrs.band; }
+ char getMGRSEast100k() const { return _mgrs.east100k; }
+ char getMGRSNorth100k() const { return _mgrs.north100k; }
+ uint32_t getMGRSEasting() const { return _mgrs.easting; }
+ uint32_t getMGRSNorthing() const { return _mgrs.northing; }
- // OSGR getters
- char getOSGRE100k() const { return _osgr.e100k; }
- char getOSGRN100k() const { return _osgr.n100k; }
- uint32_t getOSGREasting() const { return _osgr.easting; }
- uint32_t getOSGRNorthing() const { return _osgr.northing; }
+ // OSGR getters
+ char getOSGRE100k() const { return _osgr.e100k; }
+ char getOSGRN100k() const { return _osgr.n100k; }
+ uint32_t getOSGREasting() const { return _osgr.easting; }
+ uint32_t getOSGRNorthing() const { return _osgr.northing; }
- // OLC getter
- void getOLCCode(char* code) { strncpy(code, _olc.code, OLC_CODE_LEN + 1); } // +1 for null termination
+ // OLC getter
+ void getOLCCode(char *code) { strncpy(code, _olc.code, OLC_CODE_LEN + 1); } // +1 for null termination
};
-
diff --git a/src/gps/NMEAGPS.cpp b/src/gps/NMEAGPS.cpp
index a89083c0e..0632164e9 100644
--- a/src/gps/NMEAGPS.cpp
+++ b/src/gps/NMEAGPS.cpp
@@ -1,12 +1,12 @@
-#include "configuration.h"
#include "NMEAGPS.h"
#include "RTC.h"
+#include "configuration.h"
#include
// GPS solutions older than this will be rejected - see TinyGPSDatum::age()
-#define GPS_SOL_EXPIRY_MS 5000 // in millis. give 1 second time to combine different sentences. NMEA Frequency isn't higher anyway
-#define NMEA_MSG_GXGSA "GNGSA" // GSA message (GPGSA, GNGSA etc)
+#define GPS_SOL_EXPIRY_MS 5000 // in millis. give 1 second time to combine different sentences. NMEA Frequency isn't higher anyway
+#define NMEA_MSG_GXGSA "GNGSA" // GSA message (GPGSA, GNGSA etc)
static int32_t toDegInt(RawDegrees d)
{
@@ -20,19 +20,18 @@ static int32_t toDegInt(RawDegrees d)
bool NMEAGPS::factoryReset()
{
#ifdef PIN_GPS_REINIT
- //The L76K GNSS on the T-Echo requires the RESET pin to be pulled LOW
+ // The L76K GNSS on the T-Echo requires the RESET pin to be pulled LOW
digitalWrite(PIN_GPS_REINIT, 0);
pinMode(PIN_GPS_REINIT, OUTPUT);
- delay(150); //The L76K datasheet calls for at least 100MS delay
+ delay(150); // The L76K datasheet calls for at least 100MS delay
digitalWrite(PIN_GPS_REINIT, 1);
-#endif
+#endif
// send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's UBLOX.
// Factory Reset
- byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF,
- 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
- _serial_gps->write(_message_reset,sizeof(_message_reset));
+ byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
+ _serial_gps->write(_message_reset, sizeof(_message_reset));
delay(1000);
return true;
}
@@ -40,7 +39,7 @@ bool NMEAGPS::factoryReset()
bool NMEAGPS::setupGPS()
{
GPS::setupGPS();
-
+
#ifdef PIN_GPS_PPS
// pulse per second
// FIXME - move into shared GPS code
@@ -84,8 +83,9 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
t.tm_mon = d.month() - 1;
t.tm_year = d.year() - 1900;
t.tm_isdst = false;
- if (t.tm_mon > -1){
- LOG_DEBUG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
+ if (t.tm_mon > -1) {
+ LOG_DEBUG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min,
+ t.tm_sec);
perhapsSetRTC(RTCQualityGPS, t);
return true;
} else
@@ -102,47 +102,44 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
*/
bool NMEAGPS::lookForLocation()
{
- // By default, TinyGPS++ does not parse GPGSA lines, which give us
+ // By default, TinyGPS++ does not parse GPGSA lines, which give us
// the 2D/3D fixType (see NMEAGPS.h)
// At a minimum, use the fixQuality indicator in GPGGA (FIXME?)
fixQual = reader.fixQuality();
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
- fixType = atoi(gsafixtype.value()); // will set to zero if no data
+ fixType = atoi(gsafixtype.value()); // will set to zero if no data
// LOG_DEBUG("FIX QUAL=%d, TYPE=%d\n", fixQual, fixType);
#endif
// check if GPS has an acceptable lock
- if (! hasLock())
+ if (!hasLock())
return false;
#ifdef GPS_EXTRAVERBOSE
- LOG_DEBUG("AGE: LOC=%d FIX=%d DATE=%d TIME=%d\n",
- reader.location.age(),
+ LOG_DEBUG("AGE: LOC=%d FIX=%d DATE=%d TIME=%d\n", reader.location.age(),
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
- gsafixtype.age(),
+ gsafixtype.age(),
#else
- 0,
+ 0,
#endif
- reader.date.age(), reader.time.age());
-#endif // GPS_EXTRAVERBOSE
+ reader.date.age(), reader.time.age());
+#endif // GPS_EXTRAVERBOSE
// check if a complete GPS solution set is available for reading
// tinyGPSDatum::age() also includes isValid() test
// FIXME
- if (! ((reader.location.age() < GPS_SOL_EXPIRY_MS) &&
+ if (!((reader.location.age() < GPS_SOL_EXPIRY_MS) &&
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
- (gsafixtype.age() < GPS_SOL_EXPIRY_MS) &&
+ (gsafixtype.age() < GPS_SOL_EXPIRY_MS) &&
#endif
- (reader.time.age() < GPS_SOL_EXPIRY_MS) &&
- (reader.date.age() < GPS_SOL_EXPIRY_MS)))
- {
+ (reader.time.age() < GPS_SOL_EXPIRY_MS) && (reader.date.age() < GPS_SOL_EXPIRY_MS))) {
LOG_WARN("SOME data is TOO OLD: LOC %u, TIME %u, DATE %u\n", reader.location.age(), reader.time.age(), reader.date.age());
return false;
}
// Is this a new point or are we re-reading the previous one?
- if (! reader.location.isUpdated())
+ if (!reader.location.isUpdated())
return false;
// We know the solution is fresh and valid, so just read the data
@@ -150,19 +147,19 @@ bool NMEAGPS::lookForLocation()
// Bail out EARLY to avoid overwriting previous good data (like #857)
if (toDegInt(loc.lat) > 900000000) {
-#ifdef GPS_EXTRAVERBOSE
- LOG_DEBUG("Bail out EARLY on LAT %i\n",toDegInt(loc.lat));
+#ifdef GPS_EXTRAVERBOSE
+ LOG_DEBUG("Bail out EARLY on LAT %i\n", toDegInt(loc.lat));
#endif
return false;
}
if (toDegInt(loc.lng) > 1800000000) {
-#ifdef GPS_EXTRAVERBOSE
- LOG_DEBUG("Bail out EARLY on LNG %i\n",toDegInt(loc.lng));
+#ifdef GPS_EXTRAVERBOSE
+ LOG_DEBUG("Bail out EARLY on LNG %i\n", toDegInt(loc.lng));
#endif
return false;
}
- p.location_source = Position_LocSource_LOC_INTERNAL;
+ p.location_source = meshtastic_Position_LocSource_LOC_INTERNAL;
// Dilution of precision (an accuracy metric) is reported in 10^2 units, so we need to scale down when we use it
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
@@ -209,11 +206,11 @@ bool NMEAGPS::lookForLocation()
}
if (reader.course.isUpdated() && reader.course.isValid()) {
- if (reader.course.value() < 36000) { // sanity check
- p.ground_track = reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5
+ if (reader.course.value() < 36000) { // sanity check
+ p.ground_track =
+ reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5
} else {
- LOG_WARN("BOGUS course.value() REJECTED: %d\n",
- reader.course.value());
+ LOG_WARN("BOGUS course.value() REJECTED: %d\n", reader.course.value());
}
}
@@ -224,14 +221,13 @@ bool NMEAGPS::lookForLocation()
return true;
}
-
bool NMEAGPS::hasLock()
{
// Using GPGGA fix quality indicator
if (fixQual >= 1 && fixQual <= 5) {
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
// Use GPGSA fix type 2D/3D (better) if available
- if (fixType == 3 || fixType == 0) // zero means "no data received"
+ if (fixType == 3 || fixType == 0) // zero means "no data received"
#endif
return true;
}
diff --git a/src/gps/NMEAGPS.h b/src/gps/NMEAGPS.h
index c97be08ce..82e691717 100644
--- a/src/gps/NMEAGPS.h
+++ b/src/gps/NMEAGPS.h
@@ -12,14 +12,14 @@
class NMEAGPS : public GPS
{
TinyGPSPlus reader;
- uint8_t fixQual = 0; // fix quality from GPGGA
+ uint8_t fixQual = 0; // fix quality from GPGGA
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
// (20210908) TinyGps++ can only read the GPGSA "FIX TYPE" field
// via optional feature "custom fields", currently disabled (bug #525)
- TinyGPSCustom gsafixtype; // custom extract fix type from GPGSA
- TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA
- uint8_t fixType = 0; // fix type from GPGSA
+ TinyGPSCustom gsafixtype; // custom extract fix type from GPGSA
+ TinyGPSCustom gsapdop; // custom extract PDOP from GPGSA
+ uint8_t fixType = 0; // fix type from GPGSA
#endif
public:
@@ -29,9 +29,9 @@ class NMEAGPS : public GPS
protected:
/** Subclasses should look for serial rx characters here and feed it to their GPS parser
- *
+ *
* Return true if we received a valid message from the GPS
- */
+ */
virtual bool whileIdle() override;
/**
diff --git a/src/gps/NMEAWPL.cpp b/src/gps/NMEAWPL.cpp
index 70812e87b..6ab2c85bf 100644
--- a/src/gps/NMEAWPL.cpp
+++ b/src/gps/NMEAWPL.cpp
@@ -16,22 +16,18 @@
* -------------------------------------------
*/
-uint32_t printWPL(char *buf, const Position &pos, const char *name)
+uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const char *name)
{
- GeoCoord geoCoord(pos.latitude_i,pos.longitude_i,pos.altitude);
- uint32_t len = sprintf(buf, "$GNWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s",
- geoCoord.getDMSLatDeg(),
- (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6,
- geoCoord.getDMSLatCP(),
- geoCoord.getDMSLonDeg(),
- (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
- geoCoord.getDMSLonCP(),
- name);
+ GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude);
+ uint32_t len = snprintf(buf, bufsz, "$GNWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s", geoCoord.getDMSLatDeg(),
+ (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(),
+ geoCoord.getDMSLonDeg(), (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
+ geoCoord.getDMSLonCP(), name);
uint32_t chk = 0;
for (uint32_t i = 1; i < len; i++) {
chk ^= buf[i];
}
- len += sprintf(buf + len, "*%02X\r\n", chk);
+ len += snprintf(buf + len, bufsz - len, "*%02X\r\n", chk);
return len;
}
@@ -51,40 +47,26 @@ uint32_t printWPL(char *buf, const Position &pos, const char *name)
* 8 Horizontal Dilution of precision (meters)
* 9 Antenna Altitude above/below mean-sea-level (geoid) (in meters)
* 10 Units of antenna altitude, meters
- * 11 Geoidal separation, the difference between the WGS-84 earth ellipsoid and mean-sea-level (geoid), "-" means mean-sea-level below ellipsoid
- * 12 Units of geoidal separation, meters
- * 13 Age of differential GPS data, time in seconds since last SC104 type 1 or 9 update, null field when DGPS is not used
- * 14 Differential reference station ID, 0000-1023
- * 15 Checksum
+ * 11 Geoidal separation, the difference between the WGS-84 earth ellipsoid and mean-sea-level (geoid), "-" means mean-sea-level
+ * below ellipsoid 12 Units of geoidal separation, meters 13 Age of differential GPS data, time in seconds since last SC104 type 1
+ * or 9 update, null field when DGPS is not used 14 Differential reference station ID, 0000-1023 15 Checksum
* -------------------------------------------
*/
-uint32_t printGGA(char *buf, const Position &pos)
+uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos)
{
- GeoCoord geoCoord(pos.latitude_i,pos.longitude_i,pos.altitude);
- uint32_t len = sprintf(buf, "$GNGGA,%06u.%03u,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d",
- pos.time / 1000,
- pos.time % 1000,
- geoCoord.getDMSLatDeg(),
- (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6,
- geoCoord.getDMSLatCP(),
- geoCoord.getDMSLonDeg(),
- (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
- geoCoord.getDMSLonCP(),
- pos.fix_type,
- pos.sats_in_view,
- pos.HDOP,
- geoCoord.getAltitude(),
- 'M',
- pos.altitude_geoidal_separation,
- 'M',
- 0,
- 0);
+ GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude);
+ uint32_t len =
+ snprintf(buf, bufsz, "$GNGGA,%06u.%03u,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", pos.time / 1000,
+ pos.time % 1000, geoCoord.getDMSLatDeg(), (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6,
+ geoCoord.getDMSLatCP(), geoCoord.getDMSLonDeg(),
+ (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), pos.fix_type,
+ pos.sats_in_view, pos.HDOP, geoCoord.getAltitude(), 'M', pos.altitude_geoidal_separation, 'M', 0, 0);
uint32_t chk = 0;
for (uint32_t i = 1; i < len; i++) {
chk ^= buf[i];
}
- len += sprintf(buf + len, "*%02X\r\n", chk);
+ len += snprintf(buf + len, bufsz - len, "*%02X\r\n", chk);
return len;
}
\ No newline at end of file
diff --git a/src/gps/NMEAWPL.h b/src/gps/NMEAWPL.h
index aaa18933c..a9f00cb14 100644
--- a/src/gps/NMEAWPL.h
+++ b/src/gps/NMEAWPL.h
@@ -1,7 +1,7 @@
#pragma once
-#include
#include "main.h"
+#include
-uint32_t printWPL(char *buf, const Position &pos, const char *name);
-uint32_t printGGA(char *buf, const Position &pos);
+uint32_t printWPL(char *buf, size_t bufsz, const meshtastic_Position &pos, const char *name);
+uint32_t printGGA(char *buf, size_t bufsz, const meshtastic_Position &pos);
diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp
index e61991917..2e25949af 100644
--- a/src/gps/RTC.cpp
+++ b/src/gps/RTC.cpp
@@ -20,7 +20,7 @@ void readFromRTC()
{
struct timeval tv; /* btw settimeofday() is helpfull here too*/
#ifdef RV3028_RTC
- if(rtc_found == RV3028_RTC) {
+ if (rtc_found == RV3028_RTC) {
uint32_t now = millis();
Melopero_RV3028 rtc;
rtc.initI2C();
@@ -41,7 +41,7 @@ void readFromRTC()
}
}
#elif defined(PCF8563_RTC)
- if(rtc_found == PCF8563_RTC) {
+ if (rtc_found == PCF8563_RTC) {
uint32_t now = millis();
PCF8563_Class rtc;
#ifdef RTC_USE_WIRE1
@@ -66,7 +66,7 @@ void readFromRTC()
currentQuality = RTCQualityDevice;
}
}
-#else
+#else
if (!gettimeofday(&tv, NULL)) {
uint32_t now = millis();
LOG_DEBUG("Read RTC time as %ld\n", tv.tv_sec);
@@ -87,12 +87,11 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
currentQuality = q;
shouldSet = true;
LOG_DEBUG("Upgrading time to RTC %ld secs (quality %d)\n", tv->tv_sec, q);
- } else if(q == RTCQualityGPS && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) {
+ } else if (q == RTCQualityGPS && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) {
// Every 12 hrs we will slam in a new GPS time, to correct for local RTC clock drift
shouldSet = true;
LOG_DEBUG("Reapplying external time to correct clock drift %ld secs\n", tv->tv_sec);
- }
- else
+ } else
shouldSet = false;
if (shouldSet) {
@@ -104,24 +103,26 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
// If this platform has a setable RTC, set it
#ifdef RV3028_RTC
- if(rtc_found == RV3028_RTC) {
+ if (rtc_found == RV3028_RTC) {
Melopero_RV3028 rtc;
rtc.initI2C();
tm *t = localtime(&tv->tv_sec);
rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
- LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
+ LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
+ t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
}
#elif defined(PCF8563_RTC)
- if(rtc_found == PCF8563_RTC) {
+ if (rtc_found == PCF8563_RTC) {
PCF8563_Class rtc;
#ifdef RTC_USE_WIRE1
- rtc.begin(Wire1);
+ rtc.begin(Wire1);
#else
- rtc.begin();
+ rtc.begin();
#endif
tm *t = localtime(&tv->tv_sec);
rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
- LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
+ LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
+ t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
}
#elif defined(ARCH_ESP32)
settimeofday(tv, NULL);
@@ -160,7 +161,7 @@ bool perhapsSetRTC(RTCQuality q, struct tm &t)
uint32_t getTime()
{
- return (((uint32_t) millis() - timeStartMsec) / 1000) + zeroOffsetSecs;
+ return (((uint32_t)millis() - timeStartMsec) / 1000) + zeroOffsetSecs;
}
uint32_t getValidTime(RTCQuality minQuality)
diff --git a/src/graphics/EInkDisplay2.cpp b/src/graphics/EInkDisplay2.cpp
index 07fcd2c46..f9d99ab7e 100644
--- a/src/graphics/EInkDisplay2.cpp
+++ b/src/graphics/EInkDisplay2.cpp
@@ -1,11 +1,11 @@
#include "configuration.h"
#ifdef USE_EINK
-#include "main.h"
#include "EInkDisplay2.h"
-#include "SPILock.h"
-#include
#include "GxEPD2_BW.h"
+#include "SPILock.h"
+#include "main.h"
+#include
#define COLORED GxEPD_BLACK
#define UNCOLORED GxEPD_WHITE
@@ -14,62 +14,63 @@
#define TECHO_DISPLAY_MODEL GxEPD2_154_D67
#elif defined(RAK4630)
-//GxEPD2_213_BN - RAK14000 2.13 inch b/w 250x122 - changed from GxEPD2_213_B74 - which was not going to give partial update support
+// GxEPD2_213_BN - RAK14000 2.13 inch b/w 250x122 - changed from GxEPD2_213_B74 - which was not going to give partial update
+// support
#define TECHO_DISPLAY_MODEL GxEPD2_213_BN
-//4.2 inch 300x400 - GxEPD2_420_M01
+// 4.2 inch 300x400 - GxEPD2_420_M01
//#define TECHO_DISPLAY_MODEL GxEPD2_420_M01
-//2.9 inch 296x128 - GxEPD2_290_T5D
+// 2.9 inch 296x128 - GxEPD2_290_T5D
//#define TECHO_DISPLAY_MODEL GxEPD2_290_T5D
-//1.54 inch 200x200 - GxEPD2_154_M09
+// 1.54 inch 200x200 - GxEPD2_154_M09
//#define TECHO_DISPLAY_MODEL GxEPD2_154_M09
#elif defined(PCA10059)
-//4.2 inch 300x400 - GxEPD2_420_M01
+// 4.2 inch 300x400 - GxEPD2_420_M01
#define TECHO_DISPLAY_MODEL GxEPD2_420_M01
#elif defined(M5_COREINK)
-//M5Stack CoreInk
-//1.54 inch 200x200 - GxEPD2_154_M09
+// M5Stack CoreInk
+// 1.54 inch 200x200 - GxEPD2_154_M09
#define TECHO_DISPLAY_MODEL GxEPD2_154_M09
#endif
GxEPD2_BW *adafruitDisplay;
-EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl)
+EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl, uint8_t screen_model)
{
- #if defined(TTGO_T_ECHO)
+#if defined(TTGO_T_ECHO)
setGeometry(GEOMETRY_RAWMODE, TECHO_DISPLAY_MODEL::WIDTH, TECHO_DISPLAY_MODEL::HEIGHT);
- #elif defined(RAK4630)
-
- //GxEPD2_213_BN - RAK14000 2.13 inch b/w 250x122
+#elif defined(RAK4630)
+
+ // GxEPD2_213_BN - RAK14000 2.13 inch b/w 250x122
setGeometry(GEOMETRY_RAWMODE, 250, 122);
- //GxEPD2_420_M01
- //setGeometry(GEOMETRY_RAWMODE, 300, 400);
+ // GxEPD2_420_M01
+ // setGeometry(GEOMETRY_RAWMODE, 300, 400);
- //GxEPD2_290_T5D
- //setGeometry(GEOMETRY_RAWMODE, 296, 128);
+ // GxEPD2_290_T5D
+ // setGeometry(GEOMETRY_RAWMODE, 296, 128);
- //GxEPD2_154_M09
- //setGeometry(GEOMETRY_RAWMODE, 200, 200);
-
- #elif defined(PCA10059)
+ // GxEPD2_154_M09
+ // setGeometry(GEOMETRY_RAWMODE, 200, 200);
- //GxEPD2_420_M01
+#elif defined(PCA10059)
+
+ // GxEPD2_420_M01
setGeometry(GEOMETRY_RAWMODE, 300, 400);
-
- #elif defined(M5_COREINK)
-
- //M5Stack_CoreInk 200x200
- //1.54 inch 200x200 - GxEPD2_154_M09
+
+#elif defined(M5_COREINK)
+
+ // M5Stack_CoreInk 200x200
+ // 1.54 inch 200x200 - GxEPD2_154_M09
setGeometry(GEOMETRY_RAWMODE, EPD_HEIGHT, EPD_WIDTH);
- #endif
+#endif
// setGeometry(GEOMETRY_RAWMODE, 128, 64); // old resolution
// setGeometry(GEOMETRY_128_64); // We originally used this because I wasn't sure if rawmode worked - it does
}
@@ -104,28 +105,28 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit)
}
LOG_DEBUG("Updating E-Paper... ");
-
- #if defined(TTGO_T_ECHO)
+
+#if defined(TTGO_T_ECHO)
// ePaper.Reset(); // wake the screen from sleep
adafruitDisplay->display(false); // FIXME, use partial update mode
- #elif defined(RAK4630)
-
- //RAK14000 2.13 inch b/w 250x122 actually now does support partial updates
-
- //Full update mode (slow)
- //adafruitDisplay->display(false); // FIXME, use partial update mode
-
- //Only enable for e-Paper with support for partial updates and comment out above adafruitDisplay->display(false);
- // 1.54 inch 200x200 - GxEPD2_154_M09
- // 2.13 inch 250x122 - GxEPD2_213_BN
- // 2.9 inch 296x128 - GxEPD2_290_T5D
- // 4.2 inch 300x400 - GxEPD2_420_M01
+#elif defined(RAK4630)
+
+ // RAK14000 2.13 inch b/w 250x122 actually now does support partial updates
+
+ // Full update mode (slow)
+ // adafruitDisplay->display(false); // FIXME, use partial update mode
+
+ // Only enable for e-Paper with support for partial updates and comment out above adafruitDisplay->display(false);
+ // 1.54 inch 200x200 - GxEPD2_154_M09
+ // 2.13 inch 250x122 - GxEPD2_213_BN
+ // 2.9 inch 296x128 - GxEPD2_290_T5D
+ // 4.2 inch 300x400 - GxEPD2_420_M01
adafruitDisplay->nextPage();
-
- #elif defined(PCA10059) || defined(M5_COREINK)
+
+#elif defined(PCA10059) || defined(M5_COREINK)
adafruitDisplay->nextPage();
- #endif
-
+#endif
+
// Put screen to sleep to save power (possibly not necessary because we already did poweroff inside of display)
adafruitDisplay->hibernate();
LOG_DEBUG("done\n");
@@ -175,41 +176,40 @@ bool EInkDisplay::connect()
pinMode(PIN_EINK_EN, OUTPUT);
#endif
-
#if defined(TTGO_T_ECHO)
-{
- auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY, SPI1);
-
- adafruitDisplay = new GxEPD2_BW(*lowLevel);
- adafruitDisplay->init();
- adafruitDisplay->setRotation(3);
-}
-#elif defined(RAK4630)
-{
- if (eink_found) {
- auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
+ {
+ auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY, SPI1);
adafruitDisplay = new GxEPD2_BW(*lowLevel);
-
- adafruitDisplay->init(115200, true, 10, false, SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));
-
- //RAK14000 2.13 inch b/w 250x122 does actually now support partial updates
+ adafruitDisplay->init();
adafruitDisplay->setRotation(3);
- //Partial update support for 1.54, 2.13 RAK14000 b/w , 2.9 and 4.2
- //adafruitDisplay->setRotation(1);
- adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
- } else {
- (void)adafruitDisplay;
- }
-}
+ }
+#elif defined(RAK4630)
+ {
+ if (eink_found) {
+ auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
+
+ adafruitDisplay = new GxEPD2_BW(*lowLevel);
+
+ adafruitDisplay->init(115200, true, 10, false, SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));
+
+ // RAK14000 2.13 inch b/w 250x122 does actually now support partial updates
+ adafruitDisplay->setRotation(3);
+ // Partial update support for 1.54, 2.13 RAK14000 b/w , 2.9 and 4.2
+ // adafruitDisplay->setRotation(1);
+ adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
+ } else {
+ (void)adafruitDisplay;
+ }
+ }
#elif defined(PCA10059)
-{
- auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
- adafruitDisplay = new GxEPD2_BW(*lowLevel);
- adafruitDisplay->init(115200, true, 10, false, SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));
- adafruitDisplay->setRotation(3);
- adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
-}
+ {
+ auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
+ adafruitDisplay = new GxEPD2_BW(*lowLevel);
+ adafruitDisplay->init(115200, true, 10, false, SPI1, SPISettings(4000000, MSBFIRST, SPI_MODE0));
+ adafruitDisplay->setRotation(3);
+ adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
+ }
#elif defined(M5_COREINK)
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
adafruitDisplay = new GxEPD2_BW(*lowLevel);
@@ -217,12 +217,11 @@ bool EInkDisplay::connect()
adafruitDisplay->setRotation(0);
adafruitDisplay->setPartialWindow(0, 0, EPD_WIDTH, EPD_HEIGHT);
#endif
-
-
- //adafruitDisplay->setFullWindow();
- //adafruitDisplay->fillScreen(UNCOLORED);
- //adafruitDisplay->drawCircle(100, 100, 20, COLORED);
- //adafruitDisplay->display(false);
+
+ // adafruitDisplay->setFullWindow();
+ // adafruitDisplay->fillScreen(UNCOLORED);
+ // adafruitDisplay->drawCircle(100, 100, 20, COLORED);
+ // adafruitDisplay->display(false);
return true;
}
diff --git a/src/graphics/EInkDisplay2.h b/src/graphics/EInkDisplay2.h
index 727132d0e..7d56c8022 100644
--- a/src/graphics/EInkDisplay2.h
+++ b/src/graphics/EInkDisplay2.h
@@ -17,26 +17,26 @@ class EInkDisplay : public OLEDDisplay
/// How often should we update the display
/// thereafter we do once per 5 minutes
uint32_t slowUpdateMsec = 5 * 60 * 1000;
-
+
public:
/* constructor
FIXME - the parameters are not used, just a temporary hack to keep working like the old displays
*/
- EInkDisplay(uint8_t address, int sda, int scl);
+ EInkDisplay(uint8_t address, int sda, int scl, uint8_t screen_model);
// Write the buffer to the display memory (for eink we only do this occasionally)
virtual void display(void) override;
/**
* Force a display update if we haven't drawn within the specified msecLimit
- *
+ *
* @return true if we did draw the screen
*/
bool forceDisplay(uint32_t msecLimit = 1000);
/**
* shim to make the abstraction happy
- *
+ *
*/
void setDetected(uint8_t detected);
@@ -50,5 +50,3 @@ class EInkDisplay : public OLEDDisplay
// Connect to the display
virtual bool connect() override;
};
-
-
diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp
index 53ca75a51..ed5e1c3a0 100644
--- a/src/graphics/Screen.cpp
+++ b/src/graphics/Screen.cpp
@@ -33,9 +33,9 @@ along with this program. If not, see .
#include "main.h"
#include "mesh-pb-constants.h"
#include "mesh/Channels.h"
-#include "mesh/generated/deviceonly.pb.h"
-#include "modules/TextMessageModule.h"
+#include "mesh/generated/meshtastic/deviceonly.pb.h"
#include "modules/ExternalNotificationModule.h"
+#include "modules/TextMessageModule.h"
#include "sleep.h"
#include "target_specific.h"
#include "utils.h"
@@ -69,7 +69,7 @@ static uint32_t targetFramerate = IDLE_FRAMERATE;
static char btPIN[16] = "888888";
uint32_t logo_timeout = 5000; // 4 seconds for EACH logo
-
+
// This image definition is here instead of images.h because it's modified dynamically by the drawBattery function
uint8_t imgBattery[16] = {0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xE7, 0x3C};
@@ -97,9 +97,9 @@ static uint16_t displayWidth, displayHeight;
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
// The screen is bigger so use bigger fonts
-#define FONT_SMALL ArialMT_Plain_16 // Height: 19
+#define FONT_SMALL ArialMT_Plain_16 // Height: 19
#define FONT_MEDIUM ArialMT_Plain_24 // Height: 28
-#define FONT_LARGE ArialMT_Plain_24 // Height: 28
+#define FONT_LARGE ArialMT_Plain_24 // Height: 28
#else
#ifdef OLED_RU
#define FONT_SMALL ArialMT_Plain_10_RU
@@ -107,7 +107,7 @@ static uint16_t displayWidth, displayHeight;
#define FONT_SMALL ArialMT_Plain_10 // Height: 13
#endif
#define FONT_MEDIUM ArialMT_Plain_16 // Height: 19
-#define FONT_LARGE ArialMT_Plain_24 // Height: 28
+#define FONT_LARGE ArialMT_Plain_24 // Height: 28
#endif
#define fontHeight(font) ((font)[1] + 1) // height is position 1
@@ -118,7 +118,6 @@ static uint16_t displayWidth, displayHeight;
#define getStringCenteredX(s) ((SCREEN_WIDTH - display->getStringWidth(s)) / 2)
-
/**
* Draw the icon with extra info printed around the corners
*/
@@ -236,7 +235,7 @@ static void drawWelcomeScreen(OLEDDisplay *display, OLEDDisplayUiState *state, i
display->drawString(64 + x, y, "//\\ E S H T /\\ S T / C");
display->drawString(64 + x, y + FONT_HEIGHT_SMALL, getDeviceName());
display->setTextAlignment(TEXT_ALIGN_LEFT);
-
+
if ((millis() / 10000) % 2) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 2 - 3, "Set the region using the");
display->drawString(x, y + FONT_HEIGHT_SMALL * 3 - 3, "Meshtastic Android, iOS,");
@@ -292,7 +291,7 @@ static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state,
display->drawString(x_offset + x, y_offset + y, "Bluetooth");
display->setFont(FONT_SMALL);
- y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_MEDIUM -4 : y_offset + FONT_HEIGHT_MEDIUM + 5;
+ y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_MEDIUM - 4 : y_offset + FONT_HEIGHT_MEDIUM + 5;
display->drawString(x_offset + x, y_offset + y, "Enter this code");
display->setFont(FONT_LARGE);
@@ -302,7 +301,7 @@ static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state,
display->drawString(x_offset + x, y_offset + y, pin);
display->setFont(FONT_SMALL);
- String deviceName = "Name: ";
+ String deviceName = "Name: ";
deviceName.concat(getDeviceName());
y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_LARGE - 6 : y_offset + FONT_HEIGHT_LARGE + 5;
display->drawString(x_offset + x, y_offset + y, deviceName);
@@ -332,7 +331,8 @@ static void drawFrameFirmware(OLEDDisplay *display, OLEDDisplayUiState *state, i
display->setFont(FONT_SMALL);
display->setTextAlignment(TEXT_ALIGN_LEFT);
- display->drawStringMaxWidth(0 + x, 2 + y + FONT_HEIGHT_SMALL *2, x + display->getWidth(), "Please be patient and do not power off.");
+ display->drawStringMaxWidth(0 + x, 2 + y + FONT_HEIGHT_SMALL * 2, x + display->getWidth(),
+ "Please be patient and do not power off.");
}
/// Draw the last text message we received
@@ -352,10 +352,9 @@ static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *sta
}
// Ignore messages orginating from phone (from the current node 0x0) unless range test or store and forward module are enabled
-static bool shouldDrawMessage(const MeshPacket *packet)
+static bool shouldDrawMessage(const meshtastic_MeshPacket *packet)
{
- return packet->from != 0 && !moduleConfig.range_test.enabled &&
- !moduleConfig.store_forward.enabled;
+ return packet->from != 0 && !moduleConfig.range_test.enabled && !moduleConfig.store_forward.enabled;
}
/// Draw the last text message we received
@@ -366,8 +365,8 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
// the max length of this buffer is much longer than we can possibly print
static char tempBuf[237];
- MeshPacket &mp = devicestate.rx_text_message;
- NodeInfo *node = nodeDB.getNode(getFrom(&mp));
+ meshtastic_MeshPacket &mp = devicestate.rx_text_message;
+ meshtastic_NodeInfo *node = nodeDB.getNode(getFrom(&mp));
// LOG_DEBUG("drawing text message from 0x%x: %s\n", mp.from,
// mp.decoded.variant.data.decoded.bytes);
@@ -376,14 +375,20 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state
// be wrapped. Currently only spaces and "-" are allowed for wrapping
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL);
- if (config.display.displaymode == Config_DisplayConfig_DisplayMode_INVERTED) {
+ if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
display->setColor(BLACK);
}
- display->drawStringf(0 + x, 0 + y, tempBuf, "From: %s", (node && node->has_user) ? node->user.short_name : "???");
- if(config.display.heading_bold) {
- display->drawStringf(1 + x, 0 + y, tempBuf, "From: %s", (node && node->has_user) ? node->user.short_name : "???");
+
+ tm *tm = localtime(reinterpret_cast(&mp.rx_time));
+
+ if (config.display.heading_bold) {
+ display->drawStringf(1 + x, 0 + y, tempBuf, "[%02d:%02d:%02d] From: %s", tm->tm_hour, tm->tm_min, tm->tm_sec,
+ (node && node->has_user) ? node->user.short_name : "???");
}
+ display->drawStringf(0 + x, 0 + y, tempBuf, "[%02d:%02d:%02d] From: %s", tm->tm_hour, tm->tm_min, tm->tm_sec,
+ (node && node->has_user) ? node->user.short_name : "???");
+
display->setColor(WHITE);
snprintf(tempBuf, sizeof(tempBuf), "%s", mp.decoded.payload.bytes);
display->drawStringMaxWidth(0 + x, 0 + y + FONT_HEIGHT_SMALL, x + display->getWidth(), tempBuf);
@@ -470,14 +475,14 @@ static void drawBattery(OLEDDisplay *display, int16_t x, int16_t y, uint8_t *img
static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, NodeStatus *nodeStatus)
{
char usersString[20];
- sprintf(usersString, "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
+ snprintf(usersString, sizeof(usersString), "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
display->drawFastImage(x, y + 3, 8, 8, imgUser);
#else
display->drawFastImage(x, y, 8, 8, imgUser);
#endif
display->drawString(x + 10, y - 2, usersString);
- if(config.display.heading_bold)
+ if (config.display.heading_bold)
display->drawString(x + 11, y - 2, usersString);
}
@@ -487,20 +492,20 @@ static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus
if (config.position.fixed_position) {
// GPS coordinates are currently fixed
display->drawString(x - 1, y - 2, "Fixed GPS");
- if(config.display.heading_bold)
+ if (config.display.heading_bold)
display->drawString(x, y - 2, "Fixed GPS");
return;
}
if (!gps->getIsConnected()) {
display->drawString(x, y - 2, "No GPS");
- if(config.display.heading_bold)
+ if (config.display.heading_bold)
display->drawString(x + 1, y - 2, "No GPS");
return;
}
display->drawFastImage(x, y, 6, 8, gps->getHasLock() ? imgPositionSolid : imgPositionEmpty);
if (!gps->getHasLock()) {
display->drawString(x + 8, y - 2, "No sats");
- if(config.display.heading_bold)
+ if (config.display.heading_bold)
display->drawString(x + 9, y - 2, "No sats");
return;
} else {
@@ -521,26 +526,26 @@ static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus
display->drawFastImage(x + 24, y, 8, 8, imgSatellite);
// Draw the number of satellites
- sprintf(satsString, "%u", gps->getNumSatellites());
+ snprintf(satsString, sizeof(satsString), "%u", gps->getNumSatellites());
display->drawString(x + 34, y - 2, satsString);
- if(config.display.heading_bold)
+ if (config.display.heading_bold)
display->drawString(x + 35, y - 2, satsString);
}
}
-//Draw status when gps is disabled by PMU
+// Draw status when gps is disabled by PMU
static void drawGPSpowerstat(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
{
-#ifdef HAS_PMU
+#ifdef HAS_PMU
String displayLine = "GPS disabled";
int16_t xPos = display->getStringWidth(displayLine);
- if (!config.position.gps_enabled){
+ if (!config.position.gps_enabled) {
display->drawString(x + xPos, y, displayLine);
-#ifdef GPS_POWER_TOGGLE
+#ifdef GPS_POWER_TOGGLE
display->drawString(x + xPos, y - 2 + FONT_HEIGHT_SMALL, " by button");
#endif
- //display->drawString(x + xPos, y + 2, displayLine);
+ // display->drawString(x + xPos, y + 2, displayLine);
}
#endif
}
@@ -557,7 +562,7 @@ static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GP
} else {
geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude()));
displayLine = "Altitude: " + String(geoCoord.getAltitude()) + "m";
- if (config.display.units == Config_DisplayConfig_DisplayUnits_IMPERIAL)
+ if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL)
displayLine = "Altitude: " + String(geoCoord.getAltitude() * METERS_TO_FEET) + "ft";
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
}
@@ -579,25 +584,26 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const
geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude()));
- if (gpsFormat != Config_DisplayConfig_GpsCoordinateFormat_DMS) {
+ if (gpsFormat != meshtastic_Config_DisplayConfig_GpsCoordinateFormat_DMS) {
char coordinateLine[22];
- if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_DEC) { // Decimal Degrees
- sprintf(coordinateLine, "%f %f", geoCoord.getLatitude() * 1e-7, geoCoord.getLongitude() * 1e-7);
- } else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_UTM) { // Universal Transverse Mercator
- sprintf(coordinateLine, "%2i%1c %06u %07u", geoCoord.getUTMZone(), geoCoord.getUTMBand(),
- geoCoord.getUTMEasting(), geoCoord.getUTMNorthing());
- } else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_MGRS) { // Military Grid Reference System
- sprintf(coordinateLine, "%2i%1c %1c%1c %05u %05u", geoCoord.getMGRSZone(), geoCoord.getMGRSBand(),
- geoCoord.getMGRSEast100k(), geoCoord.getMGRSNorth100k(), geoCoord.getMGRSEasting(),
- geoCoord.getMGRSNorthing());
- } else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_OLC) { // Open Location Code
+ if (gpsFormat == meshtastic_Config_DisplayConfig_GpsCoordinateFormat_DEC) { // Decimal Degrees
+ snprintf(coordinateLine, sizeof(coordinateLine), "%f %f", geoCoord.getLatitude() * 1e-7,
+ geoCoord.getLongitude() * 1e-7);
+ } else if (gpsFormat == meshtastic_Config_DisplayConfig_GpsCoordinateFormat_UTM) { // Universal Transverse Mercator
+ snprintf(coordinateLine, sizeof(coordinateLine), "%2i%1c %06u %07u", geoCoord.getUTMZone(), geoCoord.getUTMBand(),
+ geoCoord.getUTMEasting(), geoCoord.getUTMNorthing());
+ } else if (gpsFormat == meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MGRS) { // Military Grid Reference System
+ snprintf(coordinateLine, sizeof(coordinateLine), "%2i%1c %1c%1c %05u %05u", geoCoord.getMGRSZone(),
+ geoCoord.getMGRSBand(), geoCoord.getMGRSEast100k(), geoCoord.getMGRSNorth100k(),
+ geoCoord.getMGRSEasting(), geoCoord.getMGRSNorthing());
+ } else if (gpsFormat == meshtastic_Config_DisplayConfig_GpsCoordinateFormat_OLC) { // Open Location Code
geoCoord.getOLCCode(coordinateLine);
- } else if (gpsFormat == Config_DisplayConfig_GpsCoordinateFormat_OSGR) { // Ordnance Survey Grid Reference
+ } else if (gpsFormat == meshtastic_Config_DisplayConfig_GpsCoordinateFormat_OSGR) { // Ordnance Survey Grid Reference
if (geoCoord.getOSGRE100k() == 'I' || geoCoord.getOSGRN100k() == 'I') // OSGR is only valid around the UK region
- sprintf(coordinateLine, "%s", "Out of Boundary");
+ snprintf(coordinateLine, sizeof(coordinateLine), "%s", "Out of Boundary");
else
- sprintf(coordinateLine, "%1c%1c %05u %05u", geoCoord.getOSGRE100k(), geoCoord.getOSGRN100k(),
- geoCoord.getOSGREasting(), geoCoord.getOSGRNorthing());
+ snprintf(coordinateLine, sizeof(coordinateLine), "%1c%1c %05u %05u", geoCoord.getOSGRE100k(),
+ geoCoord.getOSGRN100k(), geoCoord.getOSGREasting(), geoCoord.getOSGRNorthing());
}
// If fixed position, display text "Fixed GPS" alternating with the coordinates.
@@ -610,14 +616,13 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const
} else {
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(coordinateLine))) / 2, y, coordinateLine);
}
-
} else {
char latLine[22];
char lonLine[22];
- sprintf(latLine, "%2i° %2i' %2u\" %1c", geoCoord.getDMSLatDeg(), geoCoord.getDMSLatMin(), geoCoord.getDMSLatSec(),
- geoCoord.getDMSLatCP());
- sprintf(lonLine, "%3i° %2i' %2u\" %1c", geoCoord.getDMSLonDeg(), geoCoord.getDMSLonMin(), geoCoord.getDMSLonSec(),
- geoCoord.getDMSLonCP());
+ snprintf(latLine, sizeof(latLine), "%2i° %2i' %2u\" %1c", geoCoord.getDMSLatDeg(), geoCoord.getDMSLatMin(),
+ geoCoord.getDMSLatSec(), geoCoord.getDMSLatCP());
+ snprintf(lonLine, sizeof(lonLine), "%3i° %2i' %2u\" %1c", geoCoord.getDMSLonDeg(), geoCoord.getDMSLonMin(),
+ geoCoord.getDMSLonSec(), geoCoord.getDMSLonCP());
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(latLine))) / 2, y - FONT_HEIGHT_SMALL * 1, latLine);
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(lonLine))) / 2, y, lonLine);
}
@@ -653,8 +658,8 @@ class Point
void scale(float f)
{
- //We use -f here to counter the flip that happens
- //on the y axis when drawing and rotating on screen
+ // We use -f here to counter the flip that happens
+ // on the y axis when drawing and rotating on screen
x *= f;
y *= -f;
}
@@ -699,7 +704,7 @@ static float estimatedHeading(double lat, double lon)
/// Sometimes we will have Position objects that only have a time, so check for
/// valid lat/lon
-static bool hasPosition(NodeInfo *n)
+static bool hasPosition(meshtastic_NodeInfo *n)
{
return n->has_position && (n->position.latitude_i != 0 || n->position.longitude_i != 0);
}
@@ -709,11 +714,11 @@ static uint16_t getCompassDiam(OLEDDisplay *display)
uint16_t diam = 0;
uint16_t offset = 0;
- if (config.display.displaymode != Config_DisplayConfig_DisplayMode_DEFAULT)
+ if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT)
offset = FONT_HEIGHT_SMALL;
// get the smaller of the 2 dimensions and subtract 20
- if(display->getWidth() > (display->getHeight() - offset)) {
+ if (display->getWidth() > (display->getHeight() - offset)) {
diam = display->getHeight() - offset;
// if 2/3 of the other size would be smaller, use that
if (diam > (display->getWidth() * 2 / 3)) {
@@ -725,7 +730,7 @@ static uint16_t getCompassDiam(OLEDDisplay *display)
diam = (display->getHeight() - offset) * 2 / 3;
}
}
-
+
return diam - 20;
};
@@ -756,10 +761,10 @@ static void drawNodeHeading(OLEDDisplay *display, int16_t compassX, int16_t comp
// Draw north
static void drawCompassNorth(OLEDDisplay *display, int16_t compassX, int16_t compassY, float myHeading)
{
- //If north is supposed to be at the top of the compass we want rotation to be +0
- if(config.display.compass_north_top)
+ // If north is supposed to be at the top of the compass we want rotation to be +0
+ if (config.display.compass_north_top)
myHeading = -0;
-
+
Point N1(-0.04f, 0.65f), N2(0.04f, 0.65f);
Point N3(-0.04f, 0.55f), N4(0.04f, 0.55f);
Point *rosePoints[] = {&N1, &N2, &N3, &N4};
@@ -786,7 +791,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
prevFrame = state->currentFrame;
nodeIndex = (nodeIndex + 1) % nodeDB.getNumNodes();
- NodeInfo *n = nodeDB.getNodeByIndex(nodeIndex);
+ meshtastic_NodeInfo *n = nodeDB.getNodeByIndex(nodeIndex);
if (n->num == nodeDB.getNodeNum()) {
// Don't show our node, just skip to next
nodeIndex = (nodeIndex + 1) % nodeDB.getNumNodes();
@@ -795,14 +800,14 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
displayedNodeNum = n->num;
}
- NodeInfo *node = nodeDB.getNodeByIndex(nodeIndex);
+ meshtastic_NodeInfo *node = nodeDB.getNodeByIndex(nodeIndex);
display->setFont(FONT_SMALL);
// The coordinates define the left starting point of the text
display->setTextAlignment(TEXT_ALIGN_LEFT);
- if (config.display.displaymode == Config_DisplayConfig_DisplayMode_INVERTED) {
+ if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
}
@@ -831,13 +836,13 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
}
static char distStr[20];
- strcpy(distStr, "? km"); // might not have location data
- NodeInfo *ourNode = nodeDB.getNode(nodeDB.getNodeNum());
+ strncpy(distStr, "? km", sizeof(distStr)); // might not have location data
+ meshtastic_NodeInfo *ourNode = nodeDB.getNode(nodeDB.getNodeNum());
const char *fields[] = {username, distStr, signalStr, lastStr, NULL};
int16_t compassX = 0, compassY = 0;
// coordinates for the center of the compass/circle
- if (config.display.displaymode == Config_DisplayConfig_DisplayMode_DEFAULT) {
+ if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
compassX = x + SCREEN_WIDTH - getCompassDiam(display) / 2 - 5;
compassY = y + SCREEN_HEIGHT / 2;
} else {
@@ -847,18 +852,18 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
bool hasNodeHeading = false;
if (ourNode && hasPosition(ourNode)) {
- Position &op = ourNode->position;
+ meshtastic_Position &op = ourNode->position;
float myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
drawCompassNorth(display, compassX, compassY, myHeading);
if (hasPosition(node)) {
// display direction toward node
hasNodeHeading = true;
- Position &p = node->position;
+ meshtastic_Position &p = node->position;
float d =
GeoCoord::latLongToMeter(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
- if (config.display.units == Config_DisplayConfig_DisplayUnits_IMPERIAL) {
+ if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) {
if (d < (2 * MILES_TO_FEET))
snprintf(distStr, sizeof(distStr), "%.0f ft", d * METERS_TO_FEET);
else
@@ -874,7 +879,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
GeoCoord::bearing(DegD(op.latitude_i), DegD(op.longitude_i), DegD(p.latitude_i), DegD(p.longitude_i));
// If the top of the compass is a static north then bearingToOther can be drawn on the compass directly
// If the top of the compass is not a static north we need adjust bearingToOther based on heading
- if(!config.display.compass_north_top)
+ if (!config.display.compass_north_top)
bearingToOther -= myHeading;
drawNodeHeading(display, compassX, compassY, bearingToOther);
}
@@ -887,7 +892,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
}
display->drawCircle(compassX, compassY, getCompassDiam(display) / 2);
- if (config.display.displaymode == Config_DisplayConfig_DisplayMode_INVERTED) {
+ if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->setColor(BLACK);
}
// Must be after distStr is populated
@@ -908,7 +913,11 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
// }
// }
// #else
-Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue(32), dispdev(address, sda, scl), ui(&dispdev)
+Screen::Screen(uint8_t address, int sda, int scl)
+ : OSThread("Screen"), cmdQueue(32),
+ dispdev(address, sda, scl,
+ screen_model == meshtastic_Config_DisplayConfig_OledType_OLED_SH1107 ? GEOMETRY_128_128 : GEOMETRY_128_64),
+ ui(&dispdev)
{
address_found = address;
cmdQueue.setReader(this);
@@ -958,6 +967,8 @@ void Screen::setup()
useDisplay = true;
#ifdef AutoOLEDWire_h
+ if (screen_model == meshtastic_Config_DisplayConfig_OledType_OLED_SH1107)
+ screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1106;
dispdev.setDetected(screen_model);
#endif
@@ -1000,8 +1011,8 @@ void Screen::setup()
#ifdef SCREEN_MIRROR
dispdev.mirrorScreen();
#else
- // Standard behaviour is to FLIP the screen (needed on T-Beam). If this config item is set, unflip it, and thereby logically flip it.
- // If you have a headache now, you're welcome.
+ // Standard behaviour is to FLIP the screen (needed on T-Beam). If this config item is set, unflip it, and thereby logically
+ // flip it. If you have a headache now, you're welcome.
if (!config.display.flip_screen) {
dispdev.flipScreenVertically();
}
@@ -1010,7 +1021,7 @@ void Screen::setup()
// Get our hardware ID
uint8_t dmac[6];
getMacAddr(dmac);
- sprintf(ourId, "%02x%02x", dmac[4], dmac[5]);
+ snprintf(ourId, sizeof(ourId), "%02x%02x", dmac[4], dmac[5]);
// Turn on the display.
handleSetOn(true);
@@ -1071,7 +1082,7 @@ int32_t Screen::runOnce()
static const int bootOEMFrameCount = sizeof(bootOEMFrames) / sizeof(bootOEMFrames[0]);
ui.setFrames(bootOEMFrames, bootOEMFrameCount);
ui.update();
-#ifndef USE_EINK
+#ifndef USE_EINK
ui.update();
#endif
showingOEMBootScreen = false;
@@ -1079,7 +1090,7 @@ int32_t Screen::runOnce()
}
#ifndef DISABLE_WELCOME_UNSET
- if (showingNormalScreen && config.lora.region == Config_LoRaConfig_RegionCode_UNSET) {
+ if (showingNormalScreen && config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET) {
setWelcomeFrames();
}
#endif
@@ -1399,7 +1410,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
// The coordinates define the left starting point of the text
display->setTextAlignment(TEXT_ALIGN_LEFT);
- if (config.display.displaymode == Config_DisplayConfig_DisplayMode_INVERTED) {
+ if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
display->setColor(BLACK);
}
@@ -1413,33 +1424,33 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
// Display power status
if (powerStatus->getHasBattery()) {
- if (config.display.displaymode == Config_DisplayConfig_DisplayMode_DEFAULT) {
- drawBattery(display, x , y + 2, imgBattery, powerStatus);
+ if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
+ drawBattery(display, x, y + 2, imgBattery, powerStatus);
} else {
drawBattery(display, x + 1, y + 3, imgBattery, powerStatus);
}
} else if (powerStatus->knowsUSB()) {
- if (config.display.displaymode == Config_DisplayConfig_DisplayMode_DEFAULT) {
+ if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
display->drawFastImage(x, y + 2, 16, 8, powerStatus->getHasUSB() ? imgUSB : imgPower);
} else {
display->drawFastImage(x + 1, y + 3, 16, 8, powerStatus->getHasUSB() ? imgUSB : imgPower);
}
}
// Display nodes status
- if (config.display.displaymode == Config_DisplayConfig_DisplayMode_DEFAULT) {
+ if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 2, nodeStatus);
} else {
drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 3, nodeStatus);
}
// Display GPS status
- if (!config.position.gps_enabled){
+ if (!config.position.gps_enabled) {
int16_t yPos = y + 2;
#ifdef GPS_POWER_TOGGLE
yPos = (y + 10 + FONT_HEIGHT_SMALL);
#endif
drawGPSpowerstat(display, x, yPos, gpsStatus);
} else {
- if (config.display.displaymode == Config_DisplayConfig_DisplayMode_DEFAULT) {
+ if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
drawGPS(display, x + (SCREEN_WIDTH * 0.63), y + 2, gpsStatus);
} else {
drawGPS(display, x + (SCREEN_WIDTH * 0.63), y + 3, gpsStatus);
@@ -1451,27 +1462,36 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
display->drawString(x, y + FONT_HEIGHT_SMALL, channelStr);
// Draw our hardware ID to assist with bluetooth pairing. Either prefix with Info or S&F Logo
if (moduleConfig.store_forward.enabled) {
-#ifdef ARCH_ESP32
- if (millis() - storeForwardModule->lastHeartbeat > (storeForwardModule->heartbeatInterval * 1200)) { //no heartbeat, overlap a bit
+#ifdef ARCH_ESP32
+ if (millis() - storeForwardModule->lastHeartbeat >
+ (storeForwardModule->heartbeatInterval * 1200)) { // no heartbeat, overlap a bit
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
- display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8, imgQuestionL1);
- display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 12, 8, imgQuestionL2);
+ display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
+ imgQuestionL1);
+ display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 12, 8,
+ imgQuestionL2);
#else
- display->drawFastImage(x + SCREEN_WIDTH - 10 - display->getStringWidth(ourId), y + 2 + FONT_HEIGHT_SMALL, 8, 8, imgQuestion);
+ display->drawFastImage(x + SCREEN_WIDTH - 10 - display->getStringWidth(ourId), y + 2 + FONT_HEIGHT_SMALL, 8, 8,
+ imgQuestion);
#endif
} else {
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
- display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 16, 8, imgSFL1);
- display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 16, 8, imgSFL2);
+ display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 16, 8,
+ imgSFL1);
+ display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 16, 8,
+ imgSFL2);
#else
- display->drawFastImage(x + SCREEN_WIDTH - 13 - display->getStringWidth(ourId), y + 2 + FONT_HEIGHT_SMALL, 11, 8, imgSF);
+ display->drawFastImage(x + SCREEN_WIDTH - 13 - display->getStringWidth(ourId), y + 2 + FONT_HEIGHT_SMALL, 11, 8,
+ imgSF);
#endif
}
-#endif
+#endif
} else {
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
- display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8, imgInfoL1);
- display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 12, 8, imgInfoL2);
+ display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
+ imgInfoL1);
+ display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 12, 8,
+ imgInfoL2);
#else
display->drawFastImage(x + SCREEN_WIDTH - 10 - display->getStringWidth(ourId), y + 2 + FONT_HEIGHT_SMALL, 8, 8, imgInfo);
#endif
@@ -1503,23 +1523,23 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
// The coordinates define the left starting point of the text
display->setTextAlignment(TEXT_ALIGN_LEFT);
- if (config.display.displaymode == Config_DisplayConfig_DisplayMode_INVERTED) {
+ if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
display->setColor(BLACK);
}
if (WiFi.status() != WL_CONNECTED) {
display->drawString(x, y, String("WiFi: Not Connected"));
- if(config.display.heading_bold)
+ if (config.display.heading_bold)
display->drawString(x + 1, y, String("WiFi: Not Connected"));
} else {
display->drawString(x, y, String("WiFi: Connected"));
- if(config.display.heading_bold)
+ if (config.display.heading_bold)
display->drawString(x + 1, y, String("WiFi: Connected"));
display->drawString(x + SCREEN_WIDTH - display->getStringWidth("RSSI " + String(WiFi.RSSI())), y,
"RSSI " + String(WiFi.RSSI()));
- if(config.display.heading_bold) {
+ if (config.display.heading_bold) {
display->drawString(x + SCREEN_WIDTH - display->getStringWidth("RSSI " + String(WiFi.RSSI())) - 1, y,
"RSSI " + String(WiFi.RSSI()));
}
@@ -1635,7 +1655,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
// The coordinates define the left starting point of the text
display->setTextAlignment(TEXT_ALIGN_LEFT);
- if (config.display.displaymode == Config_DisplayConfig_DisplayMode_INVERTED) {
+ if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
display->setColor(BLACK);
}
@@ -1650,37 +1670,40 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
// Line 1
display->drawString(x, y, batStr);
- if(config.display.heading_bold)
+ if (config.display.heading_bold)
display->drawString(x + 1, y, batStr);
} else {
// Line 1
display->drawString(x, y, String("USB"));
- if(config.display.heading_bold)
+ if (config.display.heading_bold)
display->drawString(x + 1, y, String("USB"));
}
auto mode = "";
switch (config.lora.modem_preset) {
- case Config_LoRaConfig_ModemPreset_SHORT_SLOW:
+ case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
mode = "ShortS";
break;
- case Config_LoRaConfig_ModemPreset_SHORT_FAST:
+ case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
mode = "ShortF";
break;
- case Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
+ case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
mode = "MedS";
break;
- case Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
+ case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
mode = "MedF";
break;
- case Config_LoRaConfig_ModemPreset_LONG_SLOW:
+ case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW:
mode = "LongS";
break;
- case Config_LoRaConfig_ModemPreset_LONG_FAST:
+ case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
mode = "LongF";
break;
- case Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
+ case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
+ mode = "LongM";
+ break;
+ case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
mode = "VeryL";
break;
default:
@@ -1689,7 +1712,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
}
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode), y, mode);
- if(config.display.heading_bold)
+ if (config.display.heading_bold)
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode) - 1, y, mode);
// Line 2
@@ -1738,19 +1761,19 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
// Display Channel Utilization
char chUtil[13];
- sprintf(chUtil, "ChUtil %2.0f%%", airTime->channelUtilizationPercent());
+ snprintf(chUtil, sizeof(chUtil), "ChUtil %2.0f%%", airTime->channelUtilizationPercent());
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil), y + FONT_HEIGHT_SMALL * 1, chUtil);
-if (config.position.gps_enabled) {
- // Line 3
- if (config.display.gps_format !=
- Config_DisplayConfig_GpsCoordinateFormat_DMS) // if DMS then don't draw altitude
- drawGPSAltitude(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus);
+ if (config.position.gps_enabled) {
+ // Line 3
+ if (config.display.gps_format !=
+ meshtastic_Config_DisplayConfig_GpsCoordinateFormat_DMS) // if DMS then don't draw altitude
+ drawGPSAltitude(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus);
- // Line 4
- drawGPScoordinates(display, x, y + FONT_HEIGHT_SMALL * 3, gpsStatus);
-} else {
- drawGPSpowerstat(display, x - (SCREEN_WIDTH / 4), y + FONT_HEIGHT_SMALL * 2, gpsStatus);
-}
+ // Line 4
+ drawGPScoordinates(display, x, y + FONT_HEIGHT_SMALL * 3, gpsStatus);
+ } else {
+ drawGPSpowerstat(display, x - (SCREEN_WIDTH / 4), y + FONT_HEIGHT_SMALL * 2, gpsStatus);
+ }
/* Display a heartbeat pixel that blinks every time the frame is redrawn */
#ifdef SHOW_REDRAWS
if (heartbeat)
@@ -1791,7 +1814,7 @@ int Screen::handleStatusUpdate(const meshtastic::Status *arg)
return 0;
}
-int Screen::handleTextMessage(const MeshPacket *packet)
+int Screen::handleTextMessage(const meshtastic_MeshPacket *packet)
{
if (showingNormalScreen) {
setFrames(); // Regen the list of screens (will show new text message)
diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h
index 3988fa1a8..db851e8bb 100644
--- a/src/graphics/Screen.h
+++ b/src/graphics/Screen.h
@@ -7,15 +7,15 @@
namespace graphics
{
// Noop class for boards without screen.
-class Screen
+class Screen
{
public:
- explicit Screen(char){}
+ explicit Screen(char) {}
void onPress() {}
void setup() {}
void setOn(bool) {}
- void print(const char*){}
- void adjustBrightness(){}
+ void print(const char *) {}
+ void adjustBrightness() {}
void doDeepSleep() {}
void forceDisplay() {}
void startBluetoothPinScreen(uint32_t pin) {}
@@ -23,7 +23,7 @@ class Screen
void startRebootScreen() {}
void startFirmwareUpdateScreen() {}
};
-}
+} // namespace graphics
#else
#include
@@ -34,7 +34,7 @@ class Screen
#ifdef USE_ST7567
#include
-#elif defined(USE_SH1106)
+#elif defined(USE_SH1106) || defined(USE_SH1107)
#include
#elif defined(USE_SSD1306)
#include
@@ -49,9 +49,9 @@ class Screen
#include "commands.h"
#include "concurrency/LockGuard.h"
#include "concurrency/OSThread.h"
+#include "mesh/MeshModule.h"
#include "power.h"
#include
-#include "mesh/MeshModule.h"
// 0 to 255, though particular variants might define different defaults
#ifndef BRIGHTNESS_DEFAULT
@@ -110,8 +110,8 @@ class Screen : public concurrency::OSThread
CallbackObserver(this, &Screen::handleStatusUpdate);
CallbackObserver nodeStatusObserver =
CallbackObserver(this, &Screen::handleStatusUpdate);
- CallbackObserver textMessageObserver =
- CallbackObserver(this, &Screen::handleTextMessage);
+ CallbackObserver textMessageObserver =
+ CallbackObserver(this, &Screen::handleTextMessage);
CallbackObserver uiFrameEventObserver =
CallbackObserver(this, &Screen::handleUIFrameEvent);
@@ -132,13 +132,14 @@ class Screen : public concurrency::OSThread
void setOn(bool on)
{
if (!on)
- handleSetOn(false); // We handle off commands immediately, because they might be called because the CPU is shutting down
+ handleSetOn(
+ false); // We handle off commands immediately, because they might be called because the CPU is shutting down
else
enqueueCmd(ScreenCmd{.cmd = on ? Cmd::SET_ON : Cmd::SET_OFF});
}
/**
- * Prepare the display for the unit going to the lowest power mode possible. Most screens will just
+ * Prepare the display for the unit going to the lowest power mode possible. Most screens will just
* poweroff, but eink screens will show a "I'm sleeping" graphic, possibly with a QR code
*/
void doDeepSleep();
@@ -223,29 +224,33 @@ class Screen : public concurrency::OSThread
LASTCHAR = ch;
switch (last) { // conversion depending on first UTF8-character
- case 0xC2: {
- SKIPREST = false;
- return (uint8_t)ch;
- }
- case 0xC3: {
- SKIPREST = false;
- return (uint8_t)(ch | 0xC0);
- }
- // map UTF-8 cyrillic chars to it Windows-1251 (CP-1251) ASCII codes
- // note: in this case we must use compatible font - provided ArialMT_Plain_10/16/24 by 'ThingPulse/esp8266-oled-ssd1306' library
- // have empty chars for non-latin ASCII symbols
- case 0xD0: {
- SKIPREST = false;
- if (ch == 129) return (uint8_t)(168); // Ё
- if (ch > 143 && ch < 192) return (uint8_t)(ch + 48);
- break;
- }
- case 0xD1: {
- SKIPREST = false;
- if (ch == 145) return (uint8_t)(184); // ё
- if (ch > 127 && ch < 144) return (uint8_t)(ch + 112);
- break;
- }
+ case 0xC2: {
+ SKIPREST = false;
+ return (uint8_t)ch;
+ }
+ case 0xC3: {
+ SKIPREST = false;
+ return (uint8_t)(ch | 0xC0);
+ }
+ // map UTF-8 cyrillic chars to it Windows-1251 (CP-1251) ASCII codes
+ // note: in this case we must use compatible font - provided ArialMT_Plain_10/16/24 by 'ThingPulse/esp8266-oled-ssd1306'
+ // library have empty chars for non-latin ASCII symbols
+ case 0xD0: {
+ SKIPREST = false;
+ if (ch == 129)
+ return (uint8_t)(168); // Ё
+ if (ch > 143 && ch < 192)
+ return (uint8_t)(ch + 48);
+ break;
+ }
+ case 0xD1: {
+ SKIPREST = false;
+ if (ch == 145)
+ return (uint8_t)(184); // ё
+ if (ch > 127 && ch < 144)
+ return (uint8_t)(ch + 112);
+ break;
+ }
}
// We want to strip out prefix chars for two-byte char formats
@@ -268,7 +273,7 @@ class Screen : public concurrency::OSThread
DebugInfo *debug_info() { return &debugInfo; }
int handleStatusUpdate(const meshtastic::Status *arg);
- int handleTextMessage(const MeshPacket *arg);
+ int handleTextMessage(const meshtastic_MeshPacket *arg);
int handleUIFrameEvent(const UIFrameEvent *arg);
/// Used to force (super slow) eink displays to draw critical frames
@@ -342,10 +347,7 @@ class Screen : public concurrency::OSThread
/// Display device
-// #ifdef RAK4630
-// EInkDisplay dispdev;
-// AutoOLEDWire dispdev_oled;
-#ifdef USE_SH1106
+#if defined(USE_SH1106) || defined(USE_SH1107)
SH1106Wire dispdev;
#elif defined(USE_SSD1306)
SSD1306Wire dispdev;
diff --git a/src/graphics/TFTDisplay.cpp b/src/graphics/TFTDisplay.cpp
index 670c0f162..0bd1d3a99 100644
--- a/src/graphics/TFTDisplay.cpp
+++ b/src/graphics/TFTDisplay.cpp
@@ -8,7 +8,7 @@
static TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h
-TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl)
+TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl, uint8_t screen_model)
{
#ifdef SCREEN_ROTATE
setGeometry(GEOMETRY_RAWMODE, TFT_HEIGHT, TFT_WIDTH);
@@ -22,7 +22,7 @@ void TFTDisplay::display(void)
{
concurrency::LockGuard g(spiLock);
- uint16_t x,y;
+ uint16_t x, y;
for (y = 0; y < displayHeight; y++) {
for (x = 0; x < displayWidth; x++) {
diff --git a/src/graphics/TFTDisplay.h b/src/graphics/TFTDisplay.h
index c9749d9a8..c18dc03c6 100644
--- a/src/graphics/TFTDisplay.h
+++ b/src/graphics/TFTDisplay.h
@@ -18,14 +18,14 @@ class TFTDisplay : public OLEDDisplay
/* constructor
FIXME - the parameters are not used, just a temporary hack to keep working like the old displays
*/
- TFTDisplay(uint8_t address, int sda, int scl);
+ TFTDisplay(uint8_t address, int sda, int scl, uint8_t screen_model);
// Write the buffer to the display memory
virtual void display(void) override;
-
+
/**
* shim to make the abstraction happy
- *
+ *
*/
void setDetected(uint8_t detected);
diff --git a/src/graphics/fonts/OLEDDisplayFontsRU.cpp b/src/graphics/fonts/OLEDDisplayFontsRU.cpp
index 6ce18c9d1..fa055d8b5 100644
--- a/src/graphics/fonts/OLEDDisplayFontsRU.cpp
+++ b/src/graphics/fonts/OLEDDisplayFontsRU.cpp
@@ -2,425 +2,425 @@
// Font generated or edited with the glyphEditor
const uint8_t ArialMT_Plain_10_RU[] PROGMEM = {
- 0x0A, // Width: 10
- 0x0D, // Height: 13
- 0x20, // First char: 32
- 0xE0, // Number of chars: 224
-
- // Jump Table:
- 0xFF, 0xFF, 0x00, 0x0A, // 32
- 0x00, 0x00, 0x04, 0x03, // 33
- 0x00, 0x04, 0x05, 0x04, // 34
- 0x00, 0x09, 0x09, 0x06, // 35
- 0x00, 0x12, 0x0A, 0x06, // 36
- 0x00, 0x1C, 0x10, 0x09, // 37
- 0x00, 0x2C, 0x0E, 0x08, // 38
- 0x00, 0x3A, 0x01, 0x02, // 39
- 0x00, 0x3B, 0x06, 0x04, // 40
- 0x00, 0x41, 0x06, 0x04, // 41
- 0x00, 0x47, 0x05, 0x04, // 42
- 0x00, 0x4C, 0x09, 0x06, // 43
- 0x00, 0x55, 0x04, 0x03, // 44
- 0x00, 0x59, 0x03, 0x03, // 45
- 0x00, 0x5C, 0x04, 0x03, // 46
- 0x00, 0x60, 0x05, 0x04, // 47
- 0x00, 0x65, 0x0A, 0x06, // 48
- 0x00, 0x6F, 0x08, 0x05, // 49
- 0x00, 0x77, 0x0A, 0x06, // 50
- 0x00, 0x81, 0x0A, 0x06, // 51
- 0x00, 0x8B, 0x0B, 0x07, // 52
- 0x00, 0x96, 0x0A, 0x06, // 53
- 0x00, 0xA0, 0x0A, 0x06, // 54
- 0x00, 0xAA, 0x09, 0x06, // 55
- 0x00, 0xB3, 0x0A, 0x06, // 56
- 0x00, 0xBD, 0x0A, 0x06, // 57
- 0x00, 0xC7, 0x04, 0x03, // 58
- 0x00, 0xCB, 0x04, 0x03, // 59
- 0x00, 0xCF, 0x0A, 0x06, // 60
- 0x00, 0xD9, 0x09, 0x06, // 61
- 0x00, 0xE2, 0x09, 0x06, // 62
- 0x00, 0xEB, 0x0B, 0x07, // 63
- 0x00, 0xF6, 0x14, 0x0B, // 64
- 0x01, 0x0A, 0x0E, 0x08, // 65
- 0x01, 0x18, 0x0C, 0x07, // 66
- 0x01, 0x24, 0x0C, 0x07, // 67
- 0x01, 0x30, 0x0B, 0x07, // 68
- 0x01, 0x3B, 0x0C, 0x07, // 69
- 0x01, 0x47, 0x09, 0x06, // 70
- 0x01, 0x50, 0x0D, 0x08, // 71
- 0x01, 0x5D, 0x0C, 0x07, // 72
- 0x01, 0x69, 0x04, 0x03, // 73
- 0x01, 0x6D, 0x08, 0x05, // 74
- 0x01, 0x75, 0x0E, 0x08, // 75
- 0x01, 0x83, 0x0C, 0x07, // 76
- 0x01, 0x8F, 0x10, 0x09, // 77
- 0x01, 0x9F, 0x0C, 0x07, // 78
- 0x01, 0xAB, 0x0E, 0x08, // 79
- 0x01, 0xB9, 0x0B, 0x07, // 80
- 0x01, 0xC4, 0x0E, 0x08, // 81
- 0x01, 0xD2, 0x0C, 0x07, // 82
- 0x01, 0xDE, 0x0C, 0x07, // 83
- 0x01, 0xEA, 0x0B, 0x07, // 84
- 0x01, 0xF5, 0x0C, 0x07, // 85
- 0x02, 0x01, 0x0D, 0x08, // 86
- 0x02, 0x0E, 0x11, 0x0A, // 87
- 0x02, 0x1F, 0x0E, 0x08, // 88
- 0x02, 0x2D, 0x0D, 0x08, // 89
- 0x02, 0x3A, 0x0C, 0x07, // 90
- 0x02, 0x46, 0x06, 0x04, // 91
- 0x02, 0x4C, 0x06, 0x04, // 92
- 0x02, 0x52, 0x04, 0x03, // 93
- 0x02, 0x56, 0x09, 0x06, // 94
- 0x02, 0x5F, 0x0C, 0x07, // 95
- 0x02, 0x6B, 0x03, 0x03, // 96
- 0x02, 0x6E, 0x0A, 0x06, // 97
- 0x02, 0x78, 0x0A, 0x06, // 98
- 0x02, 0x82, 0x0A, 0x06, // 99
- 0x02, 0x8C, 0x0A, 0x06, // 100
- 0x02, 0x96, 0x0A, 0x06, // 101
- 0x02, 0xA0, 0x05, 0x04, // 102
- 0x02, 0xA5, 0x0A, 0x06, // 103
- 0x02, 0xAF, 0x0A, 0x06, // 104
- 0x02, 0xB9, 0x04, 0x03, // 105
- 0x02, 0xBD, 0x04, 0x03, // 106
- 0x02, 0xC1, 0x08, 0x05, // 107
- 0x02, 0xC9, 0x04, 0x03, // 108
- 0x02, 0xCD, 0x10, 0x09, // 109
- 0x02, 0xDD, 0x0A, 0x06, // 110
- 0x02, 0xE7, 0x0A, 0x06, // 111
- 0x02, 0xF1, 0x0A, 0x06, // 112
- 0x02, 0xFB, 0x0A, 0x06, // 113
- 0x03, 0x05, 0x05, 0x04, // 114
- 0x03, 0x0A, 0x08, 0x05, // 115
- 0x03, 0x12, 0x06, 0x04, // 116
- 0x03, 0x18, 0x0A, 0x06, // 117
- 0x03, 0x22, 0x09, 0x06, // 118
- 0x03, 0x2B, 0x0E, 0x08, // 119
- 0x03, 0x39, 0x0A, 0x06, // 120
- 0x03, 0x43, 0x09, 0x06, // 121
- 0x03, 0x4C, 0x0A, 0x06, // 122
- 0x03, 0x56, 0x06, 0x04, // 123
- 0x03, 0x5C, 0x04, 0x03, // 124
- 0x03, 0x60, 0x05, 0x04, // 125
- 0x03, 0x65, 0x09, 0x06, // 126
- 0xFF, 0xFF, 0x00, 0x0A, // 127
- 0xFF, 0xFF, 0x00, 0x0A, // 128
- 0xFF, 0xFF, 0x00, 0x0A, // 129
- 0xFF, 0xFF, 0x00, 0x0A, // 130
- 0xFF, 0xFF, 0x00, 0x0A, // 131
- 0xFF, 0xFF, 0x00, 0x0A, // 132
- 0xFF, 0xFF, 0x00, 0x0A, // 133
- 0xFF, 0xFF, 0x00, 0x0A, // 134
- 0xFF, 0xFF, 0x00, 0x0A, // 135
- 0xFF, 0xFF, 0x00, 0x0A, // 136
- 0xFF, 0xFF, 0x00, 0x0A, // 137
- 0xFF, 0xFF, 0x00, 0x0A, // 138
- 0xFF, 0xFF, 0x00, 0x0A, // 139
- 0xFF, 0xFF, 0x00, 0x0A, // 140
- 0xFF, 0xFF, 0x00, 0x0A, // 141
- 0xFF, 0xFF, 0x00, 0x0A, // 142
- 0xFF, 0xFF, 0x00, 0x0A, // 143
- 0xFF, 0xFF, 0x00, 0x0A, // 144
- 0xFF, 0xFF, 0x00, 0x0A, // 145
- 0xFF, 0xFF, 0x00, 0x0A, // 146
- 0xFF, 0xFF, 0x00, 0x0A, // 147
- 0xFF, 0xFF, 0x00, 0x0A, // 148
- 0xFF, 0xFF, 0x00, 0x0A, // 149
- 0xFF, 0xFF, 0x00, 0x0A, // 150
- 0xFF, 0xFF, 0x00, 0x0A, // 151
- 0xFF, 0xFF, 0x00, 0x0A, // 152
- 0xFF, 0xFF, 0x00, 0x0A, // 153
- 0xFF, 0xFF, 0x00, 0x0A, // 154
- 0xFF, 0xFF, 0x00, 0x0A, // 155
- 0xFF, 0xFF, 0x00, 0x0A, // 156
- 0xFF, 0xFF, 0x00, 0x0A, // 157
- 0xFF, 0xFF, 0x00, 0x0A, // 158
- 0xFF, 0xFF, 0x00, 0x0A, // 159
- 0xFF, 0xFF, 0x00, 0x0A, // 160
- 0x03, 0x6E, 0x04, 0x03, // 161
- 0x03, 0x72, 0x0A, 0x06, // 162
- 0x03, 0x7C, 0x0C, 0x07, // 163
- 0x03, 0x88, 0x0A, 0x06, // 164
- 0x03, 0x92, 0x0A, 0x06, // 165
- 0x03, 0x9C, 0x04, 0x03, // 166
- 0x03, 0xA0, 0x0A, 0x06, // 167
- 0x03, 0xAA, 0x0C, 0x07, // 168
- 0x03, 0xB6, 0x0D, 0x08, // 169
- 0x03, 0xC3, 0x07, 0x05, // 170
- 0x03, 0xCA, 0x0A, 0x06, // 171
- 0x03, 0xD4, 0x09, 0x06, // 172
- 0x03, 0xDD, 0x03, 0x03, // 173
- 0x03, 0xE0, 0x0D, 0x08, // 174
- 0x03, 0xED, 0x0B, 0x07, // 175
- 0x03, 0xF8, 0x07, 0x05, // 176
- 0x03, 0xFF, 0x0A, 0x06, // 177
- 0x04, 0x09, 0x05, 0x04, // 178
- 0x04, 0x0E, 0x05, 0x04, // 179
- 0x04, 0x13, 0x05, 0x04, // 180
- 0x04, 0x18, 0x0A, 0x06, // 181
- 0x04, 0x22, 0x09, 0x06, // 182
- 0x04, 0x2B, 0x03, 0x03, // 183
- 0x04, 0x2E, 0x0B, 0x07, // 184
- 0x04, 0x39, 0x0B, 0x07, // 185
- 0x04, 0x44, 0x07, 0x05, // 186
- 0x04, 0x4B, 0x0A, 0x06, // 187
- 0x04, 0x55, 0x10, 0x09, // 188
- 0x04, 0x65, 0x10, 0x09, // 189
- 0x04, 0x75, 0x10, 0x09, // 190
- 0x04, 0x85, 0x0A, 0x06, // 191
- 0x04, 0x8F, 0x0C, 0x07, // 192
- 0x04, 0x9B, 0x0C, 0x07, // 193
- 0x04, 0xA7, 0x0C, 0x07, // 194
- 0x04, 0xB3, 0x0B, 0x07, // 195
- 0x04, 0xBE, 0x0C, 0x07, // 196
- 0x04, 0xCA, 0x0C, 0x07, // 197
- 0x04, 0xD6, 0x0C, 0x07, // 198
- 0x04, 0xE2, 0x0C, 0x07, // 199
- 0x04, 0xEE, 0x0C, 0x07, // 200
- 0x04, 0xFA, 0x0C, 0x07, // 201
- 0x05, 0x06, 0x0C, 0x07, // 202
- 0x05, 0x12, 0x0C, 0x07, // 203
- 0x05, 0x1E, 0x0C, 0x07, // 204
- 0x05, 0x2A, 0x0C, 0x07, // 205
- 0x05, 0x36, 0x0C, 0x07, // 206
- 0x05, 0x42, 0x0C, 0x07, // 207
- 0x05, 0x4E, 0x0B, 0x07, // 208
- 0x05, 0x59, 0x0C, 0x07, // 209
- 0x05, 0x65, 0x0B, 0x07, // 210
- 0x05, 0x70, 0x0C, 0x07, // 211
- 0x05, 0x7C, 0x0B, 0x07, // 212
- 0x05, 0x87, 0x0C, 0x07, // 213
- 0x05, 0x93, 0x0C, 0x07, // 214
- 0x05, 0x9F, 0x0C, 0x07, // 215
- 0x05, 0xAB, 0x0C, 0x07, // 216
- 0x05, 0xB7, 0x0E, 0x08, // 217
- 0x05, 0xC5, 0x0C, 0x07, // 218
- 0x05, 0xD1, 0x0C, 0x07, // 219
- 0x05, 0xDD, 0x0C, 0x07, // 220
- 0x05, 0xE9, 0x0C, 0x07, // 221
- 0x05, 0xF5, 0x0C, 0x07, // 222
- 0x06, 0x01, 0x0C, 0x07, // 223
- 0x06, 0x0D, 0x0C, 0x07, // 224
- 0x06, 0x19, 0x0C, 0x07, // 225
- 0x06, 0x25, 0x0C, 0x07, // 226
- 0x06, 0x31, 0x0B, 0x07, // 227
- 0x06, 0x3C, 0x0C, 0x07, // 228
- 0x06, 0x48, 0x0B, 0x07, // 229
- 0x06, 0x53, 0x0C, 0x07, // 230
- 0x06, 0x5F, 0x0C, 0x07, // 231
- 0x06, 0x6B, 0x0C, 0x07, // 232
- 0x06, 0x77, 0x0C, 0x07, // 233
- 0x06, 0x83, 0x0C, 0x07, // 234
- 0x06, 0x8F, 0x0C, 0x07, // 235
- 0x06, 0x9B, 0x0C, 0x07, // 236
- 0x06, 0xA7, 0x0C, 0x07, // 237
- 0x06, 0xB3, 0x0C, 0x07, // 238
- 0x06, 0xBF, 0x0C, 0x07, // 239
- 0x06, 0xCB, 0x0B, 0x07, // 240
- 0x06, 0xD6, 0x0C, 0x07, // 241
- 0x06, 0xE2, 0x0B, 0x07, // 242
- 0x06, 0xED, 0x0C, 0x07, // 243
- 0x06, 0xF9, 0x0B, 0x07, // 244
- 0x07, 0x04, 0x0C, 0x07, // 245
- 0x07, 0x10, 0x0C, 0x07, // 246
- 0x07, 0x1C, 0x0C, 0x07, // 247
- 0x07, 0x28, 0x0C, 0x07, // 248
- 0x07, 0x34, 0x0E, 0x08, // 249
- 0x07, 0x42, 0x0C, 0x07, // 250
- 0x07, 0x4E, 0x0C, 0x07, // 251
- 0x07, 0x5A, 0x0C, 0x07, // 252
- 0x07, 0x66, 0x0C, 0x07, // 253
- 0x07, 0x72, 0x0C, 0x07, // 254
- 0x07, 0x7E, 0x0C, 0x07, // 255
-
- // Font Data:
- 0x00, 0x00, 0xF8, 0x02, // 33
- 0x38, 0x00, 0x00, 0x00, 0x38, // 34
- 0xA0, 0x03, 0xE0, 0x00, 0xB8, 0x03, 0xE0, 0x00, 0xB8, // 35
- 0x30, 0x01, 0x28, 0x02, 0xF8, 0x07, 0x48, 0x02, 0x90, 0x01, // 36
- 0x00, 0x00, 0x30, 0x00, 0x48, 0x00, 0x30, 0x03, 0xC0, 0x00, 0xB0, 0x01, 0x48, 0x02, 0x80, 0x01, // 37
- 0x80, 0x01, 0x50, 0x02, 0x68, 0x02, 0xA8, 0x02, 0x18, 0x01, 0x80, 0x03, 0x80, 0x02, // 38
- 0x38, // 39
- 0xE0, 0x03, 0x10, 0x04, 0x08, 0x08, // 40
- 0x08, 0x08, 0x10, 0x04, 0xE0, 0x03, // 41
- 0x28, 0x00, 0x18, 0x00, 0x28, // 42
- 0x40, 0x00, 0x40, 0x00, 0xF0, 0x01, 0x40, 0x00, 0x40, // 43
- 0x00, 0x00, 0x00, 0x06, // 44
- 0x80, 0x00, 0x80, // 45
- 0x00, 0x00, 0x00, 0x02, // 46
- 0x00, 0x03, 0xE0, 0x00, 0x18, // 47
- 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0xF0, 0x01, // 48
- 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0xF8, 0x03, // 49
- 0x10, 0x02, 0x08, 0x03, 0x88, 0x02, 0x48, 0x02, 0x30, 0x02, // 50
- 0x10, 0x01, 0x08, 0x02, 0x48, 0x02, 0x48, 0x02, 0xB0, 0x01, // 51
- 0xC0, 0x00, 0xA0, 0x00, 0x90, 0x00, 0x88, 0x00, 0xF8, 0x03, 0x80, // 52
- 0x60, 0x01, 0x38, 0x02, 0x28, 0x02, 0x28, 0x02, 0xC8, 0x01, // 53
- 0xF0, 0x01, 0x28, 0x02, 0x28, 0x02, 0x28, 0x02, 0xD0, 0x01, // 54
- 0x08, 0x00, 0x08, 0x03, 0xC8, 0x00, 0x38, 0x00, 0x08, // 55
- 0xB0, 0x01, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xB0, 0x01, // 56
- 0x70, 0x01, 0x88, 0x02, 0x88, 0x02, 0x88, 0x02, 0xF0, 0x01, // 57
- 0x00, 0x00, 0x20, 0x02, // 58
- 0x00, 0x00, 0x20, 0x06, // 59
- 0x00, 0x00, 0x40, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0x10, 0x01, // 60
- 0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0xA0, // 61
- 0x00, 0x00, 0x10, 0x01, 0xA0, 0x00, 0xA0, 0x00, 0x40, // 62
- 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0xC8, 0x02, 0x48, 0x00, 0x30, // 63
- 0x00, 0x00, 0xC0, 0x03, 0x30, 0x04, 0xD0, 0x09, 0x28, 0x0A, 0x28, 0x0A, 0xC8, 0x0B, 0x68, 0x0A, 0x10, 0x05, 0xE0, 0x04, // 64
- 0x00, 0x02, 0xC0, 0x01, 0xB0, 0x00, 0x88, 0x00, 0xB0, 0x00, 0xC0, 0x01, 0x00, 0x02, // 65
- 0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xF0, 0x01, // 66
- 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x10, 0x01, // 67
- 0x00, 0x00, 0xF8, 0x03, 0x08, 0x02, 0x08, 0x02, 0x10, 0x01, 0xE0, // 68
- 0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, // 69
- 0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0x08, // 70
- 0x00, 0x00, 0xE0, 0x00, 0x10, 0x01, 0x08, 0x02, 0x48, 0x02, 0x50, 0x01, 0xC0, // 71
- 0x00, 0x00, 0xF8, 0x03, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xF8, 0x03, // 72
- 0x00, 0x00, 0xF8, 0x03, // 73
- 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0xF8, 0x01, // 74
- 0x00, 0x00, 0xF8, 0x03, 0x80, 0x00, 0x60, 0x00, 0x90, 0x00, 0x08, 0x01, 0x00, 0x02, // 75
- 0x00, 0x00, 0xF8, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, // 76
- 0x00, 0x00, 0xF8, 0x03, 0x30, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x30, 0x00, 0xF8, 0x03, // 77
- 0x00, 0x00, 0xF8, 0x03, 0x30, 0x00, 0x40, 0x00, 0x80, 0x01, 0xF8, 0x03, // 78
- 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0xF0, 0x01, // 79
- 0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x30, // 80
- 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x03, 0x08, 0x03, 0xF0, 0x02, // 81
- 0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0xC8, 0x00, 0x30, 0x03, // 82
- 0x00, 0x00, 0x30, 0x01, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x90, 0x01, // 83
- 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0xF8, 0x03, 0x08, 0x00, 0x08, // 84
- 0x00, 0x00, 0xF8, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0xF8, 0x01, // 85
- 0x08, 0x00, 0x70, 0x00, 0x80, 0x01, 0x00, 0x02, 0x80, 0x01, 0x70, 0x00, 0x08, // 86
- 0x18, 0x00, 0xE0, 0x01, 0x00, 0x02, 0xF0, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x02, 0xE0, 0x01, 0x18, // 87
- 0x00, 0x02, 0x08, 0x01, 0x90, 0x00, 0x60, 0x00, 0x90, 0x00, 0x08, 0x01, 0x00, 0x02, // 88
- 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0xC0, 0x03, 0x20, 0x00, 0x10, 0x00, 0x08, // 89
- 0x08, 0x03, 0x88, 0x02, 0xC8, 0x02, 0x68, 0x02, 0x38, 0x02, 0x18, 0x02, // 90
- 0x00, 0x00, 0xF8, 0x0F, 0x08, 0x08, // 91
- 0x18, 0x00, 0xE0, 0x00, 0x00, 0x03, // 92
- 0x08, 0x08, 0xF8, 0x0F, // 93
- 0x40, 0x00, 0x30, 0x00, 0x08, 0x00, 0x30, 0x00, 0x40, // 94
- 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, // 95
- 0x08, 0x00, 0x10, // 96
- 0x00, 0x00, 0x00, 0x03, 0xA0, 0x02, 0xA0, 0x02, 0xE0, 0x03, // 97
- 0x00, 0x00, 0xF8, 0x03, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 98
- 0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0x40, 0x01, // 99
- 0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0xF8, 0x03, // 100
- 0x00, 0x00, 0xC0, 0x01, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x02, // 101
- 0x20, 0x00, 0xF0, 0x03, 0x28, // 102
- 0x00, 0x00, 0xC0, 0x05, 0x20, 0x0A, 0x20, 0x0A, 0xE0, 0x07, // 103
- 0x00, 0x00, 0xF8, 0x03, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x03, // 104
- 0x00, 0x00, 0xE8, 0x03, // 105
- 0x00, 0x08, 0xE8, 0x07, // 106
- 0xF8, 0x03, 0x80, 0x00, 0xC0, 0x01, 0x20, 0x02, // 107
- 0x00, 0x00, 0xF8, 0x03, // 108
- 0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x03, // 109
- 0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x03, // 110
- 0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 111
- 0x00, 0x00, 0xE0, 0x0F, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 112
- 0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0xE0, 0x0F, // 113
- 0x00, 0x00, 0xE0, 0x03, 0x20, // 114
- 0x40, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0x20, 0x01, // 115
- 0x20, 0x00, 0xF8, 0x03, 0x20, 0x02, // 116
- 0x00, 0x00, 0xE0, 0x01, 0x00, 0x02, 0x00, 0x02, 0xE0, 0x03, // 117
- 0x20, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x20, // 118
- 0xE0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x20, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xE0, 0x01, // 119
- 0x20, 0x02, 0x40, 0x01, 0x80, 0x00, 0x40, 0x01, 0x20, 0x02, // 120
- 0x20, 0x00, 0xC0, 0x09, 0x00, 0x06, 0xC0, 0x01, 0x20, // 121
- 0x20, 0x02, 0x20, 0x03, 0xA0, 0x02, 0x60, 0x02, 0x20, 0x02, // 122
- 0x80, 0x00, 0x78, 0x0F, 0x08, 0x08, // 123
- 0x00, 0x00, 0xF8, 0x0F, // 124
- 0x08, 0x08, 0x78, 0x0F, 0x80, // 125
- 0xC0, 0x00, 0x40, 0x00, 0xC0, 0x00, 0x80, 0x00, 0xC0, // 126
- 0x00, 0x00, 0xA0, 0x0F, // 161
- 0x00, 0x00, 0xC0, 0x01, 0xA0, 0x0F, 0x78, 0x02, 0x40, 0x01, // 162
- 0x40, 0x02, 0x70, 0x03, 0xC8, 0x02, 0x48, 0x02, 0x08, 0x02, 0x10, 0x02, // 163
- 0x00, 0x00, 0xE0, 0x01, 0x20, 0x01, 0x20, 0x01, 0xE0, 0x01, // 164
- 0x48, 0x01, 0x70, 0x01, 0xC0, 0x03, 0x70, 0x01, 0x48, 0x01, // 165
- 0x00, 0x00, 0x38, 0x0F, // 166
- 0xD0, 0x04, 0x28, 0x09, 0x48, 0x09, 0x48, 0x0A, 0x90, 0x05, // 167
- 0x00, 0x00, 0xE0, 0x03, 0xA8, 0x02, 0xA0, 0x02, 0xA8, 0x02, 0x20, 0x02, // 168
- 0xE0, 0x00, 0x10, 0x01, 0x48, 0x02, 0xA8, 0x02, 0xA8, 0x02, 0x10, 0x01, 0xE0, // 169
- 0x68, 0x00, 0x68, 0x00, 0x68, 0x00, 0x78, // 170
- 0x00, 0x00, 0x80, 0x01, 0x40, 0x02, 0x80, 0x01, 0x40, 0x02, // 171
- 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xE0, // 172
- 0x80, 0x00, 0x80, // 173
- 0xE0, 0x00, 0x10, 0x01, 0xE8, 0x02, 0x68, 0x02, 0xC8, 0x02, 0x10, 0x01, 0xE0, // 174
- 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, // 175
- 0x00, 0x00, 0x38, 0x00, 0x28, 0x00, 0x38, // 176
- 0x40, 0x02, 0x40, 0x02, 0xF0, 0x03, 0x40, 0x02, 0x40, 0x02, // 177
- 0x48, 0x00, 0x68, 0x00, 0x58, // 178
- 0x48, 0x00, 0x58, 0x00, 0x68, // 179
- 0x00, 0x00, 0x10, 0x00, 0x08, // 180
- 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x02, 0x00, 0x02, 0xE0, 0x03, // 181
- 0x70, 0x00, 0xF8, 0x0F, 0x08, 0x00, 0xF8, 0x0F, 0x08, // 182
- 0x00, 0x00, 0x40, // 183
- 0x00, 0x00, 0xC0, 0x01, 0xA8, 0x02, 0xA0, 0x02, 0xA8, 0x02, 0xC0, // 184
- 0x00, 0x00, 0xF0, 0x03, 0x40, 0x00, 0x80, 0x00, 0xF8, 0x03, 0x08, // 185
- 0x30, 0x00, 0x48, 0x00, 0x48, 0x00, 0x30, // 186
- 0x00, 0x00, 0x40, 0x02, 0x80, 0x01, 0x40, 0x02, 0x80, 0x01, // 187
- 0x00, 0x00, 0x10, 0x02, 0x78, 0x01, 0xC0, 0x00, 0x20, 0x01, 0x90, 0x01, 0xC8, 0x03, 0x00, 0x01, // 188
- 0x00, 0x00, 0x10, 0x02, 0x78, 0x01, 0x80, 0x00, 0x60, 0x00, 0x50, 0x02, 0x48, 0x03, 0xC0, 0x02, // 189
- 0x48, 0x00, 0x58, 0x00, 0x68, 0x03, 0x80, 0x00, 0x60, 0x01, 0x90, 0x01, 0xC8, 0x03, 0x00, 0x01, // 190
- 0x00, 0x00, 0x00, 0x06, 0x00, 0x09, 0xA0, 0x09, 0x00, 0x04, // 191
- 0x00, 0x00, 0xF0, 0x03, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0xF0, 0x03, // 192
- 0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x88, 0x01, // 193
- 0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xB0, 0x01, // 194
- 0x00, 0x00, 0xF8, 0x03, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x18, // 195
- 0x00, 0x00, 0x00, 0x02, 0xFC, 0x03, 0x04, 0x02, 0xFC, 0x03, 0x00, 0x02, // 196
- 0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x08, 0x02, // 197
- 0x00, 0x00, 0xB8, 0x03, 0x40, 0x00, 0xF8, 0x03, 0x40, 0x00, 0xB8, 0x03, // 198
- 0x00, 0x00, 0x08, 0x02, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xB0, 0x01, // 199
- 0x00, 0x00, 0xF8, 0x03, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0xF8, 0x03, // 200
- 0x00, 0x00, 0xE0, 0x03, 0x08, 0x01, 0x90, 0x00, 0x48, 0x00, 0xE0, 0x03, // 201
- 0x00, 0x00, 0xF8, 0x03, 0x40, 0x00, 0xA0, 0x00, 0x10, 0x01, 0x08, 0x02, // 202
- 0x00, 0x00, 0x00, 0x02, 0xF0, 0x01, 0x08, 0x00, 0x08, 0x00, 0xF8, 0x03, // 203
- 0x00, 0x00, 0xF8, 0x03, 0x10, 0x00, 0x60, 0x00, 0x10, 0x00, 0xF8, 0x03, // 204
- 0x00, 0x00, 0xF8, 0x03, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xF8, 0x03, // 205
- 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0xF0, 0x01, // 206
- 0x00, 0x00, 0xF8, 0x03, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0xF8, 0x03, // 207
- 0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x30, // 208
- 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x10, 0x01, // 209
- 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0xF8, 0x03, 0x08, 0x00, 0x08, // 210
- 0x00, 0x00, 0x38, 0x00, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0xF8, 0x01, // 211
- 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, 0xF8, 0x03, 0x88, 0x00, 0x70, // 212
- 0x00, 0x00, 0x18, 0x03, 0xA0, 0x00, 0x40, 0x00, 0xA0, 0x00, 0x18, 0x03, // 213
- 0x00, 0x00, 0xF8, 0x03, 0x00, 0x02, 0x00, 0x02, 0xF8, 0x03, 0x00, 0x02, // 214
- 0x00, 0x00, 0x38, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xF8, 0x03, // 215
- 0x00, 0x00, 0xF8, 0x03, 0x00, 0x02, 0xF8, 0x03, 0x00, 0x02, 0xF8, 0x03, // 216
- 0x00, 0x00, 0xF8, 0x03, 0x00, 0x02, 0xF8, 0x03, 0x00, 0x02, 0xF8, 0x03, 0x00, 0x06, // 217
- 0x00, 0x00, 0x08, 0x00, 0xF8, 0x03, 0x40, 0x02, 0x40, 0x02, 0x80, 0x01, // 218
- 0x00, 0x00, 0xF8, 0x03, 0x40, 0x02, 0x40, 0x02, 0x80, 0x01, 0xF8, 0x03, // 219
- 0x00, 0x00, 0xF8, 0x03, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x80, 0x01, // 220
- 0x00, 0x00, 0x10, 0x01, 0x08, 0x02, 0x48, 0x02, 0x48, 0x02, 0xF0, 0x01, // 221
- 0x00, 0x00, 0xF8, 0x03, 0x40, 0x00, 0xF0, 0x01, 0x08, 0x02, 0xF0, 0x01, // 222
- 0x00, 0x00, 0x30, 0x02, 0x48, 0x01, 0xC8, 0x00, 0x48, 0x00, 0xF8, 0x03, // 223
- 0x00, 0x00, 0x00, 0x01, 0xA0, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x03, // 224
- 0x00, 0x00, 0xE0, 0x01, 0x50, 0x02, 0x50, 0x02, 0x48, 0x02, 0x88, 0x01, // 225
- 0x00, 0x00, 0xE0, 0x03, 0xA0, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0x40, 0x01, // 226
- 0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x60, // 227
- 0x00, 0x00, 0x00, 0x02, 0xC0, 0x03, 0x20, 0x02, 0xE0, 0x03, 0x00, 0x02, // 228
- 0x00, 0x00, 0xC0, 0x01, 0xA0, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0xC0, // 229
- 0x00, 0x00, 0x60, 0x03, 0x80, 0x00, 0xE0, 0x03, 0x80, 0x00, 0x60, 0x03, // 230
- 0x00, 0x00, 0x20, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0x40, 0x01, // 231
- 0x00, 0x00, 0xE0, 0x03, 0x00, 0x01, 0x80, 0x00, 0x40, 0x00, 0xE0, 0x03, // 232
- 0x00, 0x00, 0xE0, 0x03, 0x00, 0x01, 0x98, 0x00, 0x40, 0x00, 0xE0, 0x03, // 233
- 0x00, 0x00, 0xE0, 0x03, 0x80, 0x00, 0x80, 0x00, 0x40, 0x01, 0x20, 0x02, // 234
- 0x00, 0x00, 0x00, 0x02, 0xC0, 0x01, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x03, // 235
- 0x00, 0x00, 0xE0, 0x03, 0x40, 0x00, 0x80, 0x00, 0x40, 0x00, 0xE0, 0x03, // 236
- 0x00, 0x00, 0xE0, 0x03, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xE0, 0x03, // 237
- 0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 238
- 0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x03, // 239
- 0x00, 0x00, 0xE0, 0x03, 0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0x40, // 240
- 0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0x40, 0x02, // 241
- 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, // 242
- 0x00, 0x00, 0x60, 0x00, 0x80, 0x02, 0x80, 0x02, 0x80, 0x02, 0xE0, 0x01, // 243
- 0x00, 0x00, 0xC0, 0x00, 0x20, 0x01, 0xE0, 0x03, 0x20, 0x01, 0xC0, // 244
- 0x00, 0x00, 0x20, 0x02, 0x40, 0x01, 0x80, 0x00, 0x40, 0x01, 0x20, 0x02, // 245
- 0x00, 0x00, 0xE0, 0x03, 0x00, 0x02, 0x00, 0x02, 0xE0, 0x03, 0x00, 0x02, // 246
- 0x00, 0x00, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xE0, 0x03, // 247
- 0x00, 0x00, 0xE0, 0x03, 0x00, 0x02, 0xE0, 0x03, 0x00, 0x02, 0xE0, 0x03, // 248
- 0x00, 0x00, 0xE0, 0x03, 0x00, 0x02, 0xE0, 0x03, 0x00, 0x02, 0xE0, 0x03, 0x00, 0x06, // 249
- 0x00, 0x00, 0x20, 0x00, 0xE0, 0x03, 0x80, 0x02, 0x80, 0x02, 0x00, 0x01, // 250
- 0x00, 0x00, 0xE0, 0x03, 0x80, 0x02, 0x80, 0x02, 0x00, 0x01, 0xE0, 0x03, // 251
- 0x00, 0x00, 0xE0, 0x03, 0x80, 0x02, 0x80, 0x02, 0x80, 0x02, 0x00, 0x01, // 252
- 0x00, 0x00, 0x40, 0x01, 0x20, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x01, // 253
- 0x00, 0x00, 0xE0, 0x03, 0x80, 0x00, 0xC0, 0x01, 0x20, 0x02, 0xC0, 0x01, // 254
- 0x00, 0x00, 0x40, 0x02, 0xA0, 0x01, 0xA0, 0x00, 0xA0, 0x00, 0xE0, 0x03, // 255
+ 0x0A, // Width: 10
+ 0x0D, // Height: 13
+ 0x20, // First char: 32
+ 0xE0, // Number of chars: 224
+
+ // Jump Table:
+ 0xFF, 0xFF, 0x00, 0x0A, // 32
+ 0x00, 0x00, 0x04, 0x03, // 33
+ 0x00, 0x04, 0x05, 0x04, // 34
+ 0x00, 0x09, 0x09, 0x06, // 35
+ 0x00, 0x12, 0x0A, 0x06, // 36
+ 0x00, 0x1C, 0x10, 0x09, // 37
+ 0x00, 0x2C, 0x0E, 0x08, // 38
+ 0x00, 0x3A, 0x01, 0x02, // 39
+ 0x00, 0x3B, 0x06, 0x04, // 40
+ 0x00, 0x41, 0x06, 0x04, // 41
+ 0x00, 0x47, 0x05, 0x04, // 42
+ 0x00, 0x4C, 0x09, 0x06, // 43
+ 0x00, 0x55, 0x04, 0x03, // 44
+ 0x00, 0x59, 0x03, 0x03, // 45
+ 0x00, 0x5C, 0x04, 0x03, // 46
+ 0x00, 0x60, 0x05, 0x04, // 47
+ 0x00, 0x65, 0x0A, 0x06, // 48
+ 0x00, 0x6F, 0x08, 0x05, // 49
+ 0x00, 0x77, 0x0A, 0x06, // 50
+ 0x00, 0x81, 0x0A, 0x06, // 51
+ 0x00, 0x8B, 0x0B, 0x07, // 52
+ 0x00, 0x96, 0x0A, 0x06, // 53
+ 0x00, 0xA0, 0x0A, 0x06, // 54
+ 0x00, 0xAA, 0x09, 0x06, // 55
+ 0x00, 0xB3, 0x0A, 0x06, // 56
+ 0x00, 0xBD, 0x0A, 0x06, // 57
+ 0x00, 0xC7, 0x04, 0x03, // 58
+ 0x00, 0xCB, 0x04, 0x03, // 59
+ 0x00, 0xCF, 0x0A, 0x06, // 60
+ 0x00, 0xD9, 0x09, 0x06, // 61
+ 0x00, 0xE2, 0x09, 0x06, // 62
+ 0x00, 0xEB, 0x0B, 0x07, // 63
+ 0x00, 0xF6, 0x14, 0x0B, // 64
+ 0x01, 0x0A, 0x0E, 0x08, // 65
+ 0x01, 0x18, 0x0C, 0x07, // 66
+ 0x01, 0x24, 0x0C, 0x07, // 67
+ 0x01, 0x30, 0x0B, 0x07, // 68
+ 0x01, 0x3B, 0x0C, 0x07, // 69
+ 0x01, 0x47, 0x09, 0x06, // 70
+ 0x01, 0x50, 0x0D, 0x08, // 71
+ 0x01, 0x5D, 0x0C, 0x07, // 72
+ 0x01, 0x69, 0x04, 0x03, // 73
+ 0x01, 0x6D, 0x08, 0x05, // 74
+ 0x01, 0x75, 0x0E, 0x08, // 75
+ 0x01, 0x83, 0x0C, 0x07, // 76
+ 0x01, 0x8F, 0x10, 0x09, // 77
+ 0x01, 0x9F, 0x0C, 0x07, // 78
+ 0x01, 0xAB, 0x0E, 0x08, // 79
+ 0x01, 0xB9, 0x0B, 0x07, // 80
+ 0x01, 0xC4, 0x0E, 0x08, // 81
+ 0x01, 0xD2, 0x0C, 0x07, // 82
+ 0x01, 0xDE, 0x0C, 0x07, // 83
+ 0x01, 0xEA, 0x0B, 0x07, // 84
+ 0x01, 0xF5, 0x0C, 0x07, // 85
+ 0x02, 0x01, 0x0D, 0x08, // 86
+ 0x02, 0x0E, 0x11, 0x0A, // 87
+ 0x02, 0x1F, 0x0E, 0x08, // 88
+ 0x02, 0x2D, 0x0D, 0x08, // 89
+ 0x02, 0x3A, 0x0C, 0x07, // 90
+ 0x02, 0x46, 0x06, 0x04, // 91
+ 0x02, 0x4C, 0x06, 0x04, // 92
+ 0x02, 0x52, 0x04, 0x03, // 93
+ 0x02, 0x56, 0x09, 0x06, // 94
+ 0x02, 0x5F, 0x0C, 0x07, // 95
+ 0x02, 0x6B, 0x03, 0x03, // 96
+ 0x02, 0x6E, 0x0A, 0x06, // 97
+ 0x02, 0x78, 0x0A, 0x06, // 98
+ 0x02, 0x82, 0x0A, 0x06, // 99
+ 0x02, 0x8C, 0x0A, 0x06, // 100
+ 0x02, 0x96, 0x0A, 0x06, // 101
+ 0x02, 0xA0, 0x05, 0x04, // 102
+ 0x02, 0xA5, 0x0A, 0x06, // 103
+ 0x02, 0xAF, 0x0A, 0x06, // 104
+ 0x02, 0xB9, 0x04, 0x03, // 105
+ 0x02, 0xBD, 0x04, 0x03, // 106
+ 0x02, 0xC1, 0x08, 0x05, // 107
+ 0x02, 0xC9, 0x04, 0x03, // 108
+ 0x02, 0xCD, 0x10, 0x09, // 109
+ 0x02, 0xDD, 0x0A, 0x06, // 110
+ 0x02, 0xE7, 0x0A, 0x06, // 111
+ 0x02, 0xF1, 0x0A, 0x06, // 112
+ 0x02, 0xFB, 0x0A, 0x06, // 113
+ 0x03, 0x05, 0x05, 0x04, // 114
+ 0x03, 0x0A, 0x08, 0x05, // 115
+ 0x03, 0x12, 0x06, 0x04, // 116
+ 0x03, 0x18, 0x0A, 0x06, // 117
+ 0x03, 0x22, 0x09, 0x06, // 118
+ 0x03, 0x2B, 0x0E, 0x08, // 119
+ 0x03, 0x39, 0x0A, 0x06, // 120
+ 0x03, 0x43, 0x09, 0x06, // 121
+ 0x03, 0x4C, 0x0A, 0x06, // 122
+ 0x03, 0x56, 0x06, 0x04, // 123
+ 0x03, 0x5C, 0x04, 0x03, // 124
+ 0x03, 0x60, 0x05, 0x04, // 125
+ 0x03, 0x65, 0x09, 0x06, // 126
+ 0xFF, 0xFF, 0x00, 0x0A, // 127
+ 0xFF, 0xFF, 0x00, 0x0A, // 128
+ 0xFF, 0xFF, 0x00, 0x0A, // 129
+ 0xFF, 0xFF, 0x00, 0x0A, // 130
+ 0xFF, 0xFF, 0x00, 0x0A, // 131
+ 0xFF, 0xFF, 0x00, 0x0A, // 132
+ 0xFF, 0xFF, 0x00, 0x0A, // 133
+ 0xFF, 0xFF, 0x00, 0x0A, // 134
+ 0xFF, 0xFF, 0x00, 0x0A, // 135
+ 0xFF, 0xFF, 0x00, 0x0A, // 136
+ 0xFF, 0xFF, 0x00, 0x0A, // 137
+ 0xFF, 0xFF, 0x00, 0x0A, // 138
+ 0xFF, 0xFF, 0x00, 0x0A, // 139
+ 0xFF, 0xFF, 0x00, 0x0A, // 140
+ 0xFF, 0xFF, 0x00, 0x0A, // 141
+ 0xFF, 0xFF, 0x00, 0x0A, // 142
+ 0xFF, 0xFF, 0x00, 0x0A, // 143
+ 0xFF, 0xFF, 0x00, 0x0A, // 144
+ 0xFF, 0xFF, 0x00, 0x0A, // 145
+ 0xFF, 0xFF, 0x00, 0x0A, // 146
+ 0xFF, 0xFF, 0x00, 0x0A, // 147
+ 0xFF, 0xFF, 0x00, 0x0A, // 148
+ 0xFF, 0xFF, 0x00, 0x0A, // 149
+ 0xFF, 0xFF, 0x00, 0x0A, // 150
+ 0xFF, 0xFF, 0x00, 0x0A, // 151
+ 0xFF, 0xFF, 0x00, 0x0A, // 152
+ 0xFF, 0xFF, 0x00, 0x0A, // 153
+ 0xFF, 0xFF, 0x00, 0x0A, // 154
+ 0xFF, 0xFF, 0x00, 0x0A, // 155
+ 0xFF, 0xFF, 0x00, 0x0A, // 156
+ 0xFF, 0xFF, 0x00, 0x0A, // 157
+ 0xFF, 0xFF, 0x00, 0x0A, // 158
+ 0xFF, 0xFF, 0x00, 0x0A, // 159
+ 0xFF, 0xFF, 0x00, 0x0A, // 160
+ 0x03, 0x6E, 0x04, 0x03, // 161
+ 0x03, 0x72, 0x0A, 0x06, // 162
+ 0x03, 0x7C, 0x0C, 0x07, // 163
+ 0x03, 0x88, 0x0A, 0x06, // 164
+ 0x03, 0x92, 0x0A, 0x06, // 165
+ 0x03, 0x9C, 0x04, 0x03, // 166
+ 0x03, 0xA0, 0x0A, 0x06, // 167
+ 0x03, 0xAA, 0x0C, 0x07, // 168
+ 0x03, 0xB6, 0x0D, 0x08, // 169
+ 0x03, 0xC3, 0x07, 0x05, // 170
+ 0x03, 0xCA, 0x0A, 0x06, // 171
+ 0x03, 0xD4, 0x09, 0x06, // 172
+ 0x03, 0xDD, 0x03, 0x03, // 173
+ 0x03, 0xE0, 0x0D, 0x08, // 174
+ 0x03, 0xED, 0x0B, 0x07, // 175
+ 0x03, 0xF8, 0x07, 0x05, // 176
+ 0x03, 0xFF, 0x0A, 0x06, // 177
+ 0x04, 0x09, 0x05, 0x04, // 178
+ 0x04, 0x0E, 0x05, 0x04, // 179
+ 0x04, 0x13, 0x05, 0x04, // 180
+ 0x04, 0x18, 0x0A, 0x06, // 181
+ 0x04, 0x22, 0x09, 0x06, // 182
+ 0x04, 0x2B, 0x03, 0x03, // 183
+ 0x04, 0x2E, 0x0B, 0x07, // 184
+ 0x04, 0x39, 0x0B, 0x07, // 185
+ 0x04, 0x44, 0x07, 0x05, // 186
+ 0x04, 0x4B, 0x0A, 0x06, // 187
+ 0x04, 0x55, 0x10, 0x09, // 188
+ 0x04, 0x65, 0x10, 0x09, // 189
+ 0x04, 0x75, 0x10, 0x09, // 190
+ 0x04, 0x85, 0x0A, 0x06, // 191
+ 0x04, 0x8F, 0x0C, 0x07, // 192
+ 0x04, 0x9B, 0x0C, 0x07, // 193
+ 0x04, 0xA7, 0x0C, 0x07, // 194
+ 0x04, 0xB3, 0x0B, 0x07, // 195
+ 0x04, 0xBE, 0x0C, 0x07, // 196
+ 0x04, 0xCA, 0x0C, 0x07, // 197
+ 0x04, 0xD6, 0x0C, 0x07, // 198
+ 0x04, 0xE2, 0x0C, 0x07, // 199
+ 0x04, 0xEE, 0x0C, 0x07, // 200
+ 0x04, 0xFA, 0x0C, 0x07, // 201
+ 0x05, 0x06, 0x0C, 0x07, // 202
+ 0x05, 0x12, 0x0C, 0x07, // 203
+ 0x05, 0x1E, 0x0C, 0x07, // 204
+ 0x05, 0x2A, 0x0C, 0x07, // 205
+ 0x05, 0x36, 0x0C, 0x07, // 206
+ 0x05, 0x42, 0x0C, 0x07, // 207
+ 0x05, 0x4E, 0x0B, 0x07, // 208
+ 0x05, 0x59, 0x0C, 0x07, // 209
+ 0x05, 0x65, 0x0B, 0x07, // 210
+ 0x05, 0x70, 0x0C, 0x07, // 211
+ 0x05, 0x7C, 0x0B, 0x07, // 212
+ 0x05, 0x87, 0x0C, 0x07, // 213
+ 0x05, 0x93, 0x0C, 0x07, // 214
+ 0x05, 0x9F, 0x0C, 0x07, // 215
+ 0x05, 0xAB, 0x0C, 0x07, // 216
+ 0x05, 0xB7, 0x0E, 0x08, // 217
+ 0x05, 0xC5, 0x0C, 0x07, // 218
+ 0x05, 0xD1, 0x0C, 0x07, // 219
+ 0x05, 0xDD, 0x0C, 0x07, // 220
+ 0x05, 0xE9, 0x0C, 0x07, // 221
+ 0x05, 0xF5, 0x0C, 0x07, // 222
+ 0x06, 0x01, 0x0C, 0x07, // 223
+ 0x06, 0x0D, 0x0C, 0x07, // 224
+ 0x06, 0x19, 0x0C, 0x07, // 225
+ 0x06, 0x25, 0x0C, 0x07, // 226
+ 0x06, 0x31, 0x0B, 0x07, // 227
+ 0x06, 0x3C, 0x0C, 0x07, // 228
+ 0x06, 0x48, 0x0B, 0x07, // 229
+ 0x06, 0x53, 0x0C, 0x07, // 230
+ 0x06, 0x5F, 0x0C, 0x07, // 231
+ 0x06, 0x6B, 0x0C, 0x07, // 232
+ 0x06, 0x77, 0x0C, 0x07, // 233
+ 0x06, 0x83, 0x0C, 0x07, // 234
+ 0x06, 0x8F, 0x0C, 0x07, // 235
+ 0x06, 0x9B, 0x0C, 0x07, // 236
+ 0x06, 0xA7, 0x0C, 0x07, // 237
+ 0x06, 0xB3, 0x0C, 0x07, // 238
+ 0x06, 0xBF, 0x0C, 0x07, // 239
+ 0x06, 0xCB, 0x0B, 0x07, // 240
+ 0x06, 0xD6, 0x0C, 0x07, // 241
+ 0x06, 0xE2, 0x0B, 0x07, // 242
+ 0x06, 0xED, 0x0C, 0x07, // 243
+ 0x06, 0xF9, 0x0B, 0x07, // 244
+ 0x07, 0x04, 0x0C, 0x07, // 245
+ 0x07, 0x10, 0x0C, 0x07, // 246
+ 0x07, 0x1C, 0x0C, 0x07, // 247
+ 0x07, 0x28, 0x0C, 0x07, // 248
+ 0x07, 0x34, 0x0E, 0x08, // 249
+ 0x07, 0x42, 0x0C, 0x07, // 250
+ 0x07, 0x4E, 0x0C, 0x07, // 251
+ 0x07, 0x5A, 0x0C, 0x07, // 252
+ 0x07, 0x66, 0x0C, 0x07, // 253
+ 0x07, 0x72, 0x0C, 0x07, // 254
+ 0x07, 0x7E, 0x0C, 0x07, // 255
+
+ // Font Data:
+ 0x00, 0x00, 0xF8, 0x02, // 33
+ 0x38, 0x00, 0x00, 0x00, 0x38, // 34
+ 0xA0, 0x03, 0xE0, 0x00, 0xB8, 0x03, 0xE0, 0x00, 0xB8, // 35
+ 0x30, 0x01, 0x28, 0x02, 0xF8, 0x07, 0x48, 0x02, 0x90, 0x01, // 36
+ 0x00, 0x00, 0x30, 0x00, 0x48, 0x00, 0x30, 0x03, 0xC0, 0x00, 0xB0, 0x01, 0x48, 0x02, 0x80, 0x01, // 37
+ 0x80, 0x01, 0x50, 0x02, 0x68, 0x02, 0xA8, 0x02, 0x18, 0x01, 0x80, 0x03, 0x80, 0x02, // 38
+ 0x38, // 39
+ 0xE0, 0x03, 0x10, 0x04, 0x08, 0x08, // 40
+ 0x08, 0x08, 0x10, 0x04, 0xE0, 0x03, // 41
+ 0x28, 0x00, 0x18, 0x00, 0x28, // 42
+ 0x40, 0x00, 0x40, 0x00, 0xF0, 0x01, 0x40, 0x00, 0x40, // 43
+ 0x00, 0x00, 0x00, 0x06, // 44
+ 0x80, 0x00, 0x80, // 45
+ 0x00, 0x00, 0x00, 0x02, // 46
+ 0x00, 0x03, 0xE0, 0x00, 0x18, // 47
+ 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0xF0, 0x01, // 48
+ 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0xF8, 0x03, // 49
+ 0x10, 0x02, 0x08, 0x03, 0x88, 0x02, 0x48, 0x02, 0x30, 0x02, // 50
+ 0x10, 0x01, 0x08, 0x02, 0x48, 0x02, 0x48, 0x02, 0xB0, 0x01, // 51
+ 0xC0, 0x00, 0xA0, 0x00, 0x90, 0x00, 0x88, 0x00, 0xF8, 0x03, 0x80, // 52
+ 0x60, 0x01, 0x38, 0x02, 0x28, 0x02, 0x28, 0x02, 0xC8, 0x01, // 53
+ 0xF0, 0x01, 0x28, 0x02, 0x28, 0x02, 0x28, 0x02, 0xD0, 0x01, // 54
+ 0x08, 0x00, 0x08, 0x03, 0xC8, 0x00, 0x38, 0x00, 0x08, // 55
+ 0xB0, 0x01, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xB0, 0x01, // 56
+ 0x70, 0x01, 0x88, 0x02, 0x88, 0x02, 0x88, 0x02, 0xF0, 0x01, // 57
+ 0x00, 0x00, 0x20, 0x02, // 58
+ 0x00, 0x00, 0x20, 0x06, // 59
+ 0x00, 0x00, 0x40, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0x10, 0x01, // 60
+ 0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0xA0, // 61
+ 0x00, 0x00, 0x10, 0x01, 0xA0, 0x00, 0xA0, 0x00, 0x40, // 62
+ 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0xC8, 0x02, 0x48, 0x00, 0x30, // 63
+ 0x00, 0x00, 0xC0, 0x03, 0x30, 0x04, 0xD0, 0x09, 0x28, 0x0A, 0x28, 0x0A, 0xC8, 0x0B, 0x68, 0x0A, 0x10, 0x05, 0xE0, 0x04, // 64
+ 0x00, 0x02, 0xC0, 0x01, 0xB0, 0x00, 0x88, 0x00, 0xB0, 0x00, 0xC0, 0x01, 0x00, 0x02, // 65
+ 0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xF0, 0x01, // 66
+ 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x10, 0x01, // 67
+ 0x00, 0x00, 0xF8, 0x03, 0x08, 0x02, 0x08, 0x02, 0x10, 0x01, 0xE0, // 68
+ 0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, // 69
+ 0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0x08, // 70
+ 0x00, 0x00, 0xE0, 0x00, 0x10, 0x01, 0x08, 0x02, 0x48, 0x02, 0x50, 0x01, 0xC0, // 71
+ 0x00, 0x00, 0xF8, 0x03, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xF8, 0x03, // 72
+ 0x00, 0x00, 0xF8, 0x03, // 73
+ 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0xF8, 0x01, // 74
+ 0x00, 0x00, 0xF8, 0x03, 0x80, 0x00, 0x60, 0x00, 0x90, 0x00, 0x08, 0x01, 0x00, 0x02, // 75
+ 0x00, 0x00, 0xF8, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, // 76
+ 0x00, 0x00, 0xF8, 0x03, 0x30, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x30, 0x00, 0xF8, 0x03, // 77
+ 0x00, 0x00, 0xF8, 0x03, 0x30, 0x00, 0x40, 0x00, 0x80, 0x01, 0xF8, 0x03, // 78
+ 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0xF0, 0x01, // 79
+ 0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x30, // 80
+ 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x03, 0x08, 0x03, 0xF0, 0x02, // 81
+ 0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0xC8, 0x00, 0x30, 0x03, // 82
+ 0x00, 0x00, 0x30, 0x01, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x90, 0x01, // 83
+ 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0xF8, 0x03, 0x08, 0x00, 0x08, // 84
+ 0x00, 0x00, 0xF8, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0xF8, 0x01, // 85
+ 0x08, 0x00, 0x70, 0x00, 0x80, 0x01, 0x00, 0x02, 0x80, 0x01, 0x70, 0x00, 0x08, // 86
+ 0x18, 0x00, 0xE0, 0x01, 0x00, 0x02, 0xF0, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x02, 0xE0, 0x01, 0x18, // 87
+ 0x00, 0x02, 0x08, 0x01, 0x90, 0x00, 0x60, 0x00, 0x90, 0x00, 0x08, 0x01, 0x00, 0x02, // 88
+ 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0xC0, 0x03, 0x20, 0x00, 0x10, 0x00, 0x08, // 89
+ 0x08, 0x03, 0x88, 0x02, 0xC8, 0x02, 0x68, 0x02, 0x38, 0x02, 0x18, 0x02, // 90
+ 0x00, 0x00, 0xF8, 0x0F, 0x08, 0x08, // 91
+ 0x18, 0x00, 0xE0, 0x00, 0x00, 0x03, // 92
+ 0x08, 0x08, 0xF8, 0x0F, // 93
+ 0x40, 0x00, 0x30, 0x00, 0x08, 0x00, 0x30, 0x00, 0x40, // 94
+ 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, // 95
+ 0x08, 0x00, 0x10, // 96
+ 0x00, 0x00, 0x00, 0x03, 0xA0, 0x02, 0xA0, 0x02, 0xE0, 0x03, // 97
+ 0x00, 0x00, 0xF8, 0x03, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 98
+ 0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0x40, 0x01, // 99
+ 0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0xF8, 0x03, // 100
+ 0x00, 0x00, 0xC0, 0x01, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x02, // 101
+ 0x20, 0x00, 0xF0, 0x03, 0x28, // 102
+ 0x00, 0x00, 0xC0, 0x05, 0x20, 0x0A, 0x20, 0x0A, 0xE0, 0x07, // 103
+ 0x00, 0x00, 0xF8, 0x03, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x03, // 104
+ 0x00, 0x00, 0xE8, 0x03, // 105
+ 0x00, 0x08, 0xE8, 0x07, // 106
+ 0xF8, 0x03, 0x80, 0x00, 0xC0, 0x01, 0x20, 0x02, // 107
+ 0x00, 0x00, 0xF8, 0x03, // 108
+ 0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x03, // 109
+ 0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x03, // 110
+ 0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 111
+ 0x00, 0x00, 0xE0, 0x0F, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 112
+ 0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0xE0, 0x0F, // 113
+ 0x00, 0x00, 0xE0, 0x03, 0x20, // 114
+ 0x40, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0x20, 0x01, // 115
+ 0x20, 0x00, 0xF8, 0x03, 0x20, 0x02, // 116
+ 0x00, 0x00, 0xE0, 0x01, 0x00, 0x02, 0x00, 0x02, 0xE0, 0x03, // 117
+ 0x20, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x20, // 118
+ 0xE0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x20, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xE0, 0x01, // 119
+ 0x20, 0x02, 0x40, 0x01, 0x80, 0x00, 0x40, 0x01, 0x20, 0x02, // 120
+ 0x20, 0x00, 0xC0, 0x09, 0x00, 0x06, 0xC0, 0x01, 0x20, // 121
+ 0x20, 0x02, 0x20, 0x03, 0xA0, 0x02, 0x60, 0x02, 0x20, 0x02, // 122
+ 0x80, 0x00, 0x78, 0x0F, 0x08, 0x08, // 123
+ 0x00, 0x00, 0xF8, 0x0F, // 124
+ 0x08, 0x08, 0x78, 0x0F, 0x80, // 125
+ 0xC0, 0x00, 0x40, 0x00, 0xC0, 0x00, 0x80, 0x00, 0xC0, // 126
+ 0x00, 0x00, 0xA0, 0x0F, // 161
+ 0x00, 0x00, 0xC0, 0x01, 0xA0, 0x0F, 0x78, 0x02, 0x40, 0x01, // 162
+ 0x40, 0x02, 0x70, 0x03, 0xC8, 0x02, 0x48, 0x02, 0x08, 0x02, 0x10, 0x02, // 163
+ 0x00, 0x00, 0xE0, 0x01, 0x20, 0x01, 0x20, 0x01, 0xE0, 0x01, // 164
+ 0x48, 0x01, 0x70, 0x01, 0xC0, 0x03, 0x70, 0x01, 0x48, 0x01, // 165
+ 0x00, 0x00, 0x38, 0x0F, // 166
+ 0xD0, 0x04, 0x28, 0x09, 0x48, 0x09, 0x48, 0x0A, 0x90, 0x05, // 167
+ 0x00, 0x00, 0xE0, 0x03, 0xA8, 0x02, 0xA0, 0x02, 0xA8, 0x02, 0x20, 0x02, // 168
+ 0xE0, 0x00, 0x10, 0x01, 0x48, 0x02, 0xA8, 0x02, 0xA8, 0x02, 0x10, 0x01, 0xE0, // 169
+ 0x68, 0x00, 0x68, 0x00, 0x68, 0x00, 0x78, // 170
+ 0x00, 0x00, 0x80, 0x01, 0x40, 0x02, 0x80, 0x01, 0x40, 0x02, // 171
+ 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xE0, // 172
+ 0x80, 0x00, 0x80, // 173
+ 0xE0, 0x00, 0x10, 0x01, 0xE8, 0x02, 0x68, 0x02, 0xC8, 0x02, 0x10, 0x01, 0xE0, // 174
+ 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, // 175
+ 0x00, 0x00, 0x38, 0x00, 0x28, 0x00, 0x38, // 176
+ 0x40, 0x02, 0x40, 0x02, 0xF0, 0x03, 0x40, 0x02, 0x40, 0x02, // 177
+ 0x48, 0x00, 0x68, 0x00, 0x58, // 178
+ 0x48, 0x00, 0x58, 0x00, 0x68, // 179
+ 0x00, 0x00, 0x10, 0x00, 0x08, // 180
+ 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x02, 0x00, 0x02, 0xE0, 0x03, // 181
+ 0x70, 0x00, 0xF8, 0x0F, 0x08, 0x00, 0xF8, 0x0F, 0x08, // 182
+ 0x00, 0x00, 0x40, // 183
+ 0x00, 0x00, 0xC0, 0x01, 0xA8, 0x02, 0xA0, 0x02, 0xA8, 0x02, 0xC0, // 184
+ 0x00, 0x00, 0xF0, 0x03, 0x40, 0x00, 0x80, 0x00, 0xF8, 0x03, 0x08, // 185
+ 0x30, 0x00, 0x48, 0x00, 0x48, 0x00, 0x30, // 186
+ 0x00, 0x00, 0x40, 0x02, 0x80, 0x01, 0x40, 0x02, 0x80, 0x01, // 187
+ 0x00, 0x00, 0x10, 0x02, 0x78, 0x01, 0xC0, 0x00, 0x20, 0x01, 0x90, 0x01, 0xC8, 0x03, 0x00, 0x01, // 188
+ 0x00, 0x00, 0x10, 0x02, 0x78, 0x01, 0x80, 0x00, 0x60, 0x00, 0x50, 0x02, 0x48, 0x03, 0xC0, 0x02, // 189
+ 0x48, 0x00, 0x58, 0x00, 0x68, 0x03, 0x80, 0x00, 0x60, 0x01, 0x90, 0x01, 0xC8, 0x03, 0x00, 0x01, // 190
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x09, 0xA0, 0x09, 0x00, 0x04, // 191
+ 0x00, 0x00, 0xF0, 0x03, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0xF0, 0x03, // 192
+ 0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x88, 0x01, // 193
+ 0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xB0, 0x01, // 194
+ 0x00, 0x00, 0xF8, 0x03, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x18, // 195
+ 0x00, 0x00, 0x00, 0x02, 0xFC, 0x03, 0x04, 0x02, 0xFC, 0x03, 0x00, 0x02, // 196
+ 0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x08, 0x02, // 197
+ 0x00, 0x00, 0xB8, 0x03, 0x40, 0x00, 0xF8, 0x03, 0x40, 0x00, 0xB8, 0x03, // 198
+ 0x00, 0x00, 0x08, 0x02, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xB0, 0x01, // 199
+ 0x00, 0x00, 0xF8, 0x03, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0xF8, 0x03, // 200
+ 0x00, 0x00, 0xE0, 0x03, 0x08, 0x01, 0x90, 0x00, 0x48, 0x00, 0xE0, 0x03, // 201
+ 0x00, 0x00, 0xF8, 0x03, 0x40, 0x00, 0xA0, 0x00, 0x10, 0x01, 0x08, 0x02, // 202
+ 0x00, 0x00, 0x00, 0x02, 0xF0, 0x01, 0x08, 0x00, 0x08, 0x00, 0xF8, 0x03, // 203
+ 0x00, 0x00, 0xF8, 0x03, 0x10, 0x00, 0x60, 0x00, 0x10, 0x00, 0xF8, 0x03, // 204
+ 0x00, 0x00, 0xF8, 0x03, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xF8, 0x03, // 205
+ 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0xF0, 0x01, // 206
+ 0x00, 0x00, 0xF8, 0x03, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0xF8, 0x03, // 207
+ 0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x30, // 208
+ 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x10, 0x01, // 209
+ 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0xF8, 0x03, 0x08, 0x00, 0x08, // 210
+ 0x00, 0x00, 0x38, 0x00, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0xF8, 0x01, // 211
+ 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, 0xF8, 0x03, 0x88, 0x00, 0x70, // 212
+ 0x00, 0x00, 0x18, 0x03, 0xA0, 0x00, 0x40, 0x00, 0xA0, 0x00, 0x18, 0x03, // 213
+ 0x00, 0x00, 0xF8, 0x03, 0x00, 0x02, 0x00, 0x02, 0xF8, 0x03, 0x00, 0x02, // 214
+ 0x00, 0x00, 0x38, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xF8, 0x03, // 215
+ 0x00, 0x00, 0xF8, 0x03, 0x00, 0x02, 0xF8, 0x03, 0x00, 0x02, 0xF8, 0x03, // 216
+ 0x00, 0x00, 0xF8, 0x03, 0x00, 0x02, 0xF8, 0x03, 0x00, 0x02, 0xF8, 0x03, 0x00, 0x06, // 217
+ 0x00, 0x00, 0x08, 0x00, 0xF8, 0x03, 0x40, 0x02, 0x40, 0x02, 0x80, 0x01, // 218
+ 0x00, 0x00, 0xF8, 0x03, 0x40, 0x02, 0x40, 0x02, 0x80, 0x01, 0xF8, 0x03, // 219
+ 0x00, 0x00, 0xF8, 0x03, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x80, 0x01, // 220
+ 0x00, 0x00, 0x10, 0x01, 0x08, 0x02, 0x48, 0x02, 0x48, 0x02, 0xF0, 0x01, // 221
+ 0x00, 0x00, 0xF8, 0x03, 0x40, 0x00, 0xF0, 0x01, 0x08, 0x02, 0xF0, 0x01, // 222
+ 0x00, 0x00, 0x30, 0x02, 0x48, 0x01, 0xC8, 0x00, 0x48, 0x00, 0xF8, 0x03, // 223
+ 0x00, 0x00, 0x00, 0x01, 0xA0, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x03, // 224
+ 0x00, 0x00, 0xE0, 0x01, 0x50, 0x02, 0x50, 0x02, 0x48, 0x02, 0x88, 0x01, // 225
+ 0x00, 0x00, 0xE0, 0x03, 0xA0, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0x40, 0x01, // 226
+ 0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x60, // 227
+ 0x00, 0x00, 0x00, 0x02, 0xC0, 0x03, 0x20, 0x02, 0xE0, 0x03, 0x00, 0x02, // 228
+ 0x00, 0x00, 0xC0, 0x01, 0xA0, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0xC0, // 229
+ 0x00, 0x00, 0x60, 0x03, 0x80, 0x00, 0xE0, 0x03, 0x80, 0x00, 0x60, 0x03, // 230
+ 0x00, 0x00, 0x20, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0x40, 0x01, // 231
+ 0x00, 0x00, 0xE0, 0x03, 0x00, 0x01, 0x80, 0x00, 0x40, 0x00, 0xE0, 0x03, // 232
+ 0x00, 0x00, 0xE0, 0x03, 0x00, 0x01, 0x98, 0x00, 0x40, 0x00, 0xE0, 0x03, // 233
+ 0x00, 0x00, 0xE0, 0x03, 0x80, 0x00, 0x80, 0x00, 0x40, 0x01, 0x20, 0x02, // 234
+ 0x00, 0x00, 0x00, 0x02, 0xC0, 0x01, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x03, // 235
+ 0x00, 0x00, 0xE0, 0x03, 0x40, 0x00, 0x80, 0x00, 0x40, 0x00, 0xE0, 0x03, // 236
+ 0x00, 0x00, 0xE0, 0x03, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xE0, 0x03, // 237
+ 0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 238
+ 0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x03, // 239
+ 0x00, 0x00, 0xE0, 0x03, 0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0x40, // 240
+ 0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0x20, 0x02, 0x40, 0x02, // 241
+ 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, // 242
+ 0x00, 0x00, 0x60, 0x00, 0x80, 0x02, 0x80, 0x02, 0x80, 0x02, 0xE0, 0x01, // 243
+ 0x00, 0x00, 0xC0, 0x00, 0x20, 0x01, 0xE0, 0x03, 0x20, 0x01, 0xC0, // 244
+ 0x00, 0x00, 0x20, 0x02, 0x40, 0x01, 0x80, 0x00, 0x40, 0x01, 0x20, 0x02, // 245
+ 0x00, 0x00, 0xE0, 0x03, 0x00, 0x02, 0x00, 0x02, 0xE0, 0x03, 0x00, 0x02, // 246
+ 0x00, 0x00, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xE0, 0x03, // 247
+ 0x00, 0x00, 0xE0, 0x03, 0x00, 0x02, 0xE0, 0x03, 0x00, 0x02, 0xE0, 0x03, // 248
+ 0x00, 0x00, 0xE0, 0x03, 0x00, 0x02, 0xE0, 0x03, 0x00, 0x02, 0xE0, 0x03, 0x00, 0x06, // 249
+ 0x00, 0x00, 0x20, 0x00, 0xE0, 0x03, 0x80, 0x02, 0x80, 0x02, 0x00, 0x01, // 250
+ 0x00, 0x00, 0xE0, 0x03, 0x80, 0x02, 0x80, 0x02, 0x00, 0x01, 0xE0, 0x03, // 251
+ 0x00, 0x00, 0xE0, 0x03, 0x80, 0x02, 0x80, 0x02, 0x80, 0x02, 0x00, 0x01, // 252
+ 0x00, 0x00, 0x40, 0x01, 0x20, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x01, // 253
+ 0x00, 0x00, 0xE0, 0x03, 0x80, 0x00, 0xC0, 0x01, 0x20, 0x02, 0xC0, 0x01, // 254
+ 0x00, 0x00, 0x40, 0x02, 0xA0, 0x01, 0xA0, 0x00, 0xA0, 0x00, 0xE0, 0x03, // 255
};
\ No newline at end of file
diff --git a/src/graphics/images.h b/src/graphics/images.h
index 9bf66a3a3..b1818e32c 100644
--- a/src/graphics/images.h
+++ b/src/graphics/images.h
@@ -6,24 +6,27 @@ const uint8_t SATELLITE_IMAGE[] PROGMEM = {0x00, 0x08, 0x00, 0x1C, 0x00, 0x0E, 0
0xF8, 0x00, 0xF0, 0x01, 0xE0, 0x03, 0xC8, 0x01, 0x9C, 0x54,
0x0E, 0x52, 0x07, 0x48, 0x02, 0x26, 0x00, 0x10, 0x00, 0x0E};
-const uint8_t imgSatellite[] PROGMEM = { 0x70, 0x71, 0x22, 0xFA, 0xFA, 0x22, 0x71, 0x70 };
-const uint8_t imgUSB[] PROGMEM = { 0x60, 0x60, 0x30, 0x18, 0x18, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x24, 0x24, 0x24, 0x3C };
-const uint8_t imgPower[] PROGMEM = { 0x40, 0x40, 0x40, 0x58, 0x48, 0x08, 0x08, 0x08, 0x1C, 0x22, 0x22, 0x41, 0x7F, 0x22, 0x22, 0x22 };
-const uint8_t imgUser[] PROGMEM = { 0x3C, 0x42, 0x99, 0xA5, 0xA5, 0x99, 0x42, 0x3C };
-const uint8_t imgPositionEmpty[] PROGMEM = { 0x20, 0x30, 0x28, 0x24, 0x42, 0xFF };
-const uint8_t imgPositionSolid[] PROGMEM = { 0x20, 0x30, 0x38, 0x3C, 0x7E, 0xFF };
+const uint8_t imgSatellite[] PROGMEM = {0x70, 0x71, 0x22, 0xFA, 0xFA, 0x22, 0x71, 0x70};
+const uint8_t imgUSB[] PROGMEM = {0x60, 0x60, 0x30, 0x18, 0x18, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x24, 0x24, 0x24, 0x3C};
+const uint8_t imgPower[] PROGMEM = {0x40, 0x40, 0x40, 0x58, 0x48, 0x08, 0x08, 0x08,
+ 0x1C, 0x22, 0x22, 0x41, 0x7F, 0x22, 0x22, 0x22};
+const uint8_t imgUser[] PROGMEM = {0x3C, 0x42, 0x99, 0xA5, 0xA5, 0x99, 0x42, 0x3C};
+const uint8_t imgPositionEmpty[] PROGMEM = {0x20, 0x30, 0x28, 0x24, 0x42, 0xFF};
+const uint8_t imgPositionSolid[] PROGMEM = {0x20, 0x30, 0x38, 0x3C, 0x7E, 0xFF};
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
-const uint8_t imgQuestionL1[] PROGMEM = { 0xff, 0x01, 0x01, 0x32, 0x7b, 0x49, 0x49, 0x6f, 0x26, 0x01, 0x01, 0xff };
-const uint8_t imgQuestionL2[] PROGMEM = { 0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f };
-const uint8_t imgInfoL1[] PROGMEM = { 0xff, 0x01, 0x01, 0x01, 0x1e, 0x7f, 0x1e, 0x01, 0x01, 0x01, 0x01, 0xff };
-const uint8_t imgInfoL2[] PROGMEM = { 0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f };
-const uint8_t imgSFL1[] PROGMEM = { 0xb6, 0x8f, 0x19, 0x11, 0x31, 0xe3, 0xc2, 0x01, 0x01, 0xf9, 0xf9, 0x89, 0x89, 0x89, 0x09, 0xeb};
-const uint8_t imgSFL2[] PROGMEM = { 0x0e, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x00, 0x0f, 0x0f, 0x00, 0x08, 0x08, 0x08, 0x0f};
+const uint8_t imgQuestionL1[] PROGMEM = {0xff, 0x01, 0x01, 0x32, 0x7b, 0x49, 0x49, 0x6f, 0x26, 0x01, 0x01, 0xff};
+const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};
+const uint8_t imgInfoL1[] PROGMEM = {0xff, 0x01, 0x01, 0x01, 0x1e, 0x7f, 0x1e, 0x01, 0x01, 0x01, 0x01, 0xff};
+const uint8_t imgInfoL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};
+const uint8_t imgSFL1[] PROGMEM = {0xb6, 0x8f, 0x19, 0x11, 0x31, 0xe3, 0xc2, 0x01,
+ 0x01, 0xf9, 0xf9, 0x89, 0x89, 0x89, 0x09, 0xeb};
+const uint8_t imgSFL2[] PROGMEM = {0x0e, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08,
+ 0x00, 0x0f, 0x0f, 0x00, 0x08, 0x08, 0x08, 0x0f};
#else
-const uint8_t imgInfo[] PROGMEM = { 0xff, 0x81, 0x00, 0xfb, 0xfb, 0x00, 0x81, 0xff };
-const uint8_t imgQuestion[] PROGMEM = { 0xbf, 0x41, 0xc0, 0x8b, 0xdb, 0x70, 0xa1, 0xdf };
-const uint8_t imgSF[] PROGMEM = { 0xd2, 0xb7, 0xad, 0xbb, 0x92, 0x01, 0xfd, 0xfd, 0x15, 0x85, 0xf5};
+const uint8_t imgInfo[] PROGMEM = {0xff, 0x81, 0x00, 0xfb, 0xfb, 0x00, 0x81, 0xff};
+const uint8_t imgQuestion[] PROGMEM = {0xbf, 0x41, 0xc0, 0x8b, 0xdb, 0x70, 0xa1, 0xdf};
+const uint8_t imgSF[] PROGMEM = {0xd2, 0xb7, 0xad, 0xbb, 0x92, 0x01, 0xfd, 0xfd, 0x15, 0x85, 0xf5};
#endif
#include "img/icon.xbm"
diff --git a/src/input/InputBroker.cpp b/src/input/InputBroker.cpp
index 09e04602d..b06c7400f 100644
--- a/src/input/InputBroker.cpp
+++ b/src/input/InputBroker.cpp
@@ -3,9 +3,7 @@
InputBroker *inputBroker;
-InputBroker::InputBroker()
-{
-};
+InputBroker::InputBroker(){};
void InputBroker::registerSource(Observable *source)
{
@@ -14,7 +12,7 @@ void InputBroker::registerSource(Observable *source)
int InputBroker::handleInputEvent(const InputEvent *event)
{
- powerFSM.trigger(EVENT_INPUT);
- this->notifyObservers(event);
- return 0;
+ powerFSM.trigger(EVENT_INPUT);
+ this->notifyObservers(event);
+ return 0;
}
\ No newline at end of file
diff --git a/src/input/InputBroker.h b/src/input/InputBroker.h
index ab264d192..d73e6657a 100644
--- a/src/input/InputBroker.h
+++ b/src/input/InputBroker.h
@@ -5,12 +5,11 @@
#define MATRIXKEY 0xFE
typedef struct _InputEvent {
- const char* source;
+ const char *source;
char inputEvent;
char kbchar;
} InputEvent;
-class InputBroker :
- public Observable
+class InputBroker : public Observable
{
CallbackObserver inputEventObserver =
CallbackObserver(this, &InputBroker::handleInputEvent);
diff --git a/src/input/RotaryEncoderInterruptBase.cpp b/src/input/RotaryEncoderInterruptBase.cpp
index ad55bd1a4..19b507f6c 100644
--- a/src/input/RotaryEncoderInterruptBase.cpp
+++ b/src/input/RotaryEncoderInterruptBase.cpp
@@ -34,7 +34,7 @@ void RotaryEncoderInterruptBase::init(
int32_t RotaryEncoderInterruptBase::runOnce()
{
InputEvent e;
- e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
+ e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
e.source = this->_originName;
if (this->action == ROTARY_ACTION_PRESSED) {
@@ -48,7 +48,7 @@ int32_t RotaryEncoderInterruptBase::runOnce()
e.inputEvent = this->_eventCcw;
}
- if (e.inputEvent != ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
+ if (e.inputEvent != meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
this->notifyObservers(&e);
}
diff --git a/src/input/RotaryEncoderInterruptBase.h b/src/input/RotaryEncoderInterruptBase.h
index 88d619178..06f7a2354 100644
--- a/src/input/RotaryEncoderInterruptBase.h
+++ b/src/input/RotaryEncoderInterruptBase.h
@@ -33,8 +33,8 @@ class RotaryEncoderInterruptBase : public Observable, public
private:
uint8_t _pinA = 0;
uint8_t _pinB = 0;
- char _eventCw = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
- char _eventCcw = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
- char _eventPressed = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
+ char _eventCw = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
+ char _eventCcw = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
+ char _eventPressed = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
const char *_originName;
};
diff --git a/src/input/RotaryEncoderInterruptImpl1.h b/src/input/RotaryEncoderInterruptImpl1.h
index aeafeeca7..1bdb3a5a5 100644
--- a/src/input/RotaryEncoderInterruptImpl1.h
+++ b/src/input/RotaryEncoderInterruptImpl1.h
@@ -8,8 +8,7 @@
* to your device as you wish, but you always need to have separate event
* handlers, thus you need to have a RotaryEncoderInterrupt implementation.
*/
-class RotaryEncoderInterruptImpl1 :
- public RotaryEncoderInterruptBase
+class RotaryEncoderInterruptImpl1 : public RotaryEncoderInterruptBase
{
public:
RotaryEncoderInterruptImpl1();
diff --git a/src/input/UpDownInterruptBase.cpp b/src/input/UpDownInterruptBase.cpp
index 5a0f25158..7c340bab0 100644
--- a/src/input/UpDownInterruptBase.cpp
+++ b/src/input/UpDownInterruptBase.cpp
@@ -1,16 +1,13 @@
-#include "configuration.h"
#include "UpDownInterruptBase.h"
+#include "configuration.h"
-UpDownInterruptBase::UpDownInterruptBase(
- const char *name)
+UpDownInterruptBase::UpDownInterruptBase(const char *name)
{
this->_originName = name;
}
-void UpDownInterruptBase::init(
- uint8_t pinDown, uint8_t pinUp, uint8_t pinPress,
- char eventDown, char eventUp, char eventPressed,
- void (*onIntDown)(), void (*onIntUp)(), void (*onIntPress)())
+void UpDownInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinPress, char eventDown, char eventUp, char eventPressed,
+ void (*onIntDown)(), void (*onIntUp)(), void (*onIntPress)())
{
this->_pinDown = pinDown;
this->_pinUp = pinUp;
@@ -26,8 +23,7 @@ void UpDownInterruptBase::init(
attachInterrupt(this->_pinDown, onIntDown, RISING);
attachInterrupt(this->_pinUp, onIntUp, RISING);
- LOG_DEBUG("GPIO initialized (%d, %d, %d)\n",
- this->_pinDown, this->_pinUp, pinPress);
+ LOG_DEBUG("GPIO initialized (%d, %d, %d)\n", this->_pinDown, this->_pinUp, pinPress);
}
void UpDownInterruptBase::intPressHandler()
diff --git a/src/input/UpDownInterruptBase.h b/src/input/UpDownInterruptBase.h
index 1ee4e4a03..ed7eee332 100644
--- a/src/input/UpDownInterruptBase.h
+++ b/src/input/UpDownInterruptBase.h
@@ -16,8 +16,8 @@ class UpDownInterruptBase : public Observable
private:
uint8_t _pinDown = 0;
uint8_t _pinUp = 0;
- char _eventDown = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
- char _eventUp = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
- char _eventPressed = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
+ char _eventDown = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
+ char _eventUp = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
+ char _eventPressed = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
const char *_originName;
};
diff --git a/src/input/UpDownInterruptImpl1.cpp b/src/input/UpDownInterruptImpl1.cpp
index c49409660..c22152f82 100644
--- a/src/input/UpDownInterruptImpl1.cpp
+++ b/src/input/UpDownInterruptImpl1.cpp
@@ -17,9 +17,9 @@ void UpDownInterruptImpl1::init()
uint8_t pinDown = moduleConfig.canned_message.inputbroker_pin_b;
uint8_t pinPress = moduleConfig.canned_message.inputbroker_pin_press;
- char eventDown = static_cast(ModuleConfig_CannedMessageConfig_InputEventChar_DOWN);
- char eventUp = static_cast(ModuleConfig_CannedMessageConfig_InputEventChar_UP);
- char eventPressed = static_cast(ModuleConfig_CannedMessageConfig_InputEventChar_SELECT);
+ char eventDown = static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN);
+ char eventUp = static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP);
+ char eventPressed = static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT);
UpDownInterruptBase::init(pinDown, pinUp, pinPress, eventDown, eventUp, eventPressed, UpDownInterruptImpl1::handleIntDown,
UpDownInterruptImpl1::handleIntUp, UpDownInterruptImpl1::handleIntPressed);
diff --git a/src/input/UpDownInterruptImpl1.h b/src/input/UpDownInterruptImpl1.h
index acdb7953c..17420db95 100644
--- a/src/input/UpDownInterruptImpl1.h
+++ b/src/input/UpDownInterruptImpl1.h
@@ -1,8 +1,7 @@
#pragma once
#include "UpDownInterruptBase.h"
-class UpDownInterruptImpl1 :
- public UpDownInterruptBase
+class UpDownInterruptImpl1 : public UpDownInterruptBase
{
public:
UpDownInterruptImpl1();
diff --git a/src/input/cardKbI2cImpl.cpp b/src/input/cardKbI2cImpl.cpp
index 3d30fb867..e1639270a 100644
--- a/src/input/cardKbI2cImpl.cpp
+++ b/src/input/cardKbI2cImpl.cpp
@@ -3,15 +3,11 @@
CardKbI2cImpl *cardKbI2cImpl;
-CardKbI2cImpl::CardKbI2cImpl() :
- KbI2cBase("cardKB")
-{
-}
+CardKbI2cImpl::CardKbI2cImpl() : KbI2cBase("cardKB") {}
void CardKbI2cImpl::init()
{
- if (cardkb_found != CARDKB_ADDR)
- {
+ if (cardkb_found != CARDKB_ADDR) {
disable();
return;
}
diff --git a/src/input/cardKbI2cImpl.h b/src/input/cardKbI2cImpl.h
index cd6ee8d47..1e6e87dfd 100644
--- a/src/input/cardKbI2cImpl.h
+++ b/src/input/cardKbI2cImpl.h
@@ -9,8 +9,7 @@
* to your device as you wish, but you always need to have separate event
* handlers, thus you need to have a RotaryEncoderInterrupt implementation.
*/
-class CardKbI2cImpl :
- public KbI2cBase
+class CardKbI2cImpl : public KbI2cBase
{
public:
CardKbI2cImpl();
diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp
index a857bae77..9212b6d4c 100644
--- a/src/input/kbI2cBase.cpp
+++ b/src/input/kbI2cBase.cpp
@@ -12,32 +12,32 @@ KbI2cBase::KbI2cBase(const char *name) : concurrency::OSThread(name)
uint8_t read_from_14004(uint8_t reg, uint8_t *data, uint8_t length)
{
- uint8_t readflag = 0;
- Wire.beginTransmission(CARDKB_ADDR);
- Wire.write(reg);
- Wire.endTransmission(); // stop transmitting
- delay(20);
- Wire.requestFrom(CARDKB_ADDR, (int)length);
- int i = 0;
- while ( Wire.available() ) // slave may send less than requested
- {
- data[i++] = Wire.read(); // receive a byte as a proper uint8_t
- readflag = 1;
- }
- return readflag;
+ uint8_t readflag = 0;
+ Wire.beginTransmission(CARDKB_ADDR);
+ Wire.write(reg);
+ Wire.endTransmission(); // stop transmitting
+ delay(20);
+ Wire.requestFrom(CARDKB_ADDR, (int)length);
+ int i = 0;
+ while (Wire.available()) // slave may send less than requested
+ {
+ data[i++] = Wire.read(); // receive a byte as a proper uint8_t
+ readflag = 1;
+ }
+ return readflag;
}
void write_to_14004(uint8_t reg, uint8_t data)
{
- Wire.beginTransmission(CARDKB_ADDR);
- Wire.write(reg);
- Wire.write(data);
- Wire.endTransmission(); // stop transmitting
+ Wire.beginTransmission(CARDKB_ADDR);
+ Wire.write(reg);
+ Wire.write(data);
+ Wire.endTransmission(); // stop transmitting
}
int32_t KbI2cBase::runOnce()
{
- if (cardkb_found != CARDKB_ADDR){
+ if (cardkb_found != CARDKB_ADDR) {
// Input device is not detected.
return INT32_MAX;
}
@@ -48,7 +48,7 @@ int32_t KbI2cBase::runOnce()
uint8_t PrintDataBuf = 0;
if (read_from_14004(0x01, rDataBuf, 0x04) == 1) {
for (uint8_t aCount = 0; aCount < 0x04; aCount++) {
- for (uint8_t bCount = 0; bCount < 0x04; bCount++ ) {
+ for (uint8_t bCount = 0; bCount < 0x04; bCount++) {
if (((rDataBuf[aCount] >> bCount) & 0x01) == 0x01) {
PrintDataBuf = aCount * 0x04 + bCount + 1;
}
@@ -70,35 +70,35 @@ int32_t KbI2cBase::runOnce()
while (Wire.available()) {
char c = Wire.read();
InputEvent e;
- e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
+ e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
e.source = this->_originName;
switch (c) {
case 0x1b: // ESC
- e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL;
+ e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL;
break;
case 0x08: // Back
- e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_BACK;
+ e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK;
e.kbchar = c;
break;
case 0xb5: // Up
- e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_UP;
+ e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP;
break;
case 0xb6: // Down
- e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
+ e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN;
break;
case 0xb4: // Left
- e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
+ e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
e.kbchar = c;
break;
case 0xb7: // Right
- e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
+ e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
e.kbchar = c;
break;
case 0x0d: // Enter
- e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
+ e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
break;
- case 0x00: //nopress
- e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
+ case 0x00: // nopress
+ e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
break;
default: // all other keys
e.inputEvent = ANYKEY;
@@ -106,7 +106,7 @@ int32_t KbI2cBase::runOnce()
break;
}
- if (e.inputEvent != ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
+ if (e.inputEvent != meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
this->notifyObservers(&e);
}
}
diff --git a/src/input/kbI2cBase.h b/src/input/kbI2cBase.h
index 2fdacbc28..c661f95c5 100644
--- a/src/input/kbI2cBase.h
+++ b/src/input/kbI2cBase.h
@@ -1,11 +1,9 @@
#pragma once
-#include "SinglePortModule.h" // TODO: what header file to include?
#include "InputBroker.h"
+#include "SinglePortModule.h" // TODO: what header file to include?
-class KbI2cBase :
- public Observable,
- public concurrency::OSThread
+class KbI2cBase : public Observable, public concurrency::OSThread
{
public:
explicit KbI2cBase(const char *name);
diff --git a/src/main.cpp b/src/main.cpp
index af7f28b50..4f65ff51b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3,12 +3,12 @@
#include "MeshService.h"
#include "NodeDB.h"
#include "PowerFSM.h"
+#include "ReliableRouter.h"
#include "airtime.h"
#include "buzz.h"
#include "configuration.h"
#include "error.h"
#include "power.h"
-#include "ReliableRouter.h"
// #include "debug.h"
#include "FSCommon.h"
#include "RTC.h"
@@ -27,8 +27,8 @@
#include
// #include
-#include "mesh/http/WiFiAPClient.h"
#include "mesh/eth/ethClient.h"
+#include "mesh/http/WiFiAPClient.h"
#ifdef ARCH_ESP32
#include "mesh/http/WebServer.h"
@@ -36,12 +36,12 @@
#endif
#if HAS_WIFI
-#include "mesh/wifi/WiFiServerAPI.h"
+#include "mesh/api/WiFiServerAPI.h"
#include "mqtt/MQTT.h"
#endif
#if HAS_ETHERNET
-#include "mesh/eth/ethServerAPI.h"
+#include "mesh/api/ethServerAPI.h"
#include "mqtt/MQTT.h"
#endif
@@ -87,7 +87,7 @@ uint8_t rtc_found;
// Keystore Chips
uint8_t keystore_found;
-#ifndef ARCH_PORTDUINO
+#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
ATECCX08A atecc;
#endif
@@ -98,7 +98,8 @@ uint32_t serialSinceMsec;
bool pmu_found;
// Array map of sensor types (as array index) and i2c address as value we'll find in the i2c scan
-uint8_t nodeTelemetrySensorsMap[_TelemetrySensorType_MAX + 1] = { 0 }; // one is enough, missing elements will be initialized to 0 anyway.
+uint8_t nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1] = {
+ 0}; // one is enough, missing elements will be initialized to 0 anyway.
Router *router = NULL; // Users of router don't care what sort of subclass implements that API
@@ -110,12 +111,12 @@ const char *getDeviceName()
// Meshtastic_ab3c or Shortname_abcd
static char name[20];
- sprintf(name, "%02x%02x", dmac[4], dmac[5]);
+ snprintf(name, sizeof(name), "%02x%02x", dmac[4], dmac[5]);
// if the shortname exists and is NOT the new default of ab3c, use it for BLE name.
if ((owner.short_name != NULL) && (strcmp(owner.short_name, name) != 0)) {
- sprintf(name, "%s_%02x%02x", owner.short_name, dmac[4], dmac[5]);
+ snprintf(name, sizeof(name), "%s_%02x%02x", owner.short_name, dmac[4], dmac[5]);
} else {
- sprintf(name, "Meshtastic_%02x%02x", dmac[4], dmac[5]);
+ snprintf(name, sizeof(name), "Meshtastic_%02x%02x", dmac[4], dmac[5]);
}
return name;
}
@@ -127,6 +128,17 @@ static int32_t ledBlinker()
setLed(ledOn);
+#ifdef ARCH_ESP32
+ auto newHeap = ESP.getFreeHeap();
+ if (newHeap < 11000) {
+ LOG_DEBUG("\n\n====== heap too low [11000] -> reboot in 1s ======\n\n");
+#ifdef HAS_SCREEN
+ screen->startRebootScreen();
+#endif
+ rebootAtMsec = millis() + 900;
+ }
+#endif
+
// have a very sparse duty cycle of LED being on, unless charging, then blink 0.5Hz square wave rate to indicate that
return powerStatus->getIsCharging() ? 1000 : (ledOn ? 1 : 1000);
}
@@ -169,7 +181,7 @@ void setup()
#endif
#ifdef DEBUG_PORT
- consoleInit(); // Set serial baud rate and init our mesh console
+ consoleInit(); // Set serial baud rate and init our mesh console
#endif
serialSinceMsec = millis();
@@ -239,7 +251,7 @@ void setup()
#ifdef RAK4630
// We need to enable 3.3V periphery in order to scan it
pinMode(PIN_3V3_EN, OUTPUT);
- digitalWrite(PIN_3V3_EN, 1);
+ digitalWrite(PIN_3V3_EN, HIGH);
#endif
// Currently only the tbeam has a PMU
@@ -249,12 +261,11 @@ void setup()
powerStatus->observe(&power->newStatus);
power->setup(); // Must be after status handler is installed, so that handler gets notified of the initial configuration
-
#ifdef LILYGO_TBEAM_S3_CORE
// In T-Beam-S3-core, the I2C device cannot be scanned before power initialization, otherwise the device will be stuck
// PCF8563 RTC in tbeam-s3 uses Wire1 to share I2C bus
Wire1.beginTransmission(PCF8563_RTC);
- if (Wire1.endTransmission() == 0){
+ if (Wire1.endTransmission() == 0) {
rtc_found = PCF8563_RTC;
LOG_INFO("PCF8563 RTC found\n");
}
@@ -299,12 +310,20 @@ void setup()
// but we need to do this after main cpu iniot (esp32setup), because we need the random seed set
nodeDB.init();
+ // If we're taking on the repeater role, use flood router
+ if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER)
+ router = new FloodingRouter();
+
playStartMelody();
// fixed screen override?
- if (config.display.oled != Config_DisplayConfig_OledType_OLED_AUTO)
+ if (config.display.oled != meshtastic_Config_DisplayConfig_OledType_OLED_AUTO)
screen_model = config.display.oled;
+#if defined(USE_SH1107)
+ screen_model = Config_DisplayConfig_OledType_OLED_SH1107; // set dimension of 128x128
+#endif
+
// Init our SPI controller (must be before screen and lora)
initSPI();
#ifndef ARCH_ESP32
@@ -337,7 +356,7 @@ void setup()
// Do this after service.init (because that clears error_code)
#ifdef HAS_PMU
if (!pmu_found)
- RECORD_CRITICALERROR(CriticalErrorCode_NO_AXP192); // Record a hardware fault for missing hardware
+ RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_NO_AXP192); // Record a hardware fault for missing hardware
#endif
// Don't call screen setup until after nodedb is setup (because we need
@@ -448,18 +467,18 @@ void setup()
}
#endif
-// check if the radio chip matches the selected region
+ // check if the radio chip matches the selected region
-if((config.lora.region == Config_LoRaConfig_RegionCode_LORA_24) && (!rIf->wideLora())){
- LOG_WARN("Radio chip does not support 2.4GHz LoRa. Reverting to unset.\n");
- config.lora.region = Config_LoRaConfig_RegionCode_UNSET;
- nodeDB.saveToDisk(SEGMENT_CONFIG);
- if(!rIf->reconfigure()) {
- LOG_WARN("Reconfigure failed, rebooting\n");
- screen->startRebootScreen();
- rebootAtMsec = millis() + 5000;
+ if ((config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_LORA_24) && (!rIf->wideLora())) {
+ LOG_WARN("Radio chip does not support 2.4GHz LoRa. Reverting to unset.\n");
+ config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_UNSET;
+ nodeDB.saveToDisk(SEGMENT_CONFIG);
+ if (!rIf->reconfigure()) {
+ LOG_WARN("Reconfigure failed, rebooting\n");
+ screen->startRebootScreen();
+ rebootAtMsec = millis() + 5000;
+ }
}
-}
#if HAS_WIFI || HAS_ETHERNET
mqttInit();
@@ -486,13 +505,15 @@ if((config.lora.region == Config_LoRaConfig_RegionCode_LORA_24) && (!rIf->wideLo
airTime = new AirTime();
if (!rIf)
- RECORD_CRITICALERROR(CriticalErrorCode_NO_RADIO);
+ RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_NO_RADIO);
else {
router->addInterface(rIf);
// Calculate and save the bit rate to myNodeInfo
// TODO: This needs to be added what ever method changes the channel from the phone.
- myNodeInfo.bitrate = (float(Constants_DATA_PAYLOAD_LEN) / (float(rIf->getPacketTime(Constants_DATA_PAYLOAD_LEN)))) * 1000;
+ myNodeInfo.bitrate =
+ (float(meshtastic_Constants_DATA_PAYLOAD_LEN) / (float(rIf->getPacketTime(meshtastic_Constants_DATA_PAYLOAD_LEN)))) *
+ 1000;
LOG_DEBUG("myNodeInfo.bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
}
diff --git a/src/main.h b/src/main.h
index 89a6bd059..9d965b0fc 100644
--- a/src/main.h
+++ b/src/main.h
@@ -1,11 +1,11 @@
#pragma once
-#include