Merge branch 'master' into picomputer-s3
This commit is contained in:
@@ -37,7 +37,9 @@ body:
|
|||||||
- T-Lora v1
|
- T-Lora v1
|
||||||
- T-Lora v1.3
|
- T-Lora v1.3
|
||||||
- T-Lora v2 1.6
|
- T-Lora v2 1.6
|
||||||
|
- T-Deck
|
||||||
- T-Echo
|
- T-Echo
|
||||||
|
- T-Watch
|
||||||
- Rak4631
|
- Rak4631
|
||||||
- Rak11200
|
- Rak11200
|
||||||
- Rak11310
|
- Rak11310
|
||||||
@@ -45,6 +47,8 @@ body:
|
|||||||
- Heltec v2
|
- Heltec v2
|
||||||
- Heltec v2.1
|
- Heltec v2.1
|
||||||
- Heltec V3
|
- Heltec V3
|
||||||
|
- Heltec Wireless Paper
|
||||||
|
- Heltec Wireless Tracker
|
||||||
- Raspberry Pi Pico (W)
|
- Raspberry Pi Pico (W)
|
||||||
- Relay v1
|
- Relay v1
|
||||||
- Relay v2
|
- Relay v2
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ jobs:
|
|||||||
uses: ./.github/actions/setup-base
|
uses: ./.github/actions/setup-base
|
||||||
|
|
||||||
- name: Pull web ui
|
- name: Pull web ui
|
||||||
uses: dsaltares/fetch-gh-release-asset@master
|
uses: dsaltares/fetch-gh-release-asset@a40c8b4a0471f9ab81bdf73a010f74cc51476ad4
|
||||||
with:
|
with:
|
||||||
repo: "meshtastic/web"
|
repo: meshtastic/web
|
||||||
file: "build.tar"
|
file: build.tar
|
||||||
target: "build.tar"
|
target: build.tar
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Unpack web ui
|
- name: Unpack web ui
|
||||||
@@ -40,11 +40,11 @@ jobs:
|
|||||||
run: bin/build-esp32.sh ${{ inputs.board }}
|
run: bin/build-esp32.sh ${{ inputs.board }}
|
||||||
|
|
||||||
- name: Pull OTA Firmware
|
- name: Pull OTA Firmware
|
||||||
uses: dsaltares/fetch-gh-release-asset@master
|
uses: dsaltares/fetch-gh-release-asset@a40c8b4a0471f9ab81bdf73a010f74cc51476ad4
|
||||||
with:
|
with:
|
||||||
repo: "meshtastic/firmware-ota"
|
repo: meshtastic/firmware-ota
|
||||||
file: "firmware.bin"
|
file: firmware.bin
|
||||||
target: "release/bleota.bin"
|
target: release/bleota.bin
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ jobs:
|
|||||||
uses: ./.github/actions/setup-base
|
uses: ./.github/actions/setup-base
|
||||||
|
|
||||||
- name: Pull web ui
|
- name: Pull web ui
|
||||||
uses: dsaltares/fetch-gh-release-asset@master
|
uses: dsaltares/fetch-gh-release-asset@a40c8b4a0471f9ab81bdf73a010f74cc51476ad4
|
||||||
with:
|
with:
|
||||||
repo: "meshtastic/web"
|
repo: meshtastic/web
|
||||||
file: "build.tar"
|
file: build.tar
|
||||||
target: "build.tar"
|
target: build.tar
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Unpack web ui
|
- name: Unpack web ui
|
||||||
@@ -38,11 +38,11 @@ jobs:
|
|||||||
run: bin/build-esp32.sh ${{ inputs.board }}
|
run: bin/build-esp32.sh ${{ inputs.board }}
|
||||||
|
|
||||||
- name: Pull OTA Firmware
|
- name: Pull OTA Firmware
|
||||||
uses: dsaltares/fetch-gh-release-asset@master
|
uses: dsaltares/fetch-gh-release-asset@a40c8b4a0471f9ab81bdf73a010f74cc51476ad4
|
||||||
with:
|
with:
|
||||||
repo: "meshtastic/firmware-ota"
|
repo: meshtastic/firmware-ota
|
||||||
file: "firmware-s3.bin"
|
file: firmware-s3.bin
|
||||||
target: "release/bleota-s3.bin"
|
target: release/bleota-s3.bin
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Get release version string
|
- name: Get release version string
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
name: CI
|
name: CI
|
||||||
|
#concurrency:
|
||||||
|
# group: ${{ github.ref }}
|
||||||
|
# cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
|
||||||
on:
|
on:
|
||||||
# # Triggers the workflow on push but only for the master branch
|
# # Triggers the workflow on push but only for the master branch
|
||||||
push:
|
push:
|
||||||
@@ -33,6 +36,8 @@ jobs:
|
|||||||
- board: m5stack-coreink
|
- board: m5stack-coreink
|
||||||
- board: tbeam-s3-core
|
- board: tbeam-s3-core
|
||||||
- board: tlora-t3s3-v1
|
- board: tlora-t3s3-v1
|
||||||
|
- board: t-watch-s3
|
||||||
|
- board: t-deck
|
||||||
#- board: rak11310
|
#- board: rak11310
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -44,7 +49,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Trunk Check
|
- name: Trunk Check
|
||||||
if: ${{ github.event_name != 'workflow_dispatch' }}
|
if: ${{ github.event_name != 'workflow_dispatch' }}
|
||||||
uses: trunk-io/trunk-action@v1
|
uses: trunk-io/trunk-action@782e83f803ca6e369f035d64c6ba2768174ba61b
|
||||||
|
|
||||||
- name: Check ${{ matrix.board }}
|
- name: Check ${{ matrix.board }}
|
||||||
run: bin/check-all.sh ${{ matrix.board }}
|
run: bin/check-all.sh ${{ matrix.board }}
|
||||||
@@ -66,6 +71,7 @@ jobs:
|
|||||||
- board: heltec-v2_1
|
- board: heltec-v2_1
|
||||||
- board: tbeam0_7
|
- board: tbeam0_7
|
||||||
- board: meshtastic-diy-v1
|
- board: meshtastic-diy-v1
|
||||||
|
- board: hydra
|
||||||
- board: meshtastic-dr-dev
|
- board: meshtastic-dr-dev
|
||||||
- board: nano-g1
|
- board: nano-g1
|
||||||
- board: station-g1
|
- board: station-g1
|
||||||
@@ -83,8 +89,12 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- board: heltec-v3
|
- board: heltec-v3
|
||||||
- board: heltec-wsl-v3
|
- board: heltec-wsl-v3
|
||||||
|
- board: heltec-wireless-tracker
|
||||||
|
- board: heltec-wireless-paper
|
||||||
- board: tbeam-s3-core
|
- board: tbeam-s3-core
|
||||||
- board: tlora-t3s3-v1
|
- board: tlora-t3s3-v1
|
||||||
|
- board: t-watch-s3
|
||||||
|
- board: t-deck
|
||||||
uses: ./.github/workflows/build_esp32_s3.yml
|
uses: ./.github/workflows/build_esp32_s3.yml
|
||||||
with:
|
with:
|
||||||
board: ${{ matrix.board }}
|
board: ${{ matrix.board }}
|
||||||
@@ -97,9 +107,11 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- board: rak4631
|
- board: rak4631
|
||||||
- board: rak4631_eink
|
- board: rak4631_eink
|
||||||
|
- board: monteops_hw1
|
||||||
- board: t-echo
|
- board: t-echo
|
||||||
- board: pca10059_diy_eink
|
- board: pca10059_diy_eink
|
||||||
- board: feather_diy
|
- board: feather_diy
|
||||||
|
- board: nano-g2-ultra
|
||||||
uses: ./.github/workflows/build_nrf52.yml
|
uses: ./.github/workflows/build_nrf52.yml
|
||||||
with:
|
with:
|
||||||
board: ${{ matrix.board }}
|
board: ${{ matrix.board }}
|
||||||
@@ -247,8 +259,9 @@ jobs:
|
|||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
- name: Create request artifacts
|
- name: Create request artifacts
|
||||||
|
continue-on-error: true # FIXME: Why are we getting 502, but things still work?
|
||||||
if: ${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request_target' || github.event_name == 'pull_request' }}
|
||||||
uses: gavv/pull-request-artifacts@v1.0.0
|
uses: gavv/pull-request-artifacts@v1.1.0
|
||||||
with:
|
with:
|
||||||
commit: ${{ (github.event.pull_request_target || github.event.pull_request).head.sha }}
|
commit: ${{ (github.event.pull_request_target || github.event.pull_request).head.sha }}
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -306,7 +319,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
draft: true
|
draft: true
|
||||||
prerelease: true
|
prerelease: true
|
||||||
release_name: Meshtastic Firmware ${{ steps.version.outputs.version }}
|
release_name: Meshtastic Firmware ${{ steps.version.outputs.version }} Alpha
|
||||||
tag_name: v${{ steps.version.outputs.version }}
|
tag_name: v${{ steps.version.outputs.version }}
|
||||||
body: |
|
body: |
|
||||||
Autogenerated by github action, developer should edit as required before publishing...
|
Autogenerated by github action, developer should edit as required before publishing...
|
||||||
|
|||||||
@@ -14,6 +14,6 @@ jobs:
|
|||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Trunk Check
|
- name: Trunk Check
|
||||||
uses: trunk-io/trunk-action@v1
|
uses: trunk-io/trunk-action@782e83f803ca6e369f035d64c6ba2768174ba61b
|
||||||
with:
|
with:
|
||||||
trunk-token: ${{ secrets.TRUNK_TOKEN }}
|
trunk-token: ${{ secrets.TRUNK_TOKEN }}
|
||||||
|
|||||||
Vendored
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"editor.defaultFormatter": "trunk.io"
|
"editor.defaultFormatter": "trunk.io",
|
||||||
|
"trunk.enableWindows": true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
; Common settings for ESP targes, mixin with extends = esp32_base
|
; Common settings for ESP targes, mixin with extends = esp32_base
|
||||||
[esp32_base]
|
[esp32_base]
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform = platformio/espressif32@^6.2.0
|
platform = platformio/espressif32@^6.3.2
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/>
|
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/>
|
||||||
@@ -28,6 +28,7 @@ build_flags =
|
|||||||
-DCONFIG_BT_NIMBLE_ENABLED
|
-DCONFIG_BT_NIMBLE_ENABLED
|
||||||
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
|
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
|
||||||
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
|
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
|
||||||
|
-DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5120
|
||||||
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
|
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
|
||||||
;-DDEBUG_HEAP
|
;-DDEBUG_HEAP
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[nrf52_base]
|
[nrf52_base]
|
||||||
; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
|
; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
|
||||||
platform = platformio/nordicnrf52@^9.6.0
|
platform = platformio/nordicnrf52@^10.0.0
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
|
|
||||||
build_type = debug ; I'm debugging with ICE a lot now
|
build_type = debug ; I'm debugging with ICE a lot now
|
||||||
@@ -9,7 +9,7 @@ build_flags =
|
|||||||
-Isrc/platform/nrf52
|
-Isrc/platform/nrf52
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/rp2040> -<mesh/eth/>
|
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2040> -<mesh/eth/>
|
||||||
|
|
||||||
lib_deps=
|
lib_deps=
|
||||||
${arduino_base.lib_deps}
|
${arduino_base.lib_deps}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ build_flags =
|
|||||||
-D__PLAT_RP2040__
|
-D__PLAT_RP2040__
|
||||||
# -D _POSIX_THREADS
|
# -D _POSIX_THREADS
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mqtt/> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/>
|
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/>
|
||||||
|
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
BluetoothOTA
|
BluetoothOTA
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ build_flags =
|
|||||||
-DVECT_TAB_OFFSET=0x08000000
|
-DVECT_TAB_OFFSET=0x08000000
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<mqtt/> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040>
|
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<mesh/eth/> -<input> -<buzz> -<modules/Telemetry> -<platform/nrf52> -<platform/portduino> -<platform/rp2040>
|
||||||
|
|
||||||
board_upload.offset_address = 0x08000000
|
board_upload.offset_address = 0x08000000
|
||||||
upload_protocol = stlink
|
upload_protocol = stlink
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ IF EXIST %FILENAME% IF x%FILENAME:update=%==x%FILENAME% (
|
|||||||
%PYTHON% -m esptool --baud 115200 write_flash 0x00 %FILENAME%
|
%PYTHON% -m esptool --baud 115200 write_flash 0x00 %FILENAME%
|
||||||
|
|
||||||
@REM Account for S3 board's different OTA partition
|
@REM Account for S3 board's different OTA partition
|
||||||
IF x%FILENAME:s3=%==x%FILENAME% IF x%FILENAME:v3=%==x%FILENAME% (
|
IF x%FILENAME:s3=%==x%FILENAME% IF x%FILENAME:v3=%==x%FILENAME% IF x%FILENAME:t-deck=%==x%FILENAME% IF x%FILENAME:wireless-paper=%==x%FILENAME% IF x%FILENAME:wireless-tracker=%==x%FILENAME% (
|
||||||
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota.bin
|
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota.bin
|
||||||
) else (
|
) else (
|
||||||
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota-s3.bin
|
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota-s3.bin
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ if [ -f "${FILENAME}" ] && [ ! -z "${FILENAME##*"update"*}" ]; then
|
|||||||
"$PYTHON" -m esptool erase_flash
|
"$PYTHON" -m esptool erase_flash
|
||||||
"$PYTHON" -m esptool write_flash 0x00 ${FILENAME}
|
"$PYTHON" -m esptool write_flash 0x00 ${FILENAME}
|
||||||
# Account for S3 board's different OTA partition
|
# Account for S3 board's different OTA partition
|
||||||
if [ ! -z "${FILENAME##*"s3"*}" ] && [ ! -z "${FILENAME##*"-v3"*}" ]; then
|
if [ ! -z "${FILENAME##*"s3"*}" ] && [ ! -z "${FILENAME##*"-v3"*}" ] && [ ! -z "${FILENAME##*"t-deck"*}" ] && [ ! -z "${FILENAME##*"wireless-paper"*}" ] && [ ! -z "${FILENAME##*"wireless-tracker"*}" ]; then
|
||||||
"$PYTHON" -m esptool write_flash 0x260000 bleota.bin
|
"$PYTHON" -m esptool write_flash 0x260000 bleota.bin
|
||||||
else
|
else
|
||||||
"$PYTHON" -m esptool write_flash 0x260000 bleota-s3.bin
|
"$PYTHON" -m esptool write_flash 0x260000 bleota-s3.bin
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"build": {
|
||||||
|
"arduino": {
|
||||||
|
"ldscript": "esp32s3_out.ld",
|
||||||
|
"partitions": "default_8MB.csv"
|
||||||
|
},
|
||||||
|
"core": "esp32",
|
||||||
|
"extra_flags": [
|
||||||
|
"-DHELTEC_WIRELESS_TRACKER",
|
||||||
|
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||||
|
"-DARDUINO_USB_MODE=0",
|
||||||
|
"-DARDUINO_RUNNING_CORE=1",
|
||||||
|
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||||
|
],
|
||||||
|
"f_cpu": "240000000L",
|
||||||
|
"f_flash": "80000000L",
|
||||||
|
"flash_mode": "qio",
|
||||||
|
"hwids": [["0x303A", "0x1001"]],
|
||||||
|
"mcu": "esp32s3",
|
||||||
|
"variant": "heltec_wireless_tracker"
|
||||||
|
},
|
||||||
|
"connectivity": ["wifi", "bluetooth", "lora"],
|
||||||
|
"debug": {
|
||||||
|
"openocd_target": "esp32s3.cfg"
|
||||||
|
},
|
||||||
|
"frameworks": ["arduino", "espidf"],
|
||||||
|
"name": "Heltec Wireless Tracker",
|
||||||
|
"upload": {
|
||||||
|
"flash_size": "8MB",
|
||||||
|
"maximum_ram_size": 327680,
|
||||||
|
"maximum_size": 8388608,
|
||||||
|
"wait_for_upload_port": true,
|
||||||
|
"require_upload_port": true,
|
||||||
|
"speed": 921600
|
||||||
|
},
|
||||||
|
"url": "https://heltec.org/project/wireless-tracker/",
|
||||||
|
"vendor": "Heltec"
|
||||||
|
}
|
||||||
@@ -0,0 +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": "BQ nRF52840",
|
||||||
|
"mcu": "nrf52840",
|
||||||
|
"variant": "nano-g2-ultra",
|
||||||
|
"bsp": {
|
||||||
|
"name": "adafruit"
|
||||||
|
},
|
||||||
|
"softdevice": {
|
||||||
|
"sd_flags": "-DS140",
|
||||||
|
"sd_name": "s140",
|
||||||
|
"sd_version": "6.1.1",
|
||||||
|
"sd_fwid": "0x00B6"
|
||||||
|
},
|
||||||
|
"bootloader": {
|
||||||
|
"settings_addr": "0xFF000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectivity": ["bluetooth"],
|
||||||
|
"debug": {
|
||||||
|
"jlink_device": "nRF52840_xxAA",
|
||||||
|
"svd_path": "nrf52840.svd"
|
||||||
|
},
|
||||||
|
"frameworks": ["arduino"],
|
||||||
|
"name": "BQ nRF52840",
|
||||||
|
"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://wiki.uniteng.com/en/meshtastic/nano-g2-ultra",
|
||||||
|
"vendor": "BQ Consulting"
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"build": {
|
||||||
|
"arduino": {
|
||||||
|
"ldscript": "esp32s3_out.ld"
|
||||||
|
},
|
||||||
|
"core": "esp32",
|
||||||
|
"extra_flags": [
|
||||||
|
"-DBOARD_HAS_PSRAM",
|
||||||
|
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||||
|
"-DARDUINO_USB_MODE=0",
|
||||||
|
"-DARDUINO_RUNNING_CORE=1",
|
||||||
|
"-DARDUINO_EVENT_RUNNING_CORE=0"
|
||||||
|
],
|
||||||
|
"f_cpu": "240000000L",
|
||||||
|
"f_flash": "80000000L",
|
||||||
|
"flash_mode": "dio",
|
||||||
|
"hwids": [["0x303A", "0x1001"]],
|
||||||
|
"mcu": "esp32s3",
|
||||||
|
"variant": "t-deck"
|
||||||
|
},
|
||||||
|
"connectivity": ["wifi", "bluetooth", "lora"],
|
||||||
|
"debug": {
|
||||||
|
"default_tool": "esp-builtin",
|
||||||
|
"onboard_tools": ["esp-builtin"],
|
||||||
|
"openocd_target": "esp32s3.cfg"
|
||||||
|
},
|
||||||
|
"frameworks": ["arduino", "espidf"],
|
||||||
|
"name": "Espressif Systems LilyGO T-Deck (16 MB FLASH, 8 MB PSRAM)",
|
||||||
|
"upload": {
|
||||||
|
"flash_size": "16MB",
|
||||||
|
"maximum_ram_size": 327680,
|
||||||
|
"maximum_size": 16777216,
|
||||||
|
"use_1200bps_touch": true,
|
||||||
|
"wait_for_upload_port": true,
|
||||||
|
"require_upload_port": true,
|
||||||
|
"speed": 921600
|
||||||
|
},
|
||||||
|
"url": "https://www.lilygo.cc/en-pl/products/t-deck",
|
||||||
|
"vendor": "LilyGO"
|
||||||
|
}
|
||||||
+4
-1
@@ -7,7 +7,10 @@
|
|||||||
"cpu": "cortex-m4",
|
"cpu": "cortex-m4",
|
||||||
"extra_flags": "-DARDUINO_NRF52840_TTGO_EINK -DNRF52840_XXAA",
|
"extra_flags": "-DARDUINO_NRF52840_TTGO_EINK -DNRF52840_XXAA",
|
||||||
"f_cpu": "64000000L",
|
"f_cpu": "64000000L",
|
||||||
"hwids": [["0x239A", "0x4405"]],
|
"hwids": [
|
||||||
|
["0x239A", "0x4405"],
|
||||||
|
["0x239A", "0x002A"]
|
||||||
|
],
|
||||||
"usb_product": "TTGO_eink",
|
"usb_product": "TTGO_eink",
|
||||||
"mcu": "nrf52840",
|
"mcu": "nrf52840",
|
||||||
"variant": "t-echo",
|
"variant": "t-echo",
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"build": {
|
||||||
|
"arduino": {
|
||||||
|
"ldscript": "esp32s3_out.ld"
|
||||||
|
},
|
||||||
|
"core": "esp32",
|
||||||
|
"extra_flags": [
|
||||||
|
"-DBOARD_HAS_PSRAM",
|
||||||
|
"-DT_WATCH_S3",
|
||||||
|
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||||
|
"-DARDUINO_USB_MODE=0",
|
||||||
|
"-DARDUINO_RUNNING_CORE=1",
|
||||||
|
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||||
|
],
|
||||||
|
"f_cpu": "240000000L",
|
||||||
|
"f_flash": "80000000L",
|
||||||
|
"flash_mode": "dio",
|
||||||
|
"hwids": [["0X303A", "0x1001"]],
|
||||||
|
"mcu": "esp32s3",
|
||||||
|
"variant": "t-watch-s3"
|
||||||
|
},
|
||||||
|
"connectivity": ["wifi"],
|
||||||
|
"debug": {
|
||||||
|
"openocd_target": "esp32s3.cfg"
|
||||||
|
},
|
||||||
|
"frameworks": ["arduino"],
|
||||||
|
"name": "LilyGo T-Watch 2020 V3",
|
||||||
|
"upload": {
|
||||||
|
"flash_size": "8MB",
|
||||||
|
"maximum_ram_size": 327680,
|
||||||
|
"maximum_size": 8388608,
|
||||||
|
"require_upload_port": true,
|
||||||
|
"use_1200bps_touch": true,
|
||||||
|
"wait_for_upload_port": true
|
||||||
|
},
|
||||||
|
"url": "http://www.lilygo.cn/",
|
||||||
|
"vendor": "LilyGo"
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
{
|
||||||
|
"build": {
|
||||||
|
"arduino": {
|
||||||
|
"ldscript": "nrf52840_s140_v7.ld"
|
||||||
|
},
|
||||||
|
"core": "nRF5",
|
||||||
|
"cpu": "cortex-m4",
|
||||||
|
"extra_flags": "-DARDUINO_MDBT50Q_RX -DNRF52840_XXAA",
|
||||||
|
"f_cpu": "64000000L",
|
||||||
|
"hwids": [
|
||||||
|
["0x239A", "0x810B"],
|
||||||
|
["0x239A", "0x010B"],
|
||||||
|
["0x239A", "0x810C"]
|
||||||
|
],
|
||||||
|
"usb_product": "XIAO-BOOT",
|
||||||
|
"mcu": "nrf52840",
|
||||||
|
"variant": "Seeed_XIAO_nRF52840_Sense",
|
||||||
|
"bsp": {
|
||||||
|
"name": "adafruit"
|
||||||
|
},
|
||||||
|
"softdevice": {
|
||||||
|
"sd_flags": "-DS140",
|
||||||
|
"sd_name": "s140",
|
||||||
|
"sd_version": "7.3.0",
|
||||||
|
"sd_fwid": "0x0123"
|
||||||
|
},
|
||||||
|
"bootloader": {
|
||||||
|
"settings_addr": "0xFF000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectivity": ["bluetooth"],
|
||||||
|
"debug": {
|
||||||
|
"jlink_device": "nRF52840_xxAA",
|
||||||
|
"svd_path": "nrf52840.svd"
|
||||||
|
},
|
||||||
|
"frameworks": ["arduino"],
|
||||||
|
"name": "Seeed Xiao BLE Sense",
|
||||||
|
"upload": {
|
||||||
|
"maximum_ram_size": 248832,
|
||||||
|
"maximum_size": 815104,
|
||||||
|
"speed": 115200,
|
||||||
|
"protocol": "nrfutil",
|
||||||
|
"protocols": [
|
||||||
|
"jlink",
|
||||||
|
"nrfjprog",
|
||||||
|
"nrfutil",
|
||||||
|
"stlink",
|
||||||
|
"cmsis-dap",
|
||||||
|
"blackmagic"
|
||||||
|
],
|
||||||
|
"use_1200bps_touch": true,
|
||||||
|
"require_upload_port": true,
|
||||||
|
"wait_for_upload_port": true
|
||||||
|
},
|
||||||
|
"url": "https://www.seeedstudio.com/Seeed-XIAO-BLE-Sense-nRF52840-p-5253.html",
|
||||||
|
"vendor": "Seeed Studio"
|
||||||
|
}
|
||||||
+3
-1
@@ -9,6 +9,7 @@
|
|||||||
;default_envs = heltec-v1
|
;default_envs = heltec-v1
|
||||||
;default_envs = heltec-v2_0
|
;default_envs = heltec-v2_0
|
||||||
;default_envs = heltec-v2_1
|
;default_envs = heltec-v2_1
|
||||||
|
;default_envs = heltec-wireless-tracker
|
||||||
;default_envs = tlora-v1
|
;default_envs = tlora-v1
|
||||||
;default_envs = tlora_v1_3
|
;default_envs = tlora_v1_3
|
||||||
;default_envs = tlora-v2
|
;default_envs = tlora-v2
|
||||||
@@ -119,4 +120,5 @@ lib_deps =
|
|||||||
adafruit/Adafruit SHT31 Library@^2.2.0
|
adafruit/Adafruit SHT31 Library@^2.2.0
|
||||||
adafruit/Adafruit PM25 AQI Sensor@^1.0.6
|
adafruit/Adafruit PM25 AQI Sensor@^1.0.6
|
||||||
adafruit/Adafruit MPU6050@^2.2.4
|
adafruit/Adafruit MPU6050@^2.2.4
|
||||||
adafruit/Adafruit LIS3DH@^1.2.4
|
adafruit/Adafruit LIS3DH@^1.2.4
|
||||||
|
https://github.com/lewisxhe/BMA423_Library@^0.0.1
|
||||||
+1
-1
Submodule protobufs updated: 5f3daac5fa...6f88374ec6
@@ -6,10 +6,37 @@
|
|||||||
|
|
||||||
#include <Adafruit_LIS3DH.h>
|
#include <Adafruit_LIS3DH.h>
|
||||||
#include <Adafruit_MPU6050.h>
|
#include <Adafruit_MPU6050.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <Wire.h>
|
||||||
|
#include <bma.h>
|
||||||
|
|
||||||
|
BMA423 bmaSensor;
|
||||||
|
bool BMA_IRQ = false;
|
||||||
|
|
||||||
#define ACCELEROMETER_CHECK_INTERVAL_MS 100
|
#define ACCELEROMETER_CHECK_INTERVAL_MS 100
|
||||||
#define ACCELEROMETER_CLICK_THRESHOLD 40
|
#define ACCELEROMETER_CLICK_THRESHOLD 40
|
||||||
|
|
||||||
|
uint16_t readRegister(uint8_t address, uint8_t reg, uint8_t *data, uint16_t len)
|
||||||
|
{
|
||||||
|
Wire.beginTransmission(address);
|
||||||
|
Wire.write(reg);
|
||||||
|
Wire.endTransmission();
|
||||||
|
Wire.requestFrom((uint8_t)address, (uint8_t)len);
|
||||||
|
uint8_t i = 0;
|
||||||
|
while (Wire.available()) {
|
||||||
|
data[i++] = Wire.read();
|
||||||
|
}
|
||||||
|
return 0; // Pass
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t writeRegister(uint8_t address, uint8_t reg, uint8_t *data, uint16_t len)
|
||||||
|
{
|
||||||
|
Wire.beginTransmission(address);
|
||||||
|
Wire.write(reg);
|
||||||
|
Wire.write(data, len);
|
||||||
|
return (0 != Wire.endTransmission());
|
||||||
|
}
|
||||||
|
|
||||||
namespace concurrency
|
namespace concurrency
|
||||||
{
|
{
|
||||||
class AccelerometerThread : public concurrency::OSThread
|
class AccelerometerThread : public concurrency::OSThread
|
||||||
@@ -29,10 +56,10 @@ class AccelerometerThread : public concurrency::OSThread
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
accleremoter_type = type;
|
acceleremoter_type = type;
|
||||||
LOG_DEBUG("AccelerometerThread initializing\n");
|
LOG_DEBUG("AccelerometerThread initializing\n");
|
||||||
|
|
||||||
if (accleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.begin(accelerometer_found.address)) {
|
if (acceleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.begin(accelerometer_found.address)) {
|
||||||
LOG_DEBUG("MPU6050 initializing\n");
|
LOG_DEBUG("MPU6050 initializing\n");
|
||||||
// setup motion detection
|
// setup motion detection
|
||||||
mpu.setHighPassFilter(MPU6050_HIGHPASS_0_63_HZ);
|
mpu.setHighPassFilter(MPU6050_HIGHPASS_0_63_HZ);
|
||||||
@@ -40,11 +67,60 @@ class AccelerometerThread : public concurrency::OSThread
|
|||||||
mpu.setMotionDetectionDuration(20);
|
mpu.setMotionDetectionDuration(20);
|
||||||
mpu.setInterruptPinLatch(true); // Keep it latched. Will turn off when reinitialized.
|
mpu.setInterruptPinLatch(true); // Keep it latched. Will turn off when reinitialized.
|
||||||
mpu.setInterruptPinPolarity(true);
|
mpu.setInterruptPinPolarity(true);
|
||||||
} else if (accleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.begin(accelerometer_found.address)) {
|
} else if (acceleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.begin(accelerometer_found.address)) {
|
||||||
LOG_DEBUG("LIS3DH initializing\n");
|
LOG_DEBUG("LIS3DH initializing\n");
|
||||||
lis.setRange(LIS3DH_RANGE_2_G);
|
lis.setRange(LIS3DH_RANGE_2_G);
|
||||||
// Adjust threshhold, higher numbers are less sensitive
|
// Adjust threshold, higher numbers are less sensitive
|
||||||
lis.setClick(config.device.double_tap_as_button_press ? 2 : 1, ACCELEROMETER_CLICK_THRESHOLD);
|
lis.setClick(config.device.double_tap_as_button_press ? 2 : 1, ACCELEROMETER_CLICK_THRESHOLD);
|
||||||
|
} else if (acceleremoter_type == ScanI2C::DeviceType::BMA423 && bmaSensor.begin(readRegister, writeRegister, delay)) {
|
||||||
|
LOG_DEBUG("BMA423 initializing\n");
|
||||||
|
Acfg cfg;
|
||||||
|
cfg.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
|
||||||
|
cfg.range = BMA4_ACCEL_RANGE_2G;
|
||||||
|
cfg.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
|
||||||
|
cfg.perf_mode = BMA4_CONTINUOUS_MODE;
|
||||||
|
bmaSensor.setAccelConfig(cfg);
|
||||||
|
bmaSensor.enableAccel();
|
||||||
|
|
||||||
|
struct bma4_int_pin_config pin_config;
|
||||||
|
pin_config.edge_ctrl = BMA4_LEVEL_TRIGGER;
|
||||||
|
pin_config.lvl = BMA4_ACTIVE_HIGH;
|
||||||
|
pin_config.od = BMA4_PUSH_PULL;
|
||||||
|
pin_config.output_en = BMA4_OUTPUT_ENABLE;
|
||||||
|
pin_config.input_en = BMA4_INPUT_DISABLE;
|
||||||
|
// The correct trigger interrupt needs to be configured as needed
|
||||||
|
bmaSensor.setINTPinConfig(pin_config, BMA4_INTR1_MAP);
|
||||||
|
|
||||||
|
#ifdef BMA423_INT
|
||||||
|
pinMode(BMA4XX_INT, INPUT);
|
||||||
|
attachInterrupt(
|
||||||
|
BMA4XX_INT,
|
||||||
|
[] {
|
||||||
|
// Set interrupt to set irq value to true
|
||||||
|
BMA_IRQ = true;
|
||||||
|
},
|
||||||
|
RISING); // Select the interrupt mode according to the actual circuit
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct bma423_axes_remap remap_data;
|
||||||
|
remap_data.x_axis = 0;
|
||||||
|
remap_data.x_axis_sign = 1;
|
||||||
|
remap_data.y_axis = 1;
|
||||||
|
remap_data.y_axis_sign = 0;
|
||||||
|
remap_data.z_axis = 2;
|
||||||
|
remap_data.z_axis_sign = 1;
|
||||||
|
// Need to raise the wrist function, need to set the correct axis
|
||||||
|
bmaSensor.setRemapAxes(&remap_data);
|
||||||
|
// sensor.enableFeature(BMA423_STEP_CNTR, true);
|
||||||
|
bmaSensor.enableFeature(BMA423_TILT, true);
|
||||||
|
bmaSensor.enableFeature(BMA423_WAKEUP, true);
|
||||||
|
// sensor.resetStepCounter();
|
||||||
|
|
||||||
|
// Turn on feature interrupt
|
||||||
|
bmaSensor.enableStepCountInterrupt();
|
||||||
|
bmaSensor.enableTiltInterrupt();
|
||||||
|
// It corresponds to isDoubleClick interrupt
|
||||||
|
bmaSensor.enableWakeupInterrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,9 +129,9 @@ class AccelerometerThread : public concurrency::OSThread
|
|||||||
{
|
{
|
||||||
canSleep = true; // Assume we should not keep the board awake
|
canSleep = true; // Assume we should not keep the board awake
|
||||||
|
|
||||||
if (accleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.getMotionInterruptStatus()) {
|
if (acceleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.getMotionInterruptStatus()) {
|
||||||
wakeScreen();
|
wakeScreen();
|
||||||
} else if (accleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.getClick() > 0) {
|
} else if (acceleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.getClick() > 0) {
|
||||||
uint8_t click = lis.getClick();
|
uint8_t click = lis.getClick();
|
||||||
if (!config.device.double_tap_as_button_press) {
|
if (!config.device.double_tap_as_button_press) {
|
||||||
wakeScreen();
|
wakeScreen();
|
||||||
@@ -65,7 +141,13 @@ class AccelerometerThread : public concurrency::OSThread
|
|||||||
buttonPress();
|
buttonPress();
|
||||||
return 500;
|
return 500;
|
||||||
}
|
}
|
||||||
|
} else if (acceleremoter_type == ScanI2C::DeviceType::BMA423 && bmaSensor.getINT()) {
|
||||||
|
if (bmaSensor.isTilt() || bmaSensor.isDoubleClick()) {
|
||||||
|
wakeScreen();
|
||||||
|
return 500;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ACCELEROMETER_CHECK_INTERVAL_MS;
|
return ACCELEROMETER_CHECK_INTERVAL_MS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,9 +166,9 @@ class AccelerometerThread : public concurrency::OSThread
|
|||||||
powerFSM.trigger(EVENT_PRESS);
|
powerFSM.trigger(EVENT_PRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScanI2C::DeviceType accleremoter_type;
|
ScanI2C::DeviceType acceleremoter_type;
|
||||||
Adafruit_MPU6050 mpu;
|
Adafruit_MPU6050 mpu;
|
||||||
Adafruit_LIS3DH lis;
|
Adafruit_LIS3DH lis;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace concurrency
|
} // namespace concurrency
|
||||||
+3
-2
@@ -4,6 +4,7 @@
|
|||||||
#include "concurrency/OSThread.h"
|
#include "concurrency/OSThread.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "graphics/Screen.h"
|
#include "graphics/Screen.h"
|
||||||
|
#include "main.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include <OneButton.h>
|
#include <OneButton.h>
|
||||||
|
|
||||||
@@ -98,10 +99,10 @@ class ButtonThread : public concurrency::OSThread
|
|||||||
userButtonTouch.tick();
|
userButtonTouch.tick();
|
||||||
canSleep &= userButtonTouch.isIdle();
|
canSleep &= userButtonTouch.isIdle();
|
||||||
#endif
|
#endif
|
||||||
// if (!canSleep) LOG_DEBUG("Supressing sleep!\n");
|
// if (!canSleep) LOG_DEBUG("Suppressing sleep!\n");
|
||||||
// else LOG_DEBUG("sleep ok\n");
|
// else LOG_DEBUG("sleep ok\n");
|
||||||
|
|
||||||
return 5;
|
return 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
#ifdef SDCARD_USE_SPI1
|
#ifdef SDCARD_USE_SPI1
|
||||||
SPIClass SPI1(HSPI);
|
SPIClass SPI1(HSPI);
|
||||||
#define SDHandler SPI1
|
#define SDHandler SPI1
|
||||||
|
#else
|
||||||
|
#define SDHandler SPI
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // HAS_SDCARD
|
#endif // HAS_SDCARD
|
||||||
|
|||||||
+1
-1
@@ -106,7 +106,7 @@ class GPSStatus : public Status
|
|||||||
bool matches(const GPSStatus *newStatus) const
|
bool matches(const GPSStatus *newStatus) const
|
||||||
{
|
{
|
||||||
#ifdef GPS_EXTRAVERBOSE
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
LOG_DEBUG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.pos_timestamp, p.pos_timestamp);
|
LOG_DEBUG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.timestamp, p.timestamp);
|
||||||
#endif
|
#endif
|
||||||
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected ||
|
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected ||
|
||||||
newStatus->isPowerSaving != isPowerSaving || newStatus->p.latitude_i != p.latitude_i ||
|
newStatus->isPowerSaving != isPowerSaving || newStatus->p.latitude_i != p.latitude_i ||
|
||||||
|
|||||||
+2
-1
@@ -5,7 +5,8 @@
|
|||||||
* Schedule a callback to run. The callback must _not_ block, though it is called from regular thread level (not ISR)
|
* Schedule a callback to run. The callback must _not_ block, though it is called from regular thread level (not ISR)
|
||||||
*
|
*
|
||||||
* NOTE! xTimerPend... seems to ignore the time passed in on ESP32 and on NRF52
|
* NOTE! xTimerPend... seems to ignore the time passed in on ESP32 and on NRF52
|
||||||
* The reason this didn't work is bcause xTimerPednFunctCall really isn't a timer function at all - it just means run the callback
|
* The reason this didn't work is because xTimerPednFunctCall really isn't a timer function at all - it just means run the
|
||||||
|
callback
|
||||||
* from the timer thread the next time you have spare cycles.
|
* from the timer thread the next time you have spare cycles.
|
||||||
*
|
*
|
||||||
* @return true if successful, false if the timer fifo is too full.
|
* @return true if successful, false if the timer fifo is too full.
|
||||||
|
|||||||
+12
-3
@@ -50,7 +50,7 @@ XPowersLibInterface *PMU = NULL;
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
// Copy of the base class defined in axp20x.h.
|
// Copy of the base class defined in axp20x.h.
|
||||||
// I'd rather not inlude axp20x.h as it brings Wire dependency.
|
// I'd rather not include axp20x.h as it brings Wire dependency.
|
||||||
class HasBatteryLevel
|
class HasBatteryLevel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -540,10 +540,12 @@ int32_t Power::runOnce()
|
|||||||
LOG_DEBUG("Battery removed\n");
|
LOG_DEBUG("Battery removed\n");
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
#ifndef T_WATCH_S3 // FIXME - why is this triggering on the T-Watch S3?
|
||||||
if (PMU->isPekeyLongPressIrq()) {
|
if (PMU->isPekeyLongPressIrq()) {
|
||||||
LOG_DEBUG("PEK long button press\n");
|
LOG_DEBUG("PEK long button press\n");
|
||||||
screen->setOn(false);
|
screen->setOn(false);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
PMU->clearIrqStatus();
|
PMU->clearIrqStatus();
|
||||||
}
|
}
|
||||||
@@ -681,7 +683,8 @@ bool Power::axpChipInit()
|
|||||||
// GNSS VDD 3300mV
|
// GNSS VDD 3300mV
|
||||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
|
PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300);
|
||||||
PMU->enablePowerOutput(XPOWERS_ALDO3);
|
PMU->enablePowerOutput(XPOWERS_ALDO3);
|
||||||
} else if (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE) {
|
} else if (HW_VENDOR == meshtastic_HardwareModel_LILYGO_TBEAM_S3_CORE ||
|
||||||
|
HW_VENDOR == meshtastic_HardwareModel_T_WATCH_S3) {
|
||||||
// t-beam s3 core
|
// t-beam s3 core
|
||||||
/**
|
/**
|
||||||
* gnss module power channel
|
* gnss module power channel
|
||||||
@@ -712,10 +715,16 @@ bool Power::axpChipInit()
|
|||||||
PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300);
|
PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300);
|
||||||
PMU->enablePowerOutput(XPOWERS_ALDO1);
|
PMU->enablePowerOutput(XPOWERS_ALDO1);
|
||||||
|
|
||||||
// sdcard power channle
|
// sdcard power channel
|
||||||
PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300);
|
PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300);
|
||||||
PMU->enablePowerOutput(XPOWERS_BLDO1);
|
PMU->enablePowerOutput(XPOWERS_BLDO1);
|
||||||
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
// DRV2605 power channel
|
||||||
|
PMU->setPowerChannelVoltage(XPOWERS_BLDO2, 3300);
|
||||||
|
PMU->enablePowerOutput(XPOWERS_BLDO2);
|
||||||
|
#endif
|
||||||
|
|
||||||
// PMU->setPowerChannelVoltage(XPOWERS_DCDC4, 3300);
|
// PMU->setPowerChannelVoltage(XPOWERS_DCDC4, 3300);
|
||||||
// PMU->enablePowerOutput(XPOWERS_DCDC4);
|
// PMU->enablePowerOutput(XPOWERS_DCDC4);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -352,5 +352,5 @@ void PowerFSM_setup()
|
|||||||
"mesh timeout");
|
"mesh timeout");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
powerFSM.run_machine(); // run one interation of the state machine, so we run our on enter tasks for the initial DARK state
|
powerFSM.run_machine(); // run one iteration of the state machine, so we run our on enter tasks for the initial DARK state
|
||||||
}
|
}
|
||||||
+2
-2
@@ -17,9 +17,9 @@
|
|||||||
|
|
||||||
Example analytics:
|
Example analytics:
|
||||||
|
|
||||||
TX_LOG + RX_LOG = Total air time for a perticular meshtastic channel.
|
TX_LOG + RX_LOG = Total air time for a particular meshtastic channel.
|
||||||
|
|
||||||
TX_LOG + RX_LOG = Total air time for a perticular meshtastic channel, including
|
TX_LOG + RX_LOG = Total air time for a particular meshtastic channel, including
|
||||||
other lora radios.
|
other lora radios.
|
||||||
|
|
||||||
RX_ALL_LOG - RX_LOG = Other lora radios on our frequency channel.
|
RX_ALL_LOG - RX_LOG = Other lora radios on our frequency channel.
|
||||||
|
|||||||
@@ -15,4 +15,6 @@ enum class Cmd {
|
|||||||
PRINT,
|
PRINT,
|
||||||
START_SHUTDOWN_SCREEN,
|
START_SHUTDOWN_SCREEN,
|
||||||
START_REBOOT_SCREEN,
|
START_REBOOT_SCREEN,
|
||||||
|
SHOW_PREV_FRAME,
|
||||||
|
SHOW_NEXT_FRAME
|
||||||
};
|
};
|
||||||
@@ -18,7 +18,7 @@ namespace concurrency
|
|||||||
*
|
*
|
||||||
* Useful for they top level loop() delay call to keep the CPU powered down until our next scheduled event or some external event.
|
* Useful for they top level loop() delay call to keep the CPU powered down until our next scheduled event or some external event.
|
||||||
*
|
*
|
||||||
* This is implmented for FreeRTOS but should be easy to port to other operating systems.
|
* This is implemented for FreeRTOS but should be easy to port to other operating systems.
|
||||||
*/
|
*/
|
||||||
class InterruptableDelay
|
class InterruptableDelay
|
||||||
{
|
{
|
||||||
|
|||||||
+10
-2
@@ -98,8 +98,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
// Define if screen should be mirrored left to right
|
// Define if screen should be mirrored left to right
|
||||||
// #define SCREEN_MIRROR
|
// #define SCREEN_MIRROR
|
||||||
|
|
||||||
// The m5stack I2C Keyboard (also RAK14004)
|
// I2C Keyboards (M5Stack, RAK14004, T-Deck)
|
||||||
#define CARDKB_ADDR 0x5F
|
#define CARDKB_ADDR 0x5F
|
||||||
|
#define TDECK_KB_ADDR 0x55
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// SENSOR
|
// SENSOR
|
||||||
@@ -123,6 +124,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
#define MPU6050_ADDR 0x68
|
#define MPU6050_ADDR 0x68
|
||||||
#define LIS3DH_ADR 0x18
|
#define LIS3DH_ADR 0x18
|
||||||
|
#define BMA423_ADDR 0x19
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// LED
|
// LED
|
||||||
@@ -172,6 +174,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#ifndef HAS_BUTTON
|
#ifndef HAS_BUTTON
|
||||||
#define HAS_BUTTON 0
|
#define HAS_BUTTON 0
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef HAS_TRACKBALL
|
||||||
|
#define HAS_TRACKBALL 0
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_TOUCHSCREEN
|
||||||
|
#define HAS_TOUCHSCREEN 0
|
||||||
|
#endif
|
||||||
#ifndef HAS_TELEMETRY
|
#ifndef HAS_TELEMETRY
|
||||||
#define HAS_TELEMETRY 0
|
#define HAS_TELEMETRY 0
|
||||||
#endif
|
#endif
|
||||||
@@ -193,4 +201,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#ifndef HW_VENDOR
|
#ifndef HW_VENDOR
|
||||||
#error HW_VENDOR must be defined
|
#error HW_VENDOR must be defined
|
||||||
#endif
|
#endif
|
||||||
@@ -30,14 +30,14 @@ ScanI2C::FoundDevice ScanI2C::firstRTC() const
|
|||||||
|
|
||||||
ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
|
ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
|
||||||
{
|
{
|
||||||
ScanI2C::DeviceType types[] = {CARDKB, RAK14004};
|
ScanI2C::DeviceType types[] = {CARDKB, TDECKKB, RAK14004};
|
||||||
return firstOfOrNONE(2, types);
|
return firstOfOrNONE(3, types);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
|
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
|
||||||
{
|
{
|
||||||
ScanI2C::DeviceType types[] = {MPU6050, LIS3DH};
|
ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423};
|
||||||
return firstOfOrNONE(2, types);
|
return firstOfOrNONE(3, types);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const
|
ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const
|
||||||
@@ -73,4 +73,4 @@ bool ScanI2C::DeviceAddress::operator<(const ScanI2C::DeviceAddress &other) cons
|
|||||||
|| (port != NO_I2C && other.port != NO_I2C && (address < other.address));
|
|| (port != NO_I2C && other.port != NO_I2C && (address < other.address));
|
||||||
}
|
}
|
||||||
|
|
||||||
ScanI2C::FoundDevice::FoundDevice(ScanI2C::DeviceType type, ScanI2C::DeviceAddress address) : type(type), address(address) {}
|
ScanI2C::FoundDevice::FoundDevice(ScanI2C::DeviceType type, ScanI2C::DeviceAddress address) : type(type), address(address) {}
|
||||||
@@ -16,6 +16,7 @@ class ScanI2C
|
|||||||
RTC_RV3028,
|
RTC_RV3028,
|
||||||
RTC_PCF8563,
|
RTC_PCF8563,
|
||||||
CARDKB,
|
CARDKB,
|
||||||
|
TDECKKB,
|
||||||
RAK14004,
|
RAK14004,
|
||||||
PMU_AXP192_AXP2101,
|
PMU_AXP192_AXP2101,
|
||||||
BME_680,
|
BME_680,
|
||||||
@@ -33,7 +34,10 @@ class ScanI2C
|
|||||||
PMSA0031,
|
PMSA0031,
|
||||||
MPU6050,
|
MPU6050,
|
||||||
LIS3DH,
|
LIS3DH,
|
||||||
|
BMA423,
|
||||||
|
#ifdef HAS_NCP5623
|
||||||
NCP5623,
|
NCP5623,
|
||||||
|
#endif
|
||||||
} DeviceType;
|
} DeviceType;
|
||||||
|
|
||||||
// typedef uint8_t DeviceAddress;
|
// typedef uint8_t DeviceAddress;
|
||||||
@@ -95,4 +99,4 @@ class ScanI2C
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool shouldSuppressScreen = false;
|
bool shouldSuppressScreen = false;
|
||||||
};
|
};
|
||||||
@@ -212,9 +212,11 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found\n")
|
SCAN_SIMPLE_CASE(TDECK_KB_ADDR, TDECKKB, "T-Deck keyboard found\n");
|
||||||
|
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found\n");
|
||||||
|
#ifdef HAS_NCP5623
|
||||||
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found\n");
|
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623 RGB LED found\n");
|
||||||
|
#endif
|
||||||
#ifdef HAS_PMU
|
#ifdef HAS_PMU
|
||||||
SCAN_SIMPLE_CASE(XPOWERS_AXP192_AXP2101_ADDRESS, PMU_AXP192_AXP2101, "axp192/axp2101 PMU found\n")
|
SCAN_SIMPLE_CASE(XPOWERS_AXP192_AXP2101_ADDRESS, PMU_AXP192_AXP2101, "axp192/axp2101 PMU found\n")
|
||||||
#endif
|
#endif
|
||||||
@@ -273,6 +275,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
|
|||||||
|
|
||||||
SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found\n")
|
SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found\n")
|
||||||
SCAN_SIMPLE_CASE(MPU6050_ADDR, MPU6050, "MPU6050 accelerometer found\n");
|
SCAN_SIMPLE_CASE(MPU6050_ADDR, MPU6050, "MPU6050 accelerometer found\n");
|
||||||
|
SCAN_SIMPLE_CASE(BMA423_ADDR, BMA423, "BMA423 accelerometer found\n");
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address);
|
LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address);
|
||||||
@@ -305,4 +308,4 @@ TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address) const
|
|||||||
size_t ScanI2CTwoWire::countDevices() const
|
size_t ScanI2CTwoWire::countDevices() const
|
||||||
{
|
{
|
||||||
return foundDevices.size();
|
return foundDevices.size();
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "../configuration.h"
|
#include "../configuration.h"
|
||||||
|
|
||||||
#ifdef RAK4630
|
#ifdef RAK_4631
|
||||||
#include "../main.h"
|
#include "../main.h"
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
|
|
||||||
@@ -64,4 +64,4 @@ void scanEInkDevice(void)
|
|||||||
LOG_DEBUG("EInk display not found\n");
|
LOG_DEBUG("EInk display not found\n");
|
||||||
SPI1.end();
|
SPI1.end();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
+388
-73
@@ -4,6 +4,10 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
|
|
||||||
|
#ifndef GPS_RESET_MODE
|
||||||
|
#define GPS_RESET_MODE HIGH
|
||||||
|
#endif
|
||||||
|
|
||||||
// If we have a serial GPS port it will not be null
|
// If we have a serial GPS port it will not be null
|
||||||
#ifdef GPS_SERIAL_NUM
|
#ifdef GPS_SERIAL_NUM
|
||||||
HardwareSerial _serial_gps_real(GPS_SERIAL_NUM);
|
HardwareSerial _serial_gps_real(GPS_SERIAL_NUM);
|
||||||
@@ -21,11 +25,29 @@ GPS *gps;
|
|||||||
/// only init that port once.
|
/// only init that port once.
|
||||||
static bool didSerialInit;
|
static bool didSerialInit;
|
||||||
|
|
||||||
bool GPS::getACK(uint8_t c, uint8_t i)
|
struct uBloxGnssModelInfo info;
|
||||||
|
uint8_t uBloxProtocolVersion;
|
||||||
|
|
||||||
|
void GPS::UBXChecksum(byte *message, size_t length)
|
||||||
|
{
|
||||||
|
uint8_t CK_A = 0, CK_B = 0;
|
||||||
|
|
||||||
|
// Calculate the checksum, starting from the CLASS field (which is message[2])
|
||||||
|
for (size_t i = 2; i < length - 2; i++) {
|
||||||
|
CK_A = (CK_A + message[i]) & 0xFF;
|
||||||
|
CK_B = (CK_B + CK_A) & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Place the calculated checksum values in the message
|
||||||
|
message[length - 2] = CK_A;
|
||||||
|
message[length - 1] = CK_B;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GPS::getACK(uint8_t class_id, uint8_t msg_id)
|
||||||
{
|
{
|
||||||
uint8_t b;
|
uint8_t b;
|
||||||
uint8_t ack = 0;
|
uint8_t ack = 0;
|
||||||
const uint8_t ackP[2] = {c, i};
|
const uint8_t ackP[2] = {class_id, msg_id};
|
||||||
uint8_t buf[10] = {0xB5, 0x62, 0x05, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};
|
uint8_t buf[10] = {0xB5, 0x62, 0x05, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
unsigned long startTime = millis();
|
unsigned long startTime = millis();
|
||||||
|
|
||||||
@@ -42,17 +64,23 @@ bool GPS::getACK(uint8_t c, uint8_t i)
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (ack > 9) {
|
if (ack > 9) {
|
||||||
return true;
|
// LOG_INFO("Got ACK for class %02X message %02X\n", class_id, msg_id);
|
||||||
|
return true; // ACK received
|
||||||
}
|
}
|
||||||
if (millis() - startTime > 1000) {
|
if (millis() - startTime > 3000) {
|
||||||
return false;
|
LOG_WARN("No response for class %02X message %02X\n", class_id, msg_id);
|
||||||
|
return false; // No response received within 3 seconds
|
||||||
}
|
}
|
||||||
if (_serial_gps->available()) {
|
if (_serial_gps->available()) {
|
||||||
b = _serial_gps->read();
|
b = _serial_gps->read();
|
||||||
if (b == buf[ack]) {
|
if (b == buf[ack]) {
|
||||||
ack++;
|
ack++;
|
||||||
} else {
|
} else {
|
||||||
ack = 0;
|
ack = 0; // Reset the acknowledgement counter
|
||||||
|
if (buf[3] == 0x00) { // UBX-ACK-NAK message
|
||||||
|
LOG_WARN("Got NAK for class %02X message %02X\n", class_id, msg_id);
|
||||||
|
return false; // NAK received
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,7 +101,7 @@ int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
|
|||||||
uint32_t startTime = millis();
|
uint32_t startTime = millis();
|
||||||
uint16_t needRead;
|
uint16_t needRead;
|
||||||
|
|
||||||
while (millis() - startTime < 800) {
|
while (millis() - startTime < 1200) {
|
||||||
while (_serial_gps->available()) {
|
while (_serial_gps->available()) {
|
||||||
int c = _serial_gps->read();
|
int c = _serial_gps->read();
|
||||||
switch (ubxFrameCounter) {
|
switch (ubxFrameCounter) {
|
||||||
@@ -108,12 +136,12 @@ int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
// Payload lenght lsb
|
// Payload length lsb
|
||||||
needRead = c;
|
needRead = c;
|
||||||
ubxFrameCounter++;
|
ubxFrameCounter++;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
// Payload lenght msb
|
// Payload length msb
|
||||||
needRead |= (c << 8);
|
needRead |= (c << 8);
|
||||||
ubxFrameCounter++;
|
ubxFrameCounter++;
|
||||||
break;
|
break;
|
||||||
@@ -126,7 +154,7 @@ int GPS::getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t
|
|||||||
if (_serial_gps->readBytes(buffer, needRead) != needRead) {
|
if (_serial_gps->readBytes(buffer, needRead) != needRead) {
|
||||||
ubxFrameCounter = 0;
|
ubxFrameCounter = 0;
|
||||||
} else {
|
} else {
|
||||||
// return payload lenght
|
// return payload length
|
||||||
return needRead;
|
return needRead;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -160,10 +188,14 @@ bool GPS::setupGPS()
|
|||||||
config.position.tx_gpio = GPS_TX_PIN;
|
config.position.tx_gpio = GPS_TX_PIN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//#define BAUD_RATE 115200
|
||||||
// ESP32 has a special set of parameters vs other arduino ports
|
// ESP32 has a special set of parameters vs other arduino ports
|
||||||
#if defined(ARCH_ESP32)
|
#if defined(ARCH_ESP32)
|
||||||
if (config.position.rx_gpio)
|
if (config.position.rx_gpio) {
|
||||||
|
LOG_DEBUG("Using GPIO%d for GPS RX\n", config.position.rx_gpio);
|
||||||
|
LOG_DEBUG("Using GPIO%d for GPS TX\n", config.position.tx_gpio);
|
||||||
_serial_gps->begin(GPS_BAUDRATE, SERIAL_8N1, config.position.rx_gpio, config.position.tx_gpio);
|
_serial_gps->begin(GPS_BAUDRATE, SERIAL_8N1, config.position.rx_gpio, config.position.tx_gpio);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
_serial_gps->begin(GPS_BAUDRATE);
|
_serial_gps->begin(GPS_BAUDRATE);
|
||||||
#endif
|
#endif
|
||||||
@@ -190,8 +222,131 @@ bool GPS::setupGPS()
|
|||||||
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
|
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
|
||||||
_serial_gps->write("$PCAS11,3*1E\r\n");
|
_serial_gps->write("$PCAS11,3*1E\r\n");
|
||||||
delay(250);
|
delay(250);
|
||||||
|
} else if (gnssModel == GNSS_MODEL_UC6850) {
|
||||||
|
|
||||||
|
// use GPS + GLONASS
|
||||||
|
_serial_gps->write("$CFGSYS,h15\r\n");
|
||||||
|
delay(250);
|
||||||
} else if (gnssModel == GNSS_MODEL_UBLOX) {
|
} else if (gnssModel == GNSS_MODEL_UBLOX) {
|
||||||
|
|
||||||
|
// Configure GNSS system to GPS+SBAS+GLONASS (Module may restart after this command)
|
||||||
|
// We need set it because by default it is GPS only, and we want to use GLONASS too
|
||||||
|
// Also we need SBAS for better accuracy and extra features
|
||||||
|
// ToDo: Dynamic configure GNSS systems depending of LoRa region
|
||||||
|
byte _message_GNSS[36] = {
|
||||||
|
0xb5, 0x62, // Sync message for UBX protocol
|
||||||
|
0x06, 0x3e, // Message class and ID (UBX-CFG-GNSS)
|
||||||
|
0x1c, 0x00, // Length of payload (28 bytes)
|
||||||
|
0x00, // msgVer (0 for this version)
|
||||||
|
0x00, // numTrkChHw (max number of hardware channels, read only, so it's always 0)
|
||||||
|
0xff, // numTrkChUse (max number of channels to use, 0xff = max available)
|
||||||
|
0x03, // numConfigBlocks (number of GNSS systems), most modules support maximum 3 GNSS systems
|
||||||
|
// GNSS config format: gnssId, resTrkCh, maxTrkCh, reserved1, flags
|
||||||
|
0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, // GPS
|
||||||
|
0x01, 0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0x01, // SBAS
|
||||||
|
0x06, 0x08, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x01, // GLONASS
|
||||||
|
0x00, 0x00 // Checksum (to be calculated below)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Calculate the checksum and update the message.
|
||||||
|
UBXChecksum(_message_GNSS, sizeof(_message_GNSS));
|
||||||
|
|
||||||
|
// Send the message to the module
|
||||||
|
_serial_gps->write(_message_GNSS, sizeof(_message_GNSS));
|
||||||
|
|
||||||
|
if (!getACK(0x06, 0x3e)) {
|
||||||
|
// It's not critical if the module doesn't acknowledge this configuration.
|
||||||
|
// The module should operate adequately with its factory or previously saved settings.
|
||||||
|
// It appears that there is a firmware bug in some GPS modules: When an attempt is made
|
||||||
|
// to overwrite a saved state with identical values, no ACK/NAK is received, contrary to
|
||||||
|
// what is specified in the Ublox documentation.
|
||||||
|
// There is also a possibility that the module may be GPS-only.
|
||||||
|
LOG_INFO("Unable to reconfigure GNSS - defaults maintained. Is this module GPS-only?\n");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
LOG_INFO("GNSS configured for GPS+SBAS+GLONASS. Pause for 0.75s before sending next command.\n");
|
||||||
|
// Documentation say, we need wait atleast 0.5s after reconfiguration of GNSS module, before sending next commands
|
||||||
|
delay(750);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable interference resistance, because we are using LoRa, WiFi and Bluetooth on same board,
|
||||||
|
// and we need to reduce interference from them
|
||||||
|
byte _message_JAM[16] = {
|
||||||
|
0xB5, 0x62, // UBX protocol sync characters
|
||||||
|
0x06, 0x39, // Message class and ID (UBX-CFG-ITFM)
|
||||||
|
0x08, 0x00, // Length of payload (8 bytes)
|
||||||
|
// bbThreshold (Broadband jamming detection threshold) is set to 0x3F (63 in decimal)
|
||||||
|
// cwThreshold (CW jamming detection threshold) is set to 0x10 (16 in decimal)
|
||||||
|
// algorithmBits (Reserved algorithm settings) is set to 0x16B156 as recommended
|
||||||
|
// enable (Enable interference detection) is set to 1 (enabled)
|
||||||
|
0x3F, 0x10, 0xB1, 0x56, // config: Interference config word
|
||||||
|
// generalBits (General settings) is set to 0x31E as recommended
|
||||||
|
// antSetting (Antenna setting, 0=unknown, 1=passive, 2=active) is set to 0 (unknown)
|
||||||
|
// ToDo: Set to 1 (passive) or 2 (active) if known, for example from UBX-MON-HW, or from board info
|
||||||
|
// enable2 (Set to 1 to scan auxiliary bands, u-blox 8 / u-blox M8 only, otherwise ignored) is set to 1
|
||||||
|
// (enabled)
|
||||||
|
0x1E, 0x03, 0x00, 0x01, // config2: Extra settings for jamming/interference monitor
|
||||||
|
0x00, 0x00 // Checksum (calculated below)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Calculate the checksum and update the message.
|
||||||
|
UBXChecksum(_message_JAM, sizeof(_message_JAM));
|
||||||
|
|
||||||
|
// Send the message to the module
|
||||||
|
_serial_gps->write(_message_JAM, sizeof(_message_JAM));
|
||||||
|
|
||||||
|
if (!getACK(0x06, 0x39)) {
|
||||||
|
LOG_WARN("Unable to enable interference resistance.\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure navigation engine expert settings:
|
||||||
|
byte _message_NAVX5[48] = {
|
||||||
|
0xb5, 0x62, // UBX protocol sync characters
|
||||||
|
0x06, 0x23, // Message class and ID (UBX-CFG-NAVX5)
|
||||||
|
0x28, 0x00, // Length of payload (40 bytes)
|
||||||
|
0x00, 0x00, // msgVer (0 for this version)
|
||||||
|
// minMax flag = 1: apply min/max SVs settings
|
||||||
|
// minCno flag = 1: apply minimum C/N0 setting
|
||||||
|
// initial3dfix flag = 0: apply initial 3D fix settings
|
||||||
|
// aop flag = 1: apply aopCfg (useAOP flag) settings (AssistNow Autonomous)
|
||||||
|
0x1B, 0x00, // mask1 (First parameters bitmask)
|
||||||
|
// adr flag = 0: apply ADR sensor fusion on/off setting (useAdr flag)
|
||||||
|
// If firmware is not ADR/UDR, enabling this flag will fail configuration
|
||||||
|
// ToDo: check this with UBX-MON-VER
|
||||||
|
0x00, 0x00, 0x00, 0x00, // mask2 (Second parameters bitmask)
|
||||||
|
0x00, 0x00, // Reserved
|
||||||
|
0x03, // minSVs (Minimum number of satellites for navigation) = 3
|
||||||
|
0x10, // maxSVs (Maximum number of satellites for navigation) = 16
|
||||||
|
0x06, // minCNO (Minimum satellite signal level for navigation) = 6 dBHz
|
||||||
|
0x00, // Reserved
|
||||||
|
0x00, // iniFix3D (Initial fix must be 3D) = 0 (disabled)
|
||||||
|
0x00, 0x00, // Reserved
|
||||||
|
0x00, // ackAiding (Issue acknowledgements for assistance message input) = 0 (disabled)
|
||||||
|
0x00, 0x00, // Reserved
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reserved
|
||||||
|
0x00, // Reserved
|
||||||
|
0x01, // aopCfg (AssistNow Autonomous configuration) = 1 (enabled)
|
||||||
|
0x00, 0x00, // Reserved
|
||||||
|
0x00, 0x00, // Reserved
|
||||||
|
0x00, 0x00, 0x00, 0x00, // Reserved
|
||||||
|
0x00, 0x00, 0x00, // Reserved
|
||||||
|
0x01, // useAdr (Enable/disable ADR sensor fusion) = 1 (enabled)
|
||||||
|
0x00, 0x00 // Checksum (calculated below)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Calculate the checksum and update the message.
|
||||||
|
UBXChecksum(_message_NAVX5, sizeof(_message_NAVX5));
|
||||||
|
|
||||||
|
// Send the message to the module
|
||||||
|
_serial_gps->write(_message_NAVX5, sizeof(_message_NAVX5));
|
||||||
|
|
||||||
|
if (!getACK(0x06, 0x23)) {
|
||||||
|
LOG_WARN("Unable to configure extra settings.\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
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
|
setting will not output command messages in UART1, resulting in unrecognized module information
|
||||||
@@ -208,57 +363,205 @@ bool GPS::setupGPS()
|
|||||||
|
|
||||||
// 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
|
// Set GPS update rate to 1Hz
|
||||||
byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01,
|
// Lowering the update rate helps to save power.
|
||||||
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x05, 0x3A};
|
// Additionally, for some new modules like the M9/M10, an update rate lower than 5Hz
|
||||||
|
// is recommended to avoid a known issue with satellites disappearing.
|
||||||
|
byte _message_1Hz[] = {
|
||||||
|
0xB5, 0x62, // UBX protocol sync characters
|
||||||
|
0x06, 0x08, // Message class and ID (UBX-CFG-RATE)
|
||||||
|
0x06, 0x00, // Length of payload (6 bytes)
|
||||||
|
0xE8, 0x03, // Measurement Rate (1000ms for 1Hz)
|
||||||
|
0x01, 0x00, // Navigation rate, always 1 in GPS mode
|
||||||
|
0x01, 0x00, // Time reference
|
||||||
|
0x00, 0x00 // Placeholder for checksum, will be calculated next
|
||||||
|
};
|
||||||
|
|
||||||
|
// Calculate the checksum and update the message.
|
||||||
|
UBXChecksum(_message_1Hz, sizeof(_message_1Hz));
|
||||||
|
|
||||||
|
// Send the message to the module
|
||||||
|
_serial_gps->write(_message_1Hz, sizeof(_message_1Hz));
|
||||||
|
|
||||||
|
if (!getACK(0x06, 0x08)) {
|
||||||
|
LOG_WARN("Unable to set GPS update rate.\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable GGL. GGL - Geographic position (latitude and longitude), which provides the current geographical
|
||||||
|
// coordinates.
|
||||||
|
byte _message_GGL[] = {
|
||||||
|
0xB5, 0x62, // UBX sync characters
|
||||||
|
0x06, 0x01, // Message class and ID (UBX-CFG-MSG)
|
||||||
|
0x08, 0x00, // Length of payload (8 bytes)
|
||||||
|
0xF0, 0x01, // NMEA ID for GLL
|
||||||
|
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||||
|
0x00, // Disable
|
||||||
|
0x01, 0x01, 0x01, 0x01, // Reserved
|
||||||
|
0x00, 0x00 // CK_A and CK_B (Checksum)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Calculate the checksum and update the message.
|
||||||
|
UBXChecksum(_message_GGL, sizeof(_message_GGL));
|
||||||
|
|
||||||
|
// Send the message to the module
|
||||||
_serial_gps->write(_message_GGL, sizeof(_message_GGL));
|
_serial_gps->write(_message_GGL, sizeof(_message_GGL));
|
||||||
|
|
||||||
if (!getACK(0x06, 0x01)) {
|
if (!getACK(0x06, 0x01)) {
|
||||||
LOG_WARN("Unable to disable NMEA GGL.\n");
|
LOG_WARN("Unable to disable NMEA GGL.\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// disable GSA
|
// Enable GSA. GSA - GPS DOP and active satellites, used for detailing the satellites used in the positioning and
|
||||||
byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02,
|
// the DOP (Dilution of Precision)
|
||||||
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x41};
|
byte _message_GSA[] = {
|
||||||
|
0xB5, 0x62, // UBX sync characters
|
||||||
|
0x06, 0x01, // Message class and ID (UBX-CFG-MSG)
|
||||||
|
0x08, 0x00, // Length of payload (8 bytes)
|
||||||
|
0xF0, 0x02, // NMEA ID for GSA
|
||||||
|
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||||
|
0x01, // Enable
|
||||||
|
0x01, 0x01, 0x01, 0x01, // Reserved
|
||||||
|
0x00, 0x00 // CK_A and CK_B (Checksum)
|
||||||
|
};
|
||||||
|
UBXChecksum(_message_GSA, sizeof(_message_GSA));
|
||||||
_serial_gps->write(_message_GSA, sizeof(_message_GSA));
|
_serial_gps->write(_message_GSA, sizeof(_message_GSA));
|
||||||
if (!getACK(0x06, 0x01)) {
|
if (!getACK(0x06, 0x01)) {
|
||||||
LOG_WARN("Unable to disable NMEA GSA.\n");
|
LOG_WARN("Unable to Enable NMEA GSA.\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// disable GSV
|
// Disable GSV. GSV - Satellites in view, details the number and location of satellites in view.
|
||||||
byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03,
|
byte _message_GSV[] = {
|
||||||
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x48};
|
0xB5, 0x62, // UBX sync characters
|
||||||
|
0x06, 0x01, // Message class and ID (UBX-CFG-MSG)
|
||||||
|
0x08, 0x00, // Length of payload (8 bytes)
|
||||||
|
0xF0, 0x03, // NMEA ID for GSV
|
||||||
|
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||||
|
0x00, // Disable
|
||||||
|
0x01, 0x01, 0x01, 0x01, // Reserved
|
||||||
|
0x00, 0x00 // CK_A and CK_B (Checksum)
|
||||||
|
};
|
||||||
|
UBXChecksum(_message_GSV, sizeof(_message_GSV));
|
||||||
_serial_gps->write(_message_GSV, sizeof(_message_GSV));
|
_serial_gps->write(_message_GSV, sizeof(_message_GSV));
|
||||||
if (!getACK(0x06, 0x01)) {
|
if (!getACK(0x06, 0x01)) {
|
||||||
LOG_WARN("Unable to disable NMEA GSV.\n");
|
LOG_WARN("Unable to disable NMEA GSV.\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// disable VTG
|
// Disable VTG. VTG - Track made good and ground speed, which provides course and speed information relative to
|
||||||
byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05,
|
// the ground.
|
||||||
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x09, 0x56};
|
byte _message_VTG[] = {
|
||||||
|
0xB5, 0x62, // UBX sync characters
|
||||||
|
0x06, 0x01, // Message class and ID (UBX-CFG-MSG)
|
||||||
|
0x08, 0x00, // Length of payload (8 bytes)
|
||||||
|
0xF0, 0x05, // NMEA ID for VTG
|
||||||
|
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||||
|
0x00, // Disable
|
||||||
|
0x01, 0x01, 0x01, 0x01, // Reserved
|
||||||
|
0x00, 0x00 // CK_A and CK_B (Checksum)
|
||||||
|
};
|
||||||
|
UBXChecksum(_message_VTG, sizeof(_message_VTG));
|
||||||
_serial_gps->write(_message_VTG, sizeof(_message_VTG));
|
_serial_gps->write(_message_VTG, sizeof(_message_VTG));
|
||||||
if (!getACK(0x06, 0x01)) {
|
if (!getACK(0x06, 0x01)) {
|
||||||
LOG_WARN("Unable to disable NMEA VTG.\n");
|
LOG_WARN("Unable to disable NMEA VTG.\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable RMC
|
// Enable RMC. RMC - Recommended Minimum data, the essential gps pvt (position, velocity, time) data.
|
||||||
byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04,
|
byte _message_RMC[] = {
|
||||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09, 0x54};
|
0xB5, 0x62, // UBX sync characters
|
||||||
|
0x06, 0x01, // Message class and ID (UBX-CFG-MSG)
|
||||||
|
0x08, 0x00, // Length of payload (8 bytes)
|
||||||
|
0xF0, 0x04, // NMEA ID for RMC
|
||||||
|
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||||
|
0x01, // Enable
|
||||||
|
0x01, 0x01, 0x01, 0x01, // Reserved
|
||||||
|
0x00, 0x00 // CK_A and CK_B (Checksum)
|
||||||
|
};
|
||||||
|
UBXChecksum(_message_RMC, sizeof(_message_RMC));
|
||||||
_serial_gps->write(_message_RMC, sizeof(_message_RMC));
|
_serial_gps->write(_message_RMC, sizeof(_message_RMC));
|
||||||
if (!getACK(0x06, 0x01)) {
|
if (!getACK(0x06, 0x01)) {
|
||||||
LOG_WARN("Unable to enable NMEA RMC.\n");
|
LOG_WARN("Unable to enable NMEA RMC.\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable GGA
|
// Enable GGA. GGA - Global Positioning System Fix Data, which provides 3D location and accuracy data.
|
||||||
byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00,
|
byte _message_GGA[] = {
|
||||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x38};
|
0xB5, 0x62, // UBX sync characters
|
||||||
|
0x06, 0x01, // Message class and ID (UBX-CFG-MSG)
|
||||||
|
0x08, 0x00, // Length of payload (8 bytes)
|
||||||
|
0xF0, 0x00, // NMEA ID for GGA
|
||||||
|
0x01, // I/O Target 0=I/O, 1=UART1, 2=UART2, 3=USB, 4=SPI
|
||||||
|
0x01, // Enable
|
||||||
|
0x01, 0x01, 0x01, 0x01, // Reserved
|
||||||
|
0x00, 0x00 // CK_A and CK_B (Checksum)
|
||||||
|
};
|
||||||
|
UBXChecksum(_message_GGA, sizeof(_message_GGA));
|
||||||
_serial_gps->write(_message_GGA, sizeof(_message_GGA));
|
_serial_gps->write(_message_GGA, sizeof(_message_GGA));
|
||||||
if (!getACK(0x06, 0x01)) {
|
if (!getACK(0x06, 0x01)) {
|
||||||
LOG_WARN("Unable to enable NMEA GGA.\n");
|
LOG_WARN("Unable to enable NMEA GGA.\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The Power Management configuration allows the GPS module to operate in different power modes for optimized power
|
||||||
|
// consumption.
|
||||||
|
// The modes supported are:
|
||||||
|
// 0x00 = Full power: The module operates at full power with no power saving.
|
||||||
|
// 0x01 = Balanced: The module dynamically adjusts the tracking behavior to balance power consumption.
|
||||||
|
// 0x02 = Interval: The module operates in a periodic mode, cycling between tracking and power saving states.
|
||||||
|
// 0x03 = Aggressive with 1 Hz: The module operates in a power saving mode with a 1 Hz update rate.
|
||||||
|
// 0x04 = Aggressive with 2 Hz: The module operates in a power saving mode with a 2 Hz update rate.
|
||||||
|
// 0x05 = Aggressive with 4 Hz: The module operates in a power saving mode with a 4 Hz update rate.
|
||||||
|
// The 'period' field specifies the position update and search period. It is only valid when the powerSetupValue is
|
||||||
|
// set to Interval; otherwise, it must be set to '0'. The 'onTime' field specifies the duration of the ON phase and
|
||||||
|
// must be smaller than the period. It is only valid when the powerSetupValue is set to Interval; otherwise, it must
|
||||||
|
// be set to '0'.
|
||||||
|
byte UBX_CFG_PMS[14] = {
|
||||||
|
0xB5, 0x62, // UBX sync characters
|
||||||
|
0x06, 0x86, // Message class and ID (UBX-CFG-PMS)
|
||||||
|
0x06, 0x00, // Length of payload (6 bytes)
|
||||||
|
0x00, // Version (0)
|
||||||
|
0x03, // Power setup value
|
||||||
|
0x00, 0x00, // period: not applicable, set to 0
|
||||||
|
0x00, 0x00, // onTime: not applicable, set to 0
|
||||||
|
0x00, 0x00 // Placeholder for checksum, will be calculated next
|
||||||
|
};
|
||||||
|
|
||||||
|
// Calculate the checksum and update the message
|
||||||
|
UBXChecksum(UBX_CFG_PMS, sizeof(UBX_CFG_PMS));
|
||||||
|
|
||||||
|
// Send the message to the module
|
||||||
|
_serial_gps->write(UBX_CFG_PMS, sizeof(UBX_CFG_PMS));
|
||||||
|
if (!getACK(0x06, 0x86)) {
|
||||||
|
LOG_WARN("Unable to enable powersaving for GPS.\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need save configuration to flash to make our config changes persistent
|
||||||
|
byte _message_SAVE[21] = {
|
||||||
|
0xB5, 0x62, // UBX protocol header
|
||||||
|
0x06, 0x09, // UBX class ID (Configuration Input Messages), message ID (UBX-CFG-CFG)
|
||||||
|
0x0D, 0x00, // Length of payload (13 bytes)
|
||||||
|
0x00, 0x00, 0x00, 0x00, // clearMask: no sections cleared
|
||||||
|
0xFF, 0xFF, 0x00, 0x00, // saveMask: save all sections
|
||||||
|
0x00, 0x00, 0x00, 0x00, // loadMask: no sections loaded
|
||||||
|
0x0F, // deviceMask: BBR, Flash, EEPROM, and SPI Flash
|
||||||
|
0x00, 0x00 // Checksum (calculated below)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Calculate the checksum and update the message.
|
||||||
|
UBXChecksum(_message_SAVE, sizeof(_message_SAVE));
|
||||||
|
|
||||||
|
// Send the message to the module
|
||||||
|
_serial_gps->write(_message_SAVE, sizeof(_message_SAVE));
|
||||||
|
|
||||||
|
if (!getACK(0x06, 0x09)) {
|
||||||
|
LOG_WARN("Unable to save GNSS module configuration.\n");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
LOG_INFO("GNSS module configuration saved!\n");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -269,22 +572,21 @@ bool GPS::setupGPS()
|
|||||||
bool GPS::setup()
|
bool GPS::setup()
|
||||||
{
|
{
|
||||||
// Master power for the GPS
|
// Master power for the GPS
|
||||||
#ifdef PIN_GPS_EN
|
|
||||||
digitalWrite(PIN_GPS_EN, 1);
|
|
||||||
pinMode(PIN_GPS_EN, OUTPUT);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAS_PMU
|
#if defined(HAS_PMU) || defined(PIN_GPS_EN)
|
||||||
if (config.position.gps_enabled) {
|
if (config.position.gps_enabled) {
|
||||||
|
#ifdef PIN_GPS_EN
|
||||||
|
pinMode(PIN_GPS_EN, OUTPUT);
|
||||||
|
#endif
|
||||||
setGPSPower(true);
|
setGPSPower(true);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PIN_GPS_RESET
|
#ifdef PIN_GPS_RESET
|
||||||
digitalWrite(PIN_GPS_RESET, 1); // assert for 10ms
|
digitalWrite(PIN_GPS_RESET, GPS_RESET_MODE); // assert for 10ms
|
||||||
pinMode(PIN_GPS_RESET, OUTPUT);
|
pinMode(PIN_GPS_RESET, OUTPUT);
|
||||||
delay(10);
|
delay(10);
|
||||||
digitalWrite(PIN_GPS_RESET, 0);
|
digitalWrite(PIN_GPS_RESET, !GPS_RESET_MODE);
|
||||||
#endif
|
#endif
|
||||||
setAwake(true); // Wake GPS power before doing any init
|
setAwake(true); // Wake GPS power before doing any init
|
||||||
bool ok = setupGPS();
|
bool ok = setupGPS();
|
||||||
@@ -384,7 +686,7 @@ void GPS::setAwake(bool on)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get how long we should stay looking for each aquisition in msecs
|
/** Get how long we should stay looking for each acquisition in msecs
|
||||||
*/
|
*/
|
||||||
uint32_t GPS::getWakeTime() const
|
uint32_t GPS::getWakeTime() const
|
||||||
{
|
{
|
||||||
@@ -555,21 +857,17 @@ int GPS::prepareDeepSleep(void *unused)
|
|||||||
|
|
||||||
GnssModel_t GPS::probe()
|
GnssModel_t GPS::probe()
|
||||||
{
|
{
|
||||||
// return immediately if the model is set by the variant.h file
|
|
||||||
#ifdef GPS_UBLOX
|
|
||||||
return GNSS_MODEL_UBLOX;
|
|
||||||
#elif defined(GPS_L76K)
|
|
||||||
return GNSS_MODEL_MTK;
|
|
||||||
#else
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
memset(&info, 0, sizeof(struct uBloxGnssModelInfo));
|
memset(&info, 0, sizeof(struct uBloxGnssModelInfo));
|
||||||
|
// return immediately if the model is set by the variant.h file
|
||||||
|
//#ifdef GPS_UBLOX (unless it's a ublox, because we might want to know the module info!
|
||||||
|
// return GNSS_MODEL_UBLOX; think about removing this macro and return)
|
||||||
|
#if defined(GPS_L76K)
|
||||||
|
return GNSS_MODEL_MTK;
|
||||||
|
#elif defined(GPS_UC6580)
|
||||||
|
_serial_gps->updateBaudRate(115200);
|
||||||
|
return GNSS_MODEL_UC6850;
|
||||||
|
#else
|
||||||
|
uint8_t buffer[384] = {0};
|
||||||
|
|
||||||
// Close all NMEA sentences , Only valid for MTK platform
|
// Close all NMEA sentences , Only valid for MTK platform
|
||||||
_serial_gps->write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n");
|
_serial_gps->write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n");
|
||||||
@@ -597,31 +895,37 @@ GnssModel_t GPS::probe()
|
|||||||
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x0E, 0x30};
|
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x0E, 0x30};
|
||||||
_serial_gps->write(cfg_rate, sizeof(cfg_rate));
|
_serial_gps->write(cfg_rate, sizeof(cfg_rate));
|
||||||
// Check that the returned response class and message ID are correct
|
// Check that the returned response class and message ID are correct
|
||||||
if (!getAck(buffer, 256, 0x06, 0x08)) {
|
if (!getAck(buffer, 384, 0x06, 0x08)) {
|
||||||
LOG_WARN("Failed to find UBlox & MTK GNSS Module\n");
|
LOG_WARN("Failed to find UBlox & MTK GNSS Module\n");
|
||||||
return GNSS_MODEL_UNKONW;
|
return GNSS_MODEL_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
byte _message_MONVER[8] = {
|
||||||
|
0xB5, 0x62, // Sync message for UBX protocol
|
||||||
|
0x0A, 0x04, // Message class and ID (UBX-MON-VER)
|
||||||
|
0x00, 0x00, // Length of payload (we're asking for an answer, so no payload)
|
||||||
|
0x00, 0x00 // Checksum
|
||||||
|
};
|
||||||
// Get Ublox gnss module hardware and software info
|
// Get Ublox gnss module hardware and software info
|
||||||
uint8_t cfg_get_hw[] = {0xB5, 0x62, 0x0A, 0x04, 0x00, 0x00, 0x0E, 0x34};
|
UBXChecksum(_message_MONVER, sizeof(_message_MONVER));
|
||||||
_serial_gps->write(cfg_get_hw, sizeof(cfg_get_hw));
|
_serial_gps->write(_message_MONVER, sizeof(_message_MONVER));
|
||||||
|
|
||||||
uint16_t len = getAck(buffer, 256, 0x0A, 0x04);
|
uint16_t len = getAck(buffer, 384, 0x0A, 0x04);
|
||||||
if (len) {
|
if (len) {
|
||||||
|
// LOG_DEBUG("monver reply size = %d\n", len);
|
||||||
uint16_t position = 0;
|
uint16_t position = 0;
|
||||||
for (int i = 0; i < 30; i++) {
|
for (int i = 0; i < 30; i++) {
|
||||||
info.swVersion[i] = buffer[position];
|
info.swVersion[i] = buffer[position];
|
||||||
position++;
|
position++;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
info.hwVersion[i] = buffer[position];
|
info.hwVersion[i] = buffer[position - 1];
|
||||||
position++;
|
position++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (len >= position + 30) {
|
while (len >= position + 30) {
|
||||||
for (int i = 0; i < 30; i++) {
|
for (int i = 0; i < 30; i++) {
|
||||||
info.extension[info.extensionNo][i] = buffer[position];
|
info.extension[info.extensionNo][i] = buffer[position - 1];
|
||||||
position++;
|
position++;
|
||||||
}
|
}
|
||||||
info.extensionNo++;
|
info.extensionNo++;
|
||||||
@@ -631,6 +935,7 @@ GnssModel_t GPS::probe()
|
|||||||
|
|
||||||
LOG_DEBUG("Module Info : \n");
|
LOG_DEBUG("Module Info : \n");
|
||||||
LOG_DEBUG("Soft version: %s\n", info.swVersion);
|
LOG_DEBUG("Soft version: %s\n", info.swVersion);
|
||||||
|
LOG_DEBUG("first char is %c\n", (char)info.swVersion[0]);
|
||||||
LOG_DEBUG("Hard version: %s\n", info.hwVersion);
|
LOG_DEBUG("Hard version: %s\n", info.hwVersion);
|
||||||
LOG_DEBUG("Extensions:%d\n", info.extensionNo);
|
LOG_DEBUG("Extensions:%d\n", info.extensionNo);
|
||||||
for (int i = 0; i < info.extensionNo; i++) {
|
for (int i = 0; i < info.extensionNo; i++) {
|
||||||
@@ -641,19 +946,29 @@ GnssModel_t GPS::probe()
|
|||||||
|
|
||||||
// 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) {
|
for (int i = 0; i < info.extensionNo; ++i) {
|
||||||
if (!strncmp(info.extension[i], "OD=", 3)) {
|
if (!strncmp(info.extension[i], "MOD=", 4)) {
|
||||||
strncpy((char *)buffer, &(info.extension[i][3]), sizeof(buffer));
|
strncpy((char *)buffer, &(info.extension[i][4]), sizeof(buffer));
|
||||||
LOG_DEBUG("GetModel:%s\n", (char *)buffer);
|
// LOG_DEBUG("GetModel:%s\n", (char *)buffer);
|
||||||
|
if (strlen((char *)buffer)) {
|
||||||
|
LOG_INFO("UBlox GNSS init succeeded, using UBlox %s GNSS Module\n", (char *)buffer);
|
||||||
|
} else {
|
||||||
|
LOG_INFO("UBlox GNSS init succeeded, using UBlox GNSS Module\n");
|
||||||
|
}
|
||||||
|
} else if (!strncmp(info.extension[i], "PROTVER=", 8)) {
|
||||||
|
char *ptr = nullptr;
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
strncpy((char *)buffer, &(info.extension[i][8]), sizeof(buffer));
|
||||||
|
LOG_DEBUG("Protocol Version:%s\n", (char *)buffer);
|
||||||
|
if (strlen((char *)buffer)) {
|
||||||
|
uBloxProtocolVersion = strtoul((char *)buffer, &ptr, 10);
|
||||||
|
LOG_DEBUG("ProtVer=%d\n", uBloxProtocolVersion);
|
||||||
|
} else {
|
||||||
|
uBloxProtocolVersion = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
return GNSS_MODEL_UBLOX;
|
return GNSS_MODEL_UBLOX;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -675,8 +990,8 @@ GPS *createGps()
|
|||||||
LOG_DEBUG("Using MSL altitude model\n");
|
LOG_DEBUG("Using MSL altitude model\n");
|
||||||
#endif
|
#endif
|
||||||
if (GPS::_serial_gps) {
|
if (GPS::_serial_gps) {
|
||||||
// Some boards might have only the TX line from the GPS connected, in that case, we can't configure it at all. Just
|
// Some boards might have only the TX line from the GPS connected, in that case, we can't configure it at all.
|
||||||
// assume NMEA at 9600 baud.
|
// Just assume NMEA at 9600 baud.
|
||||||
GPS *new_gps = new NMEAGPS();
|
GPS *new_gps = new NMEAGPS();
|
||||||
new_gps->setup();
|
new_gps->setup();
|
||||||
return new_gps;
|
return new_gps;
|
||||||
@@ -688,4 +1003,4 @@ GPS *createGps()
|
|||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
+8
-3
@@ -14,7 +14,8 @@ struct uBloxGnssModelInfo {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
GNSS_MODEL_MTK,
|
GNSS_MODEL_MTK,
|
||||||
GNSS_MODEL_UBLOX,
|
GNSS_MODEL_UBLOX,
|
||||||
GNSS_MODEL_UNKONW,
|
GNSS_MODEL_UC6850,
|
||||||
|
GNSS_MODEL_UNKNOWN,
|
||||||
} GnssModel_t;
|
} GnssModel_t;
|
||||||
|
|
||||||
// Generate a string representation of DOP
|
// Generate a string representation of DOP
|
||||||
@@ -139,6 +140,9 @@ class GPS : private concurrency::OSThread
|
|||||||
/// always returns 0 to indicate okay to sleep
|
/// always returns 0 to indicate okay to sleep
|
||||||
int prepareDeepSleep(void *unused);
|
int prepareDeepSleep(void *unused);
|
||||||
|
|
||||||
|
// Calculate checksum
|
||||||
|
void UBXChecksum(byte *message, size_t length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switch the GPS into a mode where we are actively looking for a lock, or alternatively switch GPS into a low power mode
|
* Switch the GPS into a mode where we are actively looking for a lock, or alternatively switch GPS into a low power mode
|
||||||
*
|
*
|
||||||
@@ -164,6 +168,7 @@ class GPS : private concurrency::OSThread
|
|||||||
virtual int32_t runOnce() override;
|
virtual int32_t runOnce() override;
|
||||||
|
|
||||||
// Get GNSS model
|
// Get GNSS model
|
||||||
|
String getNMEA();
|
||||||
GnssModel_t probe();
|
GnssModel_t probe();
|
||||||
|
|
||||||
int getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID);
|
int getAck(uint8_t *buffer, uint16_t size, uint8_t requestedClass, uint8_t requestedID);
|
||||||
@@ -172,11 +177,11 @@ class GPS : private concurrency::OSThread
|
|||||||
uint8_t fixeddelayCtr = 0;
|
uint8_t fixeddelayCtr = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GnssModel_t gnssModel = GNSS_MODEL_UNKONW;
|
GnssModel_t gnssModel = GNSS_MODEL_UNKNOWN;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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.
|
// Returns the new instance or null if the GPS is not present.
|
||||||
GPS *createGps();
|
GPS *createGps();
|
||||||
|
|
||||||
extern GPS *gps;
|
extern GPS *gps;
|
||||||
@@ -12,7 +12,7 @@ GeoCoord::GeoCoord(int32_t lat, int32_t lon, int32_t alt) : _latitude(lat), _lon
|
|||||||
|
|
||||||
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
|
// Change decimial representation to int32_t. I.e., 12.345 becomes 123450000
|
||||||
_latitude = int32_t(lat * 1e+7);
|
_latitude = int32_t(lat * 1e+7);
|
||||||
_longitude = int32_t(lon * 1e+7);
|
_longitude = int32_t(lon * 1e+7);
|
||||||
GeoCoord::setCoords();
|
GeoCoord::setCoords();
|
||||||
@@ -20,7 +20,7 @@ GeoCoord::GeoCoord(float lat, float lon, int32_t alt) : _altitude(alt)
|
|||||||
|
|
||||||
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
|
// Change decimial representation to int32_t. I.e., 12.345 becomes 123450000
|
||||||
_latitude = int32_t(lat * 1e+7);
|
_latitude = int32_t(lat * 1e+7);
|
||||||
_longitude = int32_t(lon * 1e+7);
|
_longitude = int32_t(lon * 1e+7);
|
||||||
GeoCoord::setCoords();
|
GeoCoord::setCoords();
|
||||||
@@ -41,7 +41,7 @@ void GeoCoord::setCoords()
|
|||||||
|
|
||||||
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 marked dirty or new coordinates
|
||||||
if (_dirty || _latitude != lat || _longitude != lon || _altitude != alt) {
|
if (_dirty || _latitude != lat || _longitude != lon || _altitude != alt) {
|
||||||
_dirty = true;
|
_dirty = true;
|
||||||
_latitude = lat;
|
_latitude = lat;
|
||||||
@@ -55,7 +55,7 @@ void GeoCoord::updateCoords(const double lat, const double lon, const int32_t al
|
|||||||
{
|
{
|
||||||
int32_t iLat = lat * 1e+7;
|
int32_t iLat = lat * 1e+7;
|
||||||
int32_t iLon = lon * 1e+7;
|
int32_t iLon = lon * 1e+7;
|
||||||
// If marked dirty or new coordiantes
|
// If marked dirty or new coordinates
|
||||||
if (_dirty || _latitude != iLat || _longitude != iLon || _altitude != alt) {
|
if (_dirty || _latitude != iLat || _longitude != iLon || _altitude != alt) {
|
||||||
_dirty = true;
|
_dirty = true;
|
||||||
_latitude = iLat;
|
_latitude = iLat;
|
||||||
@@ -69,7 +69,7 @@ void GeoCoord::updateCoords(const float lat, const float lon, const int32_t alt)
|
|||||||
{
|
{
|
||||||
int32_t iLat = lat * 1e+7;
|
int32_t iLat = lat * 1e+7;
|
||||||
int32_t iLon = lon * 1e+7;
|
int32_t iLon = lon * 1e+7;
|
||||||
// If marked dirty or new coordiantes
|
// If marked dirty or new coordinates
|
||||||
if (_dirty || _latitude != iLat || _longitude != iLon || _altitude != alt) {
|
if (_dirty || _latitude != iLat || _longitude != iLon || _altitude != alt) {
|
||||||
_dirty = true;
|
_dirty = true;
|
||||||
_latitude = iLat;
|
_latitude = iLat;
|
||||||
@@ -217,7 +217,7 @@ void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr)
|
|||||||
double eta2 = v / rho - 1;
|
double eta2 = v / rho - 1;
|
||||||
double mA = (1 + n + (5 / 4) * n * n + (5 / 4) * n * n * n) * (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);
|
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
|
// loss of precision in mC & mD due to floating point rounding can cause inaccuracy 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 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 mD = (35 / 24) * n * n * n * sin(3 * (phi - phi0)) * cos(3 * (phi + phi0));
|
||||||
double m = b * f0 * (mA - mB + mC - mD);
|
double m = b * f0 * (mA - mB + mC - mD);
|
||||||
|
|||||||
+1
-1
@@ -65,7 +65,7 @@ struct MGRS {
|
|||||||
uint32_t northing;
|
uint32_t northing;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A struct to hold the data for a OSGR coordiante
|
// A struct to hold the data for a OSGR coordinate
|
||||||
struct OSGR {
|
struct OSGR {
|
||||||
char e100k;
|
char e100k;
|
||||||
char n100k;
|
char n100k;
|
||||||
|
|||||||
+1
-1
@@ -19,7 +19,7 @@ static uint64_t zeroOffsetSecs; // GPS based time in secs since 1970 - only upda
|
|||||||
|
|
||||||
void readFromRTC()
|
void readFromRTC()
|
||||||
{
|
{
|
||||||
struct timeval tv; /* btw settimeofday() is helpfull here too*/
|
struct timeval tv; /* btw settimeofday() is helpful here too*/
|
||||||
#ifdef RV3028_RTC
|
#ifdef RV3028_RTC
|
||||||
if (rtc_found.address == RV3028_RTC) {
|
if (rtc_found.address == RV3028_RTC) {
|
||||||
uint32_t now = millis();
|
uint32_t now = millis();
|
||||||
|
|||||||
@@ -7,6 +7,10 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
|
|
||||||
|
// #ifdef HELTEC_WIRELESS_PAPER
|
||||||
|
// SPIClass *hspi = NULL;
|
||||||
|
// #endif
|
||||||
|
|
||||||
#define COLORED GxEPD_BLACK
|
#define COLORED GxEPD_BLACK
|
||||||
#define UNCOLORED GxEPD_WHITE
|
#define UNCOLORED GxEPD_WHITE
|
||||||
|
|
||||||
@@ -19,13 +23,13 @@
|
|||||||
#define TECHO_DISPLAY_MODEL GxEPD2_213_BN
|
#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
|
// #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
|
// #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
|
// #define TECHO_DISPLAY_MODEL GxEPD2_154_M09
|
||||||
|
|
||||||
#elif defined(MAKERPYTHON)
|
#elif defined(MAKERPYTHON)
|
||||||
// 2.9 inch 296x128 - GxEPD2_290_T5D
|
// 2.9 inch 296x128 - GxEPD2_290_T5D
|
||||||
@@ -41,6 +45,9 @@
|
|||||||
// 1.54 inch 200x200 - GxEPD2_154_M09
|
// 1.54 inch 200x200 - GxEPD2_154_M09
|
||||||
#define TECHO_DISPLAY_MODEL GxEPD2_154_M09
|
#define TECHO_DISPLAY_MODEL GxEPD2_154_M09
|
||||||
|
|
||||||
|
#elif defined(HELTEC_WIRELESS_PAPER)
|
||||||
|
//#define TECHO_DISPLAY_MODEL GxEPD2_213_T5D
|
||||||
|
#define TECHO_DISPLAY_MODEL GxEPD2_213_BN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT> *adafruitDisplay;
|
GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT> *adafruitDisplay;
|
||||||
@@ -62,6 +69,10 @@ EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY
|
|||||||
|
|
||||||
// GxEPD2_154_M09
|
// GxEPD2_154_M09
|
||||||
// setGeometry(GEOMETRY_RAWMODE, 200, 200);
|
// setGeometry(GEOMETRY_RAWMODE, 200, 200);
|
||||||
|
|
||||||
|
#elif defined(HELTEC_WIRELESS_PAPER)
|
||||||
|
// setGeometry(GEOMETRY_RAWMODE, 212, 104);
|
||||||
|
setGeometry(GEOMETRY_RAWMODE, 250, 122);
|
||||||
#elif defined(MAKERPYTHON)
|
#elif defined(MAKERPYTHON)
|
||||||
// GxEPD2_290_T5D
|
// GxEPD2_290_T5D
|
||||||
setGeometry(GEOMETRY_RAWMODE, 296, 128);
|
setGeometry(GEOMETRY_RAWMODE, 296, 128);
|
||||||
@@ -109,7 +120,7 @@ bool EInkDisplay::forceDisplay(uint32_t msecLimit)
|
|||||||
for (uint32_t y = 0; y < displayHeight; y++) {
|
for (uint32_t y = 0; y < displayHeight; y++) {
|
||||||
for (uint32_t x = 0; x < displayWidth; x++) {
|
for (uint32_t x = 0; x < displayWidth; x++) {
|
||||||
|
|
||||||
// get src pixel in the page based ordering the OLED lib uses FIXME, super inefficent
|
// get src pixel in the page based ordering the OLED lib uses FIXME, super inefficient
|
||||||
auto b = buffer[x + (y / 8) * displayWidth];
|
auto b = buffer[x + (y / 8) * displayWidth];
|
||||||
auto isset = b & (1 << (y & 7));
|
auto isset = b & (1 << (y & 7));
|
||||||
adafruitDisplay->drawPixel(x, y, isset ? COLORED : UNCOLORED);
|
adafruitDisplay->drawPixel(x, y, isset ? COLORED : UNCOLORED);
|
||||||
@@ -218,6 +229,16 @@ bool EInkDisplay::connect()
|
|||||||
(void)adafruitDisplay;
|
(void)adafruitDisplay;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif defined(HELTEC_WIRELESS_PAPER)
|
||||||
|
{
|
||||||
|
auto lowLevel = new TECHO_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY);
|
||||||
|
adafruitDisplay = new GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT>(*lowLevel);
|
||||||
|
// hspi = new SPIClass(HSPI);
|
||||||
|
// hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS); // SCLK, MISO, MOSI, SS
|
||||||
|
adafruitDisplay->init(115200, true, 10, false, SPI, SPISettings(6000000, MSBFIRST, SPI_MODE0));
|
||||||
|
adafruitDisplay->setRotation(3);
|
||||||
|
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||||
|
}
|
||||||
#elif defined(PCA10059)
|
#elif defined(PCA10059)
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
#ifdef RAK4630
|
#ifdef HAS_NCP5623
|
||||||
#include <NCP5623.h>
|
#include <NCP5623.h>
|
||||||
extern NCP5623 rgb;
|
extern NCP5623 rgb;
|
||||||
|
|
||||||
|
|||||||
+73
-14
@@ -31,6 +31,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include "gps/GeoCoord.h"
|
#include "gps/GeoCoord.h"
|
||||||
#include "gps/RTC.h"
|
#include "gps/RTC.h"
|
||||||
#include "graphics/images.h"
|
#include "graphics/images.h"
|
||||||
|
#include "input/TouchScreenImpl1.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "mesh-pb-constants.h"
|
#include "mesh-pb-constants.h"
|
||||||
#include "mesh/Channels.h"
|
#include "mesh/Channels.h"
|
||||||
@@ -102,7 +103,7 @@ static uint16_t displayWidth, displayHeight;
|
|||||||
#define SCREEN_WIDTH displayWidth
|
#define SCREEN_WIDTH displayWidth
|
||||||
#define SCREEN_HEIGHT displayHeight
|
#define SCREEN_HEIGHT displayHeight
|
||||||
|
|
||||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(USE_ST7789)
|
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)
|
||||||
// The screen is bigger so use bigger fonts
|
// The screen is bigger so use bigger fonts
|
||||||
#define FONT_SMALL ArialMT_Plain_16 // Height: 19
|
#define FONT_SMALL ArialMT_Plain_16 // Height: 19
|
||||||
#define FONT_MEDIUM ArialMT_Plain_24 // Height: 28
|
#define FONT_MEDIUM ArialMT_Plain_24 // Height: 28
|
||||||
@@ -296,7 +297,7 @@ static void drawModuleFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int
|
|||||||
static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
{
|
{
|
||||||
int x_offset = display->width() / 2;
|
int x_offset = display->width() / 2;
|
||||||
int y_offset = display->height() == 64 ? 0 : 32;
|
int y_offset = display->height() <= 80 ? 0 : 32;
|
||||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||||
display->setFont(FONT_MEDIUM);
|
display->setFont(FONT_MEDIUM);
|
||||||
display->drawString(x_offset + x, y_offset + y, "Bluetooth");
|
display->drawString(x_offset + x, y_offset + y, "Bluetooth");
|
||||||
@@ -320,18 +321,18 @@ static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state,
|
|||||||
|
|
||||||
static void drawFrameShutdown(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
static void drawFrameShutdown(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
{
|
{
|
||||||
|
uint16_t x_offset = display->width() / 2;
|
||||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||||
|
|
||||||
display->setFont(FONT_MEDIUM);
|
display->setFont(FONT_MEDIUM);
|
||||||
display->drawString(64 + x, 26 + y, "Shutting down...");
|
display->drawString(x_offset + x, 26 + y, "Shutting down...");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drawFrameReboot(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
static void drawFrameReboot(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
{
|
{
|
||||||
|
uint16_t x_offset = display->width() / 2;
|
||||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||||
|
|
||||||
display->setFont(FONT_MEDIUM);
|
display->setFont(FONT_MEDIUM);
|
||||||
display->drawString(64 + x, 26 + y, "Rebooting...");
|
display->drawString(x_offset + x, 26 + y, "Rebooting...");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drawFrameFirmware(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
static void drawFrameFirmware(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
@@ -360,7 +361,7 @@ static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *sta
|
|||||||
display->drawString(0 + x, FONT_HEIGHT_MEDIUM + y, "For help, please visit \nmeshtastic.org");
|
display->drawString(0 + x, FONT_HEIGHT_MEDIUM + y, "For help, please visit \nmeshtastic.org");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore messages orginating from phone (from the current node 0x0) unless range test or store and forward module are enabled
|
// Ignore messages originating from phone (from the current node 0x0) unless range test or store and forward module are enabled
|
||||||
static bool shouldDrawMessage(const meshtastic_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;
|
||||||
@@ -442,7 +443,7 @@ static void drawWaypointFrame(OLEDDisplay *display, OLEDDisplayUiState *state, i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a series of fields in a column, wrapping to multiple colums if needed
|
/// Draw a series of fields in a column, wrapping to multiple columns if needed
|
||||||
static void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char **fields)
|
static void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char **fields)
|
||||||
{
|
{
|
||||||
// The coordinates define the left starting point of the text
|
// The coordinates define the left starting point of the text
|
||||||
@@ -492,7 +493,7 @@ static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, NodeStatus *no
|
|||||||
{
|
{
|
||||||
char usersString[20];
|
char usersString[20];
|
||||||
snprintf(usersString, sizeof(usersString), "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
|
snprintf(usersString, sizeof(usersString), "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
|
||||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(USE_ST7789)
|
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)
|
||||||
display->drawFastImage(x, y + 3, 8, 8, imgUser);
|
display->drawFastImage(x, y + 3, 8, 8, imgUser);
|
||||||
#else
|
#else
|
||||||
display->drawFastImage(x, y, 8, 8, imgUser);
|
display->drawFastImage(x, y, 8, 8, imgUser);
|
||||||
@@ -835,7 +836,11 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char distStr[20];
|
static char distStr[20];
|
||||||
strncpy(distStr, "? km", sizeof(distStr)); // might not have location data
|
if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) {
|
||||||
|
strncpy(distStr, "? mi", sizeof(distStr)); // might not have location data
|
||||||
|
} else {
|
||||||
|
strncpy(distStr, "? km", sizeof(distStr));
|
||||||
|
}
|
||||||
meshtastic_NodeInfoLite *ourNode = nodeDB.getMeshNode(nodeDB.getNodeNum());
|
meshtastic_NodeInfoLite *ourNode = nodeDB.getMeshNode(nodeDB.getNodeNum());
|
||||||
const char *fields[] = {username, distStr, signalStr, lastStr, NULL};
|
const char *fields[] = {username, distStr, signalStr, lastStr, NULL};
|
||||||
int16_t compassX = 0, compassY = 0;
|
int16_t compassX = 0, compassY = 0;
|
||||||
@@ -944,6 +949,9 @@ void Screen::handleSetOn(bool on)
|
|||||||
if (on != screenOn) {
|
if (on != screenOn) {
|
||||||
if (on) {
|
if (on) {
|
||||||
LOG_INFO("Turning on screen\n");
|
LOG_INFO("Turning on screen\n");
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
PMU->enablePowerOutput(XPOWERS_ALDO2);
|
||||||
|
#endif
|
||||||
dispdev.displayOn();
|
dispdev.displayOn();
|
||||||
dispdev.displayOn();
|
dispdev.displayOn();
|
||||||
enabled = true;
|
enabled = true;
|
||||||
@@ -952,6 +960,9 @@ void Screen::handleSetOn(bool on)
|
|||||||
} else {
|
} else {
|
||||||
LOG_INFO("Turning off screen\n");
|
LOG_INFO("Turning off screen\n");
|
||||||
dispdev.displayOff();
|
dispdev.displayOff();
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
PMU->disablePowerOutput(XPOWERS_ALDO2);
|
||||||
|
#endif
|
||||||
enabled = false;
|
enabled = false;
|
||||||
}
|
}
|
||||||
screenOn = on;
|
screenOn = on;
|
||||||
@@ -1034,12 +1045,18 @@ void Screen::setup()
|
|||||||
#endif
|
#endif
|
||||||
serialSinceMsec = millis();
|
serialSinceMsec = millis();
|
||||||
|
|
||||||
|
#if HAS_TOUCHSCREEN
|
||||||
|
touchScreenImpl1 = new TouchScreenImpl1(dispdev.getWidth(), dispdev.getHeight(), dispdev.getTouch);
|
||||||
|
touchScreenImpl1->init();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Subscribe to status updates
|
// Subscribe to status updates
|
||||||
powerStatusObserver.observe(&powerStatus->onNewStatus);
|
powerStatusObserver.observe(&powerStatus->onNewStatus);
|
||||||
gpsStatusObserver.observe(&gpsStatus->onNewStatus);
|
gpsStatusObserver.observe(&gpsStatus->onNewStatus);
|
||||||
nodeStatusObserver.observe(&nodeStatus->onNewStatus);
|
nodeStatusObserver.observe(&nodeStatus->onNewStatus);
|
||||||
if (textMessageModule)
|
if (textMessageModule)
|
||||||
textMessageObserver.observe(textMessageModule);
|
textMessageObserver.observe(textMessageModule);
|
||||||
|
inputObserver.observe(inputBroker);
|
||||||
|
|
||||||
// Modules can notify screen about refresh
|
// Modules can notify screen about refresh
|
||||||
MeshModule::observeUIEvents(&uiFrameEventObserver);
|
MeshModule::observeUIEvents(&uiFrameEventObserver);
|
||||||
@@ -1117,6 +1134,12 @@ int32_t Screen::runOnce()
|
|||||||
handleOnPress();
|
handleOnPress();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case Cmd::SHOW_PREV_FRAME:
|
||||||
|
handleShowPrevFrame();
|
||||||
|
break;
|
||||||
|
case Cmd::SHOW_NEXT_FRAME:
|
||||||
|
handleShowNextFrame();
|
||||||
|
break;
|
||||||
case Cmd::START_BLUETOOTH_PIN_SCREEN:
|
case Cmd::START_BLUETOOTH_PIN_SCREEN:
|
||||||
handleStartBluetoothPinScreen(cmd.bluetooth_pin);
|
handleStartBluetoothPinScreen(cmd.bluetooth_pin);
|
||||||
break;
|
break;
|
||||||
@@ -1410,6 +1433,28 @@ void Screen::handleOnPress()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Screen::handleShowPrevFrame()
|
||||||
|
{
|
||||||
|
// If screen was off, just wake it, otherwise go back to previous frame
|
||||||
|
// If we are in a transition, the press must have bounced, drop it.
|
||||||
|
if (ui.getUiState()->frameState == FIXED) {
|
||||||
|
ui.previousFrame();
|
||||||
|
lastScreenTransition = millis();
|
||||||
|
setFastFramerate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Screen::handleShowNextFrame()
|
||||||
|
{
|
||||||
|
// If screen was off, just wake it, otherwise advance to next frame
|
||||||
|
// If we are in a transition, the press must have bounced, drop it.
|
||||||
|
if (ui.getUiState()->frameState == FIXED) {
|
||||||
|
ui.nextFrame();
|
||||||
|
lastScreenTransition = millis();
|
||||||
|
setFastFramerate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef SCREEN_TRANSITION_FRAMERATE
|
#ifndef SCREEN_TRANSITION_FRAMERATE
|
||||||
#define SCREEN_TRANSITION_FRAMERATE 30 // fps
|
#define SCREEN_TRANSITION_FRAMERATE 30 // fps
|
||||||
#endif
|
#endif
|
||||||
@@ -1482,7 +1527,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
|||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
if (millis() - storeForwardModule->lastHeartbeat >
|
if (millis() - storeForwardModule->lastHeartbeat >
|
||||||
(storeForwardModule->heartbeatInterval * 1200)) { // no heartbeat, overlap a bit
|
(storeForwardModule->heartbeatInterval * 1200)) { // no heartbeat, overlap a bit
|
||||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(USE_ST7789)
|
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)
|
||||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
||||||
imgQuestionL1);
|
imgQuestionL1);
|
||||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 12, 8,
|
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 12, 8,
|
||||||
@@ -1492,7 +1537,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
|||||||
imgQuestion);
|
imgQuestion);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(USE_ST7789)
|
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)
|
||||||
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 16, 8,
|
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 16, 8,
|
||||||
imgSFL1);
|
imgSFL1);
|
||||||
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 16, 8,
|
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 16, 8,
|
||||||
@@ -1504,7 +1549,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(USE_ST7789)
|
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)
|
||||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
||||||
imgInfoL1);
|
imgInfoL1);
|
||||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 12, 8,
|
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 11 + FONT_HEIGHT_SMALL, 12, 8,
|
||||||
@@ -1789,7 +1834,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
heartbeat = !heartbeat;
|
heartbeat = !heartbeat;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// adjust Brightness cycle trough 1 to 254 as long as attachDuringLongPress is true
|
// adjust Brightness cycle through 1 to 254 as long as attachDuringLongPress is true
|
||||||
void Screen::adjustBrightness()
|
void Screen::adjustBrightness()
|
||||||
{
|
{
|
||||||
if (!useDisplay)
|
if (!useDisplay)
|
||||||
@@ -1847,6 +1892,20 @@ int Screen::handleUIFrameEvent(const UIFrameEvent *event)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Screen::handleInputEvent(const InputEvent *event)
|
||||||
|
{
|
||||||
|
if (showingNormalScreen && moduleFrames.size() == 0) {
|
||||||
|
LOG_DEBUG("Screen::handleInputEvent from %s\n", event->source);
|
||||||
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
||||||
|
showPrevFrame();
|
||||||
|
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
|
||||||
|
showNextFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace graphics
|
} // namespace graphics
|
||||||
#else
|
#else
|
||||||
graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {}
|
graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {}
|
||||||
|
|||||||
+12
-3
@@ -53,6 +53,7 @@ class Screen
|
|||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include "concurrency/LockGuard.h"
|
#include "concurrency/LockGuard.h"
|
||||||
#include "concurrency/OSThread.h"
|
#include "concurrency/OSThread.h"
|
||||||
|
#include "input/InputBroker.h"
|
||||||
#include "mesh/MeshModule.h"
|
#include "mesh/MeshModule.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -118,6 +119,8 @@ class Screen : public concurrency::OSThread
|
|||||||
CallbackObserver<Screen, const meshtastic_MeshPacket *>(this, &Screen::handleTextMessage);
|
CallbackObserver<Screen, const meshtastic_MeshPacket *>(this, &Screen::handleTextMessage);
|
||||||
CallbackObserver<Screen, const UIFrameEvent *> uiFrameEventObserver =
|
CallbackObserver<Screen, const UIFrameEvent *> uiFrameEventObserver =
|
||||||
CallbackObserver<Screen, const UIFrameEvent *>(this, &Screen::handleUIFrameEvent);
|
CallbackObserver<Screen, const UIFrameEvent *>(this, &Screen::handleUIFrameEvent);
|
||||||
|
CallbackObserver<Screen, const InputEvent *> inputObserver =
|
||||||
|
CallbackObserver<Screen, const InputEvent *>(this, &Screen::handleInputEvent);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY);
|
explicit Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY);
|
||||||
@@ -152,8 +155,10 @@ class Screen : public concurrency::OSThread
|
|||||||
|
|
||||||
void blink();
|
void blink();
|
||||||
|
|
||||||
/// Handles a button press.
|
/// Handle button press, trackball or swipe action)
|
||||||
void onPress() { enqueueCmd(ScreenCmd{.cmd = Cmd::ON_PRESS}); }
|
void onPress() { enqueueCmd(ScreenCmd{.cmd = Cmd::ON_PRESS}); }
|
||||||
|
void showPrevFrame() { enqueueCmd(ScreenCmd{.cmd = Cmd::SHOW_PREV_FRAME}); }
|
||||||
|
void showNextFrame() { enqueueCmd(ScreenCmd{.cmd = Cmd::SHOW_NEXT_FRAME}); }
|
||||||
|
|
||||||
// Implementation to Adjust Brightness
|
// Implementation to Adjust Brightness
|
||||||
void adjustBrightness();
|
void adjustBrightness();
|
||||||
@@ -301,9 +306,11 @@ class Screen : public concurrency::OSThread
|
|||||||
// Use this handle to set things like battery status, user count, GPS status, etc.
|
// Use this handle to set things like battery status, user count, GPS status, etc.
|
||||||
DebugInfo *debug_info() { return &debugInfo; }
|
DebugInfo *debug_info() { return &debugInfo; }
|
||||||
|
|
||||||
|
// Handle observer events
|
||||||
int handleStatusUpdate(const meshtastic::Status *arg);
|
int handleStatusUpdate(const meshtastic::Status *arg);
|
||||||
int handleTextMessage(const meshtastic_MeshPacket *arg);
|
int handleTextMessage(const meshtastic_MeshPacket *arg);
|
||||||
int handleUIFrameEvent(const UIFrameEvent *arg);
|
int handleUIFrameEvent(const UIFrameEvent *arg);
|
||||||
|
int handleInputEvent(const InputEvent *arg);
|
||||||
|
|
||||||
/// Used to force (super slow) eink displays to draw critical frames
|
/// Used to force (super slow) eink displays to draw critical frames
|
||||||
void forceDisplay();
|
void forceDisplay();
|
||||||
@@ -343,6 +350,8 @@ class Screen : public concurrency::OSThread
|
|||||||
// Implementations of various commands, called from doTask().
|
// Implementations of various commands, called from doTask().
|
||||||
void handleSetOn(bool on);
|
void handleSetOn(bool on);
|
||||||
void handleOnPress();
|
void handleOnPress();
|
||||||
|
void handleShowNextFrame();
|
||||||
|
void handleShowPrevFrame();
|
||||||
void handleStartBluetoothPinScreen(uint32_t pin);
|
void handleStartBluetoothPinScreen(uint32_t pin);
|
||||||
void handlePrint(const char *text);
|
void handlePrint(const char *text);
|
||||||
void handleStartFirmwareUpdateScreen();
|
void handleStartFirmwareUpdateScreen();
|
||||||
@@ -380,7 +389,7 @@ class Screen : public concurrency::OSThread
|
|||||||
SH1106Wire dispdev;
|
SH1106Wire dispdev;
|
||||||
#elif defined(USE_SSD1306)
|
#elif defined(USE_SSD1306)
|
||||||
SSD1306Wire dispdev;
|
SSD1306Wire dispdev;
|
||||||
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(USE_ST7789)
|
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ST7789_CS)
|
||||||
TFTDisplay dispdev;
|
TFTDisplay dispdev;
|
||||||
#elif defined(USE_EINK)
|
#elif defined(USE_EINK)
|
||||||
EInkDisplay dispdev;
|
EInkDisplay dispdev;
|
||||||
@@ -394,4 +403,4 @@ class Screen : public concurrency::OSThread
|
|||||||
};
|
};
|
||||||
|
|
||||||
} // namespace graphics
|
} // namespace graphics
|
||||||
#endif
|
#endif
|
||||||
+281
-16
@@ -1,12 +1,233 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
#if defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(USE_ST7789)
|
#ifndef TFT_BACKLIGHT_ON
|
||||||
|
#define TFT_BACKLIGHT_ON HIGH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// convert 24-bit color to 16-bit (56K)
|
||||||
|
#define COLOR565(r, g, b) (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3))
|
||||||
|
#define TFT_MESH COLOR565(0x67, 0xEA, 0x94)
|
||||||
|
|
||||||
|
#if defined(ST7735S)
|
||||||
|
#include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip
|
||||||
|
|
||||||
|
#if defined(ST7735_BACKLIGHT_EN) && !defined(TFT_BL)
|
||||||
|
#define TFT_BL ST7735_BACKLIGHT_EN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class LGFX : public lgfx::LGFX_Device
|
||||||
|
{
|
||||||
|
lgfx::Panel_ST7735S _panel_instance;
|
||||||
|
lgfx::Bus_SPI _bus_instance;
|
||||||
|
lgfx::Light_PWM _light_instance;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LGFX(void)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
auto cfg = _bus_instance.config();
|
||||||
|
|
||||||
|
// configure SPI
|
||||||
|
cfg.spi_host = ST7735_SPI_HOST; // ESP32-S2,S3,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
|
||||||
|
cfg.spi_mode = 0;
|
||||||
|
cfg.freq_write = SPI_FREQUENCY; // SPI clock for transmission (up to 80MHz, rounded to the value obtained by dividing
|
||||||
|
// 80MHz by an integer)
|
||||||
|
cfg.freq_read = SPI_READ_FREQUENCY; // SPI clock when receiving
|
||||||
|
cfg.spi_3wire = false; // Set to true if reception is done on the MOSI pin
|
||||||
|
cfg.use_lock = true; // Set to true to use transaction locking
|
||||||
|
cfg.dma_channel = SPI_DMA_CH_AUTO; // SPI_DMA_CH_AUTO; // Set DMA channel to use (0=not use DMA / 1=1ch / 2=ch /
|
||||||
|
// SPI_DMA_CH_AUTO=auto setting)
|
||||||
|
cfg.pin_sclk = ST7735_SCK; // Set SPI SCLK pin number
|
||||||
|
cfg.pin_mosi = ST7735_SDA; // Set SPI MOSI pin number
|
||||||
|
cfg.pin_miso = ST7735_MISO; // Set SPI MISO pin number (-1 = disable)
|
||||||
|
cfg.pin_dc = ST7735_RS; // Set SPI DC pin number (-1 = disable)
|
||||||
|
|
||||||
|
_bus_instance.config(cfg); // applies the set value to the bus.
|
||||||
|
_panel_instance.setBus(&_bus_instance); // set the bus on the panel.
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Set the display panel control.
|
||||||
|
auto cfg = _panel_instance.config(); // Gets a structure for display panel settings.
|
||||||
|
|
||||||
|
cfg.pin_cs = ST7735_CS; // Pin number where CS is connected (-1 = disable)
|
||||||
|
cfg.pin_rst = ST7735_RESET; // Pin number where RST is connected (-1 = disable)
|
||||||
|
cfg.pin_busy = ST7735_BUSY; // Pin number where BUSY is connected (-1 = disable)
|
||||||
|
|
||||||
|
// The following setting values are general initial values for each panel, so please comment out any
|
||||||
|
// unknown items and try them.
|
||||||
|
|
||||||
|
cfg.panel_width = TFT_WIDTH; // actual displayable width
|
||||||
|
cfg.panel_height = TFT_HEIGHT; // actual displayable height
|
||||||
|
cfg.offset_x = TFT_OFFSET_X; // Panel offset amount in X direction
|
||||||
|
cfg.offset_y = TFT_OFFSET_Y; // Panel offset amount in Y direction
|
||||||
|
cfg.offset_rotation = 0; // Rotation direction value offset 0~7 (4~7 is upside down)
|
||||||
|
cfg.dummy_read_pixel = 8; // Number of bits for dummy read before pixel readout
|
||||||
|
cfg.dummy_read_bits = 1; // Number of bits for dummy read before non-pixel data read
|
||||||
|
cfg.readable = true; // Set to true if data can be read
|
||||||
|
cfg.invert = true; // Set to true if the light/darkness of the panel is reversed
|
||||||
|
cfg.rgb_order = false; // Set to true if the panel's red and blue are swapped
|
||||||
|
cfg.dlen_16bit =
|
||||||
|
false; // Set to true for panels that transmit data length in 16-bit units with 16-bit parallel or SPI
|
||||||
|
cfg.bus_shared = true; // If the bus is shared with the SD card, set to true (bus control with drawJpgFile etc.)
|
||||||
|
|
||||||
|
// Set the following only when the display is shifted with a driver with a variable number of pixels, such as the
|
||||||
|
// ST7735 or ILI9163.
|
||||||
|
cfg.memory_width = TFT_WIDTH; // Maximum width supported by the driver IC
|
||||||
|
cfg.memory_height = TFT_HEIGHT; // Maximum height supported by the driver IC
|
||||||
|
_panel_instance.config(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the backlight control
|
||||||
|
{
|
||||||
|
auto cfg = _light_instance.config(); // Gets a structure for backlight settings.
|
||||||
|
|
||||||
|
cfg.pin_bl = ST7735_BL; // Pin number to which the backlight is connected
|
||||||
|
cfg.invert = true; // true to invert the brightness of the backlight
|
||||||
|
// cfg.freq = 44100; // PWM frequency of backlight
|
||||||
|
// cfg.pwm_channel = 1; // PWM channel number to use
|
||||||
|
|
||||||
|
_light_instance.config(cfg);
|
||||||
|
_panel_instance.setLight(&_light_instance); // Set the backlight on the panel.
|
||||||
|
}
|
||||||
|
|
||||||
|
setPanel(&_panel_instance);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static LGFX tft;
|
||||||
|
|
||||||
|
#elif defined(ST7789_CS)
|
||||||
|
#include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip
|
||||||
|
|
||||||
|
#if defined(ST7789_BACKLIGHT_EN) && !defined(TFT_BL)
|
||||||
|
#define TFT_BL ST7789_BACKLIGHT_EN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class LGFX : public lgfx::LGFX_Device
|
||||||
|
{
|
||||||
|
lgfx::Panel_ST7789 _panel_instance;
|
||||||
|
lgfx::Bus_SPI _bus_instance;
|
||||||
|
lgfx::Light_PWM _light_instance;
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
lgfx::Touch_FT5x06 _touch_instance;
|
||||||
|
#else
|
||||||
|
lgfx::Touch_GT911 _touch_instance;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
LGFX(void)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
auto cfg = _bus_instance.config();
|
||||||
|
|
||||||
|
// SPI
|
||||||
|
cfg.spi_host = ST7789_SPI_HOST;
|
||||||
|
cfg.spi_mode = 0;
|
||||||
|
cfg.freq_write = SPI_FREQUENCY; // SPI clock for transmission (up to 80MHz, rounded to the value obtained by dividing
|
||||||
|
// 80MHz by an integer)
|
||||||
|
cfg.freq_read = SPI_READ_FREQUENCY; // SPI clock when receiving
|
||||||
|
cfg.spi_3wire = false; // Set to true if reception is done on the MOSI pin
|
||||||
|
cfg.use_lock = true; // Set to true to use transaction locking
|
||||||
|
cfg.dma_channel = SPI_DMA_CH_AUTO; // SPI_DMA_CH_AUTO; // Set DMA channel to use (0=not use DMA / 1=1ch / 2=ch /
|
||||||
|
cfg.pin_sclk = ST7789_SCK; // Set SPI SCLK pin number
|
||||||
|
cfg.pin_mosi = ST7789_SDA; // Set SPI MOSI pin number
|
||||||
|
cfg.pin_miso = ST7789_MISO; // Set SPI MISO pin number (-1 = disable)
|
||||||
|
cfg.pin_dc = ST7789_RS; // Set SPI DC pin number (-1 = disable)
|
||||||
|
|
||||||
|
_bus_instance.config(cfg); // applies the set value to the bus.
|
||||||
|
_panel_instance.setBus(&_bus_instance); // set the bus on the panel.
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Set the display panel control.
|
||||||
|
auto cfg = _panel_instance.config(); // Gets a structure for display panel settings.
|
||||||
|
|
||||||
|
cfg.pin_cs = ST7789_CS; // Pin number where CS is connected (-1 = disable)
|
||||||
|
cfg.pin_rst = -1; // Pin number where RST is connected (-1 = disable)
|
||||||
|
cfg.pin_busy = -1; // Pin number where BUSY is connected (-1 = disable)
|
||||||
|
|
||||||
|
// The following setting values are general initial values for each panel, so please comment out any
|
||||||
|
// unknown items and try them.
|
||||||
|
|
||||||
|
cfg.panel_width = TFT_WIDTH; // actual displayable width
|
||||||
|
cfg.panel_height = TFT_HEIGHT; // actual displayable height
|
||||||
|
cfg.offset_x = TFT_OFFSET_X; // Panel offset amount in X direction
|
||||||
|
cfg.offset_y = TFT_OFFSET_Y; // Panel offset amount in Y direction
|
||||||
|
cfg.offset_rotation = 0; // Rotation direction value offset 0~7 (4~7 is mirrored)
|
||||||
|
cfg.dummy_read_pixel = 9; // Number of bits for dummy read before pixel readout
|
||||||
|
cfg.dummy_read_bits = 1; // Number of bits for dummy read before non-pixel data read
|
||||||
|
cfg.readable = true; // Set to true if data can be read
|
||||||
|
cfg.invert = true; // Set to true if the light/darkness of the panel is reversed
|
||||||
|
cfg.rgb_order = false; // Set to true if the panel's red and blue are swapped
|
||||||
|
cfg.dlen_16bit =
|
||||||
|
false; // Set to true for panels that transmit data length in 16-bit units with 16-bit parallel or SPI
|
||||||
|
cfg.bus_shared = true; // If the bus is shared with the SD card, set to true (bus control with drawJpgFile etc.)
|
||||||
|
|
||||||
|
// Set the following only when the display is shifted with a driver with a variable number of pixels, such as the
|
||||||
|
// ST7735 or ILI9163.
|
||||||
|
// cfg.memory_width = TFT_WIDTH; // Maximum width supported by the driver IC
|
||||||
|
// cfg.memory_height = TFT_HEIGHT; // Maximum height supported by the driver IC
|
||||||
|
_panel_instance.config(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the backlight control. (delete if not necessary)
|
||||||
|
{
|
||||||
|
auto cfg = _light_instance.config(); // Gets a structure for backlight settings.
|
||||||
|
|
||||||
|
cfg.pin_bl = ST7789_BL; // Pin number to which the backlight is connected
|
||||||
|
cfg.invert = false; // true to invert the brightness of the backlight
|
||||||
|
// cfg.pwm_channel = 0;
|
||||||
|
|
||||||
|
_light_instance.config(cfg);
|
||||||
|
_panel_instance.setLight(&_light_instance); // Set the backlight on the panel.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure settings for touch screen control.
|
||||||
|
{
|
||||||
|
auto cfg = _touch_instance.config();
|
||||||
|
|
||||||
|
cfg.pin_cs = -1;
|
||||||
|
cfg.x_min = 0;
|
||||||
|
cfg.x_max = TFT_HEIGHT - 1;
|
||||||
|
cfg.y_min = 0;
|
||||||
|
cfg.y_max = TFT_WIDTH - 1;
|
||||||
|
cfg.pin_int = SCREEN_TOUCH_INT;
|
||||||
|
cfg.bus_shared = true;
|
||||||
|
cfg.offset_rotation = 0;
|
||||||
|
// cfg.freq = 2500000;
|
||||||
|
|
||||||
|
// I2C
|
||||||
|
cfg.i2c_port = TOUCH_I2C_PORT;
|
||||||
|
cfg.i2c_addr = TOUCH_SLAVE_ADDRESS;
|
||||||
|
#ifdef SCREEN_TOUCH_USE_I2C1
|
||||||
|
cfg.pin_sda = I2C_SDA1;
|
||||||
|
cfg.pin_scl = I2C_SCL1;
|
||||||
|
#else
|
||||||
|
cfg.pin_sda = I2C_SDA;
|
||||||
|
cfg.pin_scl = I2C_SCL;
|
||||||
|
#endif
|
||||||
|
// cfg.freq = 400000;
|
||||||
|
|
||||||
|
_touch_instance.config(cfg);
|
||||||
|
_panel_instance.setTouch(&_touch_instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
setPanel(&_panel_instance); // Sets the panel to use.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static LGFX tft;
|
||||||
|
|
||||||
|
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER)
|
||||||
|
#include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip
|
||||||
|
|
||||||
|
static TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER)
|
||||||
#include "SPILock.h"
|
#include "SPILock.h"
|
||||||
#include "TFTDisplay.h"
|
#include "TFTDisplay.h"
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include <TFT_eSPI.h> // Graphics and font library for ST7735 driver chip
|
|
||||||
|
|
||||||
static TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h
|
|
||||||
|
|
||||||
TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY geometry, HW_I2C i2cBus)
|
TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY geometry, HW_I2C i2cBus)
|
||||||
{
|
{
|
||||||
@@ -30,7 +251,7 @@ void TFTDisplay::display(void)
|
|||||||
auto isset = buffer[x + (y / 8) * displayWidth] & (1 << (y & 7));
|
auto isset = buffer[x + (y / 8) * displayWidth] & (1 << (y & 7));
|
||||||
auto dblbuf_isset = buffer_back[x + (y / 8) * displayWidth] & (1 << (y & 7));
|
auto dblbuf_isset = buffer_back[x + (y / 8) * displayWidth] & (1 << (y & 7));
|
||||||
if (isset != dblbuf_isset) {
|
if (isset != dblbuf_isset) {
|
||||||
tft.drawPixel(x, y, isset ? TFT_WHITE : TFT_BLACK);
|
tft.drawPixel(x, y, isset ? TFT_MESH : TFT_BLACK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,8 +267,55 @@ void TFTDisplay::display(void)
|
|||||||
// Send a command to the display (low level function)
|
// Send a command to the display (low level function)
|
||||||
void TFTDisplay::sendCommand(uint8_t com)
|
void TFTDisplay::sendCommand(uint8_t com)
|
||||||
{
|
{
|
||||||
(void)com;
|
// handle display on/off directly
|
||||||
// Drop all commands to device (we just update the buffer)
|
switch (com) {
|
||||||
|
case DISPLAYON: {
|
||||||
|
#if defined(TFT_BL) && defined(TFT_BACKLIGHT_ON)
|
||||||
|
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
|
||||||
|
#endif
|
||||||
|
#ifdef VTFT_CTRL
|
||||||
|
digitalWrite(VTFT_CTRL, LOW);
|
||||||
|
#endif
|
||||||
|
#ifndef M5STACK
|
||||||
|
tft.setBrightness(128);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DISPLAYOFF: {
|
||||||
|
#if defined(TFT_BL) && defined(TFT_BACKLIGHT_ON)
|
||||||
|
digitalWrite(TFT_BL, !TFT_BACKLIGHT_ON);
|
||||||
|
#endif
|
||||||
|
#ifdef VTFT_CTRL
|
||||||
|
digitalWrite(VTFT_CTRL, HIGH);
|
||||||
|
#endif
|
||||||
|
#ifndef M5STACK
|
||||||
|
tft.setBrightness(0);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drop all other commands to device (we just update the buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TFTDisplay::hasTouch(void)
|
||||||
|
{
|
||||||
|
#ifndef M5STACK
|
||||||
|
return tft.touch() != nullptr;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TFTDisplay::getTouch(int16_t *x, int16_t *y)
|
||||||
|
{
|
||||||
|
#ifndef M5STACK
|
||||||
|
return tft.getTouch(x, y);
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void TFTDisplay::setDetected(uint8_t detected)
|
void TFTDisplay::setDetected(uint8_t detected)
|
||||||
@@ -62,23 +330,20 @@ bool TFTDisplay::connect()
|
|||||||
LOG_INFO("Doing TFT init\n");
|
LOG_INFO("Doing TFT init\n");
|
||||||
|
|
||||||
#ifdef TFT_BL
|
#ifdef TFT_BL
|
||||||
digitalWrite(TFT_BL, HIGH);
|
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
|
||||||
pinMode(TFT_BL, OUTPUT);
|
pinMode(TFT_BL, OUTPUT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ST7735_BACKLIGHT_EN
|
|
||||||
digitalWrite(ST7735_BACKLIGHT_EN, HIGH);
|
|
||||||
pinMode(ST7735_BACKLIGHT_EN, OUTPUT);
|
|
||||||
#endif
|
|
||||||
tft.init();
|
tft.init();
|
||||||
#ifdef M5STACK
|
#if defined(M5STACK) || defined(T_DECK)
|
||||||
tft.setRotation(1); // M5Stack has the TFT in landscape
|
tft.setRotation(1); // M5Stack/T-Deck have the TFT in landscape
|
||||||
|
#elif defined(T_WATCH_S3)
|
||||||
|
tft.setRotation(0); // T-Watch S3 has the TFT in portrait
|
||||||
#else
|
#else
|
||||||
tft.setRotation(3); // Orient horizontal and wide underneath the silkscreen name label
|
tft.setRotation(3); // Orient horizontal and wide underneath the silkscreen name label
|
||||||
#endif
|
#endif
|
||||||
tft.fillScreen(TFT_BLACK);
|
tft.fillScreen(TFT_BLACK);
|
||||||
// tft.drawRect(0, 0, 40, 10, TFT_PURPLE); // wide rectangle in upper left
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -7,7 +7,6 @@
|
|||||||
*
|
*
|
||||||
* Remaining TODO:
|
* Remaining TODO:
|
||||||
* optimize display() to only draw changed pixels (see other OLED subclasses for examples)
|
* optimize display() to only draw changed pixels (see other OLED subclasses for examples)
|
||||||
* implement displayOn/displayOff to turn off the TFT device (and backlight)
|
|
||||||
* Use the fast NRF52 SPI API rather than the slow standard arduino version
|
* Use the fast NRF52 SPI API rather than the slow standard arduino version
|
||||||
*
|
*
|
||||||
* turn radio back on - currently with both on spi bus is fucked? or are we leaving chip select asserted?
|
* turn radio back on - currently with both on spi bus is fucked? or are we leaving chip select asserted?
|
||||||
@@ -23,6 +22,10 @@ class TFTDisplay : public OLEDDisplay
|
|||||||
// Write the buffer to the display memory
|
// Write the buffer to the display memory
|
||||||
virtual void display(void) override;
|
virtual void display(void) override;
|
||||||
|
|
||||||
|
// Touch screen (static handlers)
|
||||||
|
static bool hasTouch(void);
|
||||||
|
static bool getTouch(int16_t *x, int16_t *y);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shim to make the abstraction happy
|
* shim to make the abstraction happy
|
||||||
*
|
*
|
||||||
@@ -38,4 +41,4 @@ class TFTDisplay : public OLEDDisplay
|
|||||||
|
|
||||||
// Connect to the display
|
// Connect to the display
|
||||||
virtual bool connect() override;
|
virtual bool connect() override;
|
||||||
};
|
};
|
||||||
@@ -14,7 +14,7 @@ const uint8_t imgUser[] PROGMEM = {0x3C, 0x42, 0x99, 0xA5, 0xA5, 0x99, 0x42, 0x3
|
|||||||
const uint8_t imgPositionEmpty[] PROGMEM = {0x20, 0x30, 0x28, 0x24, 0x42, 0xFF};
|
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 imgPositionSolid[] PROGMEM = {0x20, 0x30, 0x38, 0x3C, 0x7E, 0xFF};
|
||||||
|
|
||||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(USE_ST7789)
|
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)
|
||||||
const uint8_t imgQuestionL1[] PROGMEM = {0xff, 0x01, 0x01, 0x32, 0x7b, 0x49, 0x49, 0x6f, 0x26, 0x01, 0x01, 0xff};
|
const uint8_t imgQuestionL1[] PROGMEM = {0xff, 0x01, 0x01, 0x32, 0x7b, 0x49, 0x49, 0x6f, 0x26, 0x01, 0x01, 0xff};
|
||||||
const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};
|
const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};
|
||||||
const uint8_t imgInfoL1[] PROGMEM = {0xff, 0x01, 0x01, 0x01, 0x1e, 0x7f, 0x1e, 0x01, 0x01, 0x01, 0x01, 0xff};
|
const uint8_t imgInfoL1[] PROGMEM = {0xff, 0x01, 0x01, 0x01, 0x1e, 0x7f, 0x1e, 0x01, 0x01, 0x01, 0x01, 0xff};
|
||||||
|
|||||||
@@ -0,0 +1,137 @@
|
|||||||
|
#include "TouchScreenBase.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
#ifndef TIME_LONG_PRESS
|
||||||
|
#define TIME_LONG_PRESS 400
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// move a minimum distance over the screen to detect a "swipe"
|
||||||
|
#ifndef TOUCH_THRESHOLD_X
|
||||||
|
#define TOUCH_THRESHOLD_X 30
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TOUCH_THRESHOLD_Y
|
||||||
|
#define TOUCH_THRESHOLD_Y 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TouchScreenBase::TouchScreenBase(const char *name, uint16_t width, uint16_t height)
|
||||||
|
: concurrency::OSThread(name), _display_width(width), _display_height(height), _first_x(0), _last_x(0), _first_y(0),
|
||||||
|
_last_y(0), _start(0), _tapped(false), _originName(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TouchScreenBase::init(bool hasTouch)
|
||||||
|
{
|
||||||
|
if (hasTouch) {
|
||||||
|
LOG_INFO("TouchScreen initialized %d %d\n", TOUCH_THRESHOLD_X, TOUCH_THRESHOLD_Y);
|
||||||
|
this->setInterval(100);
|
||||||
|
} else {
|
||||||
|
disable();
|
||||||
|
this->setInterval(UINT_MAX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t TouchScreenBase::runOnce()
|
||||||
|
{
|
||||||
|
TouchEvent e;
|
||||||
|
e.touchEvent = static_cast<char>(TOUCH_ACTION_NONE);
|
||||||
|
|
||||||
|
// process touch events
|
||||||
|
int16_t x, y;
|
||||||
|
bool touched = getTouch(x, y);
|
||||||
|
if (touched) {
|
||||||
|
hapticFeedback();
|
||||||
|
this->setInterval(20);
|
||||||
|
_last_x = x;
|
||||||
|
_last_y = y;
|
||||||
|
}
|
||||||
|
if (touched != _touchedOld) {
|
||||||
|
if (touched) {
|
||||||
|
_state = TOUCH_EVENT_OCCURRED;
|
||||||
|
_start = millis();
|
||||||
|
_first_x = x;
|
||||||
|
_first_y = y;
|
||||||
|
} else {
|
||||||
|
_state = TOUCH_EVENT_CLEARED;
|
||||||
|
time_t duration = millis() - _start;
|
||||||
|
x = _last_x;
|
||||||
|
y = _last_y;
|
||||||
|
this->setInterval(50);
|
||||||
|
|
||||||
|
// compute distance
|
||||||
|
int16_t dx = x - _first_x;
|
||||||
|
int16_t dy = y - _first_y;
|
||||||
|
uint16_t adx = abs(dx);
|
||||||
|
uint16_t ady = abs(dy);
|
||||||
|
|
||||||
|
// swipe horizontal
|
||||||
|
if (adx > ady && adx > TOUCH_THRESHOLD_X) {
|
||||||
|
if (0 > dx) { // swipe right to left
|
||||||
|
e.touchEvent = static_cast<char>(TOUCH_ACTION_LEFT);
|
||||||
|
LOG_DEBUG("action SWIPE: right to left\n");
|
||||||
|
} else { // swipe left to right
|
||||||
|
e.touchEvent = static_cast<char>(TOUCH_ACTION_RIGHT);
|
||||||
|
LOG_DEBUG("action SWIPE: left to right\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// swipe vertical
|
||||||
|
else if (ady > adx && ady > TOUCH_THRESHOLD_Y) {
|
||||||
|
if (0 > dy) { // swipe bottom to top
|
||||||
|
e.touchEvent = static_cast<char>(TOUCH_ACTION_UP);
|
||||||
|
LOG_DEBUG("action SWIPE: bottom to top\n");
|
||||||
|
} else { // swipe top to bottom
|
||||||
|
e.touchEvent = static_cast<char>(TOUCH_ACTION_DOWN);
|
||||||
|
LOG_DEBUG("action SWIPE: top to bottom\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// tap
|
||||||
|
else {
|
||||||
|
if (duration > 0 && duration < TIME_LONG_PRESS) {
|
||||||
|
if (_tapped) {
|
||||||
|
_tapped = false;
|
||||||
|
e.touchEvent = static_cast<char>(TOUCH_ACTION_DOUBLE_TAP);
|
||||||
|
LOG_DEBUG("action DOUBLE TAP(%d/%d)\n", x, y);
|
||||||
|
} else {
|
||||||
|
_tapped = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_tapped = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_touchedOld = touched;
|
||||||
|
|
||||||
|
// fire TAP event when no 2nd tap occured within time
|
||||||
|
if (_tapped && (time_t(millis()) - _start) > TIME_LONG_PRESS - 50) {
|
||||||
|
_tapped = false;
|
||||||
|
e.touchEvent = static_cast<char>(TOUCH_ACTION_TAP);
|
||||||
|
LOG_DEBUG("action TAP(%d/%d)\n", _last_x, _last_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fire LONG_PRESS event without the need for release
|
||||||
|
if (touched && (time_t(millis()) - _start) > TIME_LONG_PRESS) {
|
||||||
|
// tricky: prevent reoccurring events and another touch event when releasing
|
||||||
|
_start = millis() + 30000;
|
||||||
|
e.touchEvent = static_cast<char>(TOUCH_ACTION_LONG_PRESS);
|
||||||
|
LOG_DEBUG("action LONG PRESS(%d/%d)\n", _last_x, _last_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.touchEvent != TOUCH_ACTION_NONE) {
|
||||||
|
e.source = this->_originName;
|
||||||
|
e.x = _last_x;
|
||||||
|
e.y = _last_y;
|
||||||
|
onEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TouchScreenBase::hapticFeedback()
|
||||||
|
{
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
drv.setWaveform(0, 75);
|
||||||
|
drv.setWaveform(1, 0); // end waveform
|
||||||
|
drv.go();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "InputBroker.h"
|
||||||
|
#include "concurrency/OSThread.h"
|
||||||
|
#include "mesh/NodeDB.h"
|
||||||
|
|
||||||
|
typedef struct _TouchEvent {
|
||||||
|
const char *source;
|
||||||
|
char touchEvent;
|
||||||
|
uint16_t x;
|
||||||
|
uint16_t y;
|
||||||
|
} TouchEvent;
|
||||||
|
|
||||||
|
class TouchScreenBase : public Observable<const InputEvent *>, public concurrency::OSThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit TouchScreenBase(const char *name, uint16_t width, uint16_t height);
|
||||||
|
void init(bool hasTouch);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
enum TouchScreenBaseStateType { TOUCH_EVENT_OCCURRED, TOUCH_EVENT_CLEARED };
|
||||||
|
|
||||||
|
enum TouchScreenBaseEventType {
|
||||||
|
TOUCH_ACTION_NONE,
|
||||||
|
TOUCH_ACTION_UP,
|
||||||
|
TOUCH_ACTION_DOWN,
|
||||||
|
TOUCH_ACTION_LEFT,
|
||||||
|
TOUCH_ACTION_RIGHT,
|
||||||
|
TOUCH_ACTION_TAP,
|
||||||
|
TOUCH_ACTION_DOUBLE_TAP,
|
||||||
|
TOUCH_ACTION_LONG_PRESS
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual int32_t runOnce() override;
|
||||||
|
|
||||||
|
virtual bool getTouch(int16_t &x, int16_t &y) = 0;
|
||||||
|
virtual void onEvent(const TouchEvent &event) = 0;
|
||||||
|
|
||||||
|
volatile TouchScreenBaseStateType _state = TOUCH_EVENT_CLEARED;
|
||||||
|
volatile TouchScreenBaseEventType _action = TOUCH_ACTION_NONE;
|
||||||
|
void hapticFeedback();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint16_t _display_width;
|
||||||
|
uint16_t _display_height;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _touchedOld = false; // previous touch state
|
||||||
|
int16_t _first_x, _last_x; // horizontal swipe direction
|
||||||
|
int16_t _first_y, _last_y; // vertical swipe direction
|
||||||
|
time_t _start; // for LONG_PRESS
|
||||||
|
bool _tapped; // for DOUBLE_TAP
|
||||||
|
|
||||||
|
const char *_originName;
|
||||||
|
};
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
#include "TouchScreenImpl1.h"
|
||||||
|
#include "InputBroker.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
TouchScreenImpl1 *touchScreenImpl1;
|
||||||
|
|
||||||
|
TouchScreenImpl1::TouchScreenImpl1(uint16_t width, uint16_t height, bool (*getTouch)(int16_t *, int16_t *))
|
||||||
|
: TouchScreenBase("touchscreen1", width, height), _getTouch(getTouch)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TouchScreenImpl1::init()
|
||||||
|
{
|
||||||
|
#if !HAS_TOUCHSCREEN
|
||||||
|
TouchScreenBase::init(false);
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
TouchScreenBase::init(true);
|
||||||
|
inputBroker->registerSource(this);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TouchScreenImpl1::getTouch(int16_t &x, int16_t &y)
|
||||||
|
{
|
||||||
|
return _getTouch(&x, &y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief forward touchscreen event
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*
|
||||||
|
* The touchscreen events are translated to input events and reversed
|
||||||
|
*/
|
||||||
|
void TouchScreenImpl1::onEvent(const TouchEvent &event)
|
||||||
|
{
|
||||||
|
InputEvent e;
|
||||||
|
e.source = event.source;
|
||||||
|
switch (event.touchEvent) {
|
||||||
|
case TOUCH_ACTION_LEFT: {
|
||||||
|
e.inputEvent = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TOUCH_ACTION_RIGHT: {
|
||||||
|
e.inputEvent = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TOUCH_ACTION_UP: {
|
||||||
|
e.inputEvent = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TOUCH_ACTION_DOWN: {
|
||||||
|
e.inputEvent = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TOUCH_ACTION_DOUBLE_TAP: {
|
||||||
|
e.inputEvent = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TOUCH_ACTION_LONG_PRESS: {
|
||||||
|
e.inputEvent = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->notifyObservers(&e);
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "TouchScreenBase.h"
|
||||||
|
|
||||||
|
class TouchScreenImpl1 : public TouchScreenBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TouchScreenImpl1(uint16_t width, uint16_t height, bool (*getTouch)(int16_t *, int16_t *));
|
||||||
|
void init(void);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool getTouch(int16_t &x, int16_t &y);
|
||||||
|
virtual void onEvent(const TouchEvent &event);
|
||||||
|
|
||||||
|
bool (*_getTouch)(int16_t *, int16_t *);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern TouchScreenImpl1 *touchScreenImpl1;
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
#include "TrackballInterruptBase.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
TrackballInterruptBase::TrackballInterruptBase(const char *name)
|
||||||
|
{
|
||||||
|
this->_originName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackballInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinLeft, uint8_t pinRight, uint8_t pinPress,
|
||||||
|
char eventDown, char eventUp, char eventLeft, char eventRight, char eventPressed,
|
||||||
|
void (*onIntDown)(), void (*onIntUp)(), void (*onIntLeft)(), void (*onIntRight)(),
|
||||||
|
void (*onIntPress)())
|
||||||
|
{
|
||||||
|
this->_pinDown = pinDown;
|
||||||
|
this->_pinUp = pinUp;
|
||||||
|
this->_pinLeft = pinLeft;
|
||||||
|
this->_pinRight = pinRight;
|
||||||
|
this->_eventDown = eventDown;
|
||||||
|
this->_eventUp = eventUp;
|
||||||
|
this->_eventLeft = eventLeft;
|
||||||
|
this->_eventRight = eventRight;
|
||||||
|
this->_eventPressed = eventPressed;
|
||||||
|
|
||||||
|
pinMode(pinPress, INPUT_PULLUP);
|
||||||
|
pinMode(this->_pinDown, INPUT_PULLUP);
|
||||||
|
pinMode(this->_pinUp, INPUT_PULLUP);
|
||||||
|
pinMode(this->_pinLeft, INPUT_PULLUP);
|
||||||
|
pinMode(this->_pinRight, INPUT_PULLUP);
|
||||||
|
|
||||||
|
attachInterrupt(pinPress, onIntPress, RISING);
|
||||||
|
attachInterrupt(this->_pinDown, onIntDown, RISING);
|
||||||
|
attachInterrupt(this->_pinUp, onIntUp, RISING);
|
||||||
|
attachInterrupt(this->_pinLeft, onIntLeft, RISING);
|
||||||
|
attachInterrupt(this->_pinRight, onIntRight, RISING);
|
||||||
|
|
||||||
|
LOG_DEBUG("Trackball GPIO initialized (%d, %d, %d, %d, %d)\n", this->_pinUp, this->_pinDown, this->_pinLeft, this->_pinRight,
|
||||||
|
pinPress);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackballInterruptBase::intPressHandler()
|
||||||
|
{
|
||||||
|
InputEvent e;
|
||||||
|
e.source = this->_originName;
|
||||||
|
e.inputEvent = this->_eventPressed;
|
||||||
|
this->notifyObservers(&e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackballInterruptBase::intDownHandler()
|
||||||
|
{
|
||||||
|
InputEvent e;
|
||||||
|
e.source = this->_originName;
|
||||||
|
e.inputEvent = this->_eventDown;
|
||||||
|
this->notifyObservers(&e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackballInterruptBase::intUpHandler()
|
||||||
|
{
|
||||||
|
InputEvent e;
|
||||||
|
e.source = this->_originName;
|
||||||
|
e.inputEvent = this->_eventUp;
|
||||||
|
this->notifyObservers(&e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackballInterruptBase::intLeftHandler()
|
||||||
|
{
|
||||||
|
InputEvent e;
|
||||||
|
e.source = this->_originName;
|
||||||
|
e.inputEvent = this->_eventLeft;
|
||||||
|
this->notifyObservers(&e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackballInterruptBase::intRightHandler()
|
||||||
|
{
|
||||||
|
InputEvent e;
|
||||||
|
e.source = this->_originName;
|
||||||
|
e.inputEvent = this->_eventRight;
|
||||||
|
this->notifyObservers(&e);
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "InputBroker.h"
|
||||||
|
#include "mesh/NodeDB.h"
|
||||||
|
|
||||||
|
class TrackballInterruptBase : public Observable<const InputEvent *>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit TrackballInterruptBase(const char *name);
|
||||||
|
void init(uint8_t pinDown, uint8_t pinUp, uint8_t pinLeft, uint8_t pinRight, uint8_t pinPress, char eventDown, char eventUp,
|
||||||
|
char eventLeft, char eventRight, char eventPressed, void (*onIntDown)(), void (*onIntUp)(), void (*onIntLeft)(),
|
||||||
|
void (*onIntRight)(), void (*onIntPress)());
|
||||||
|
void intPressHandler();
|
||||||
|
void intDownHandler();
|
||||||
|
void intUpHandler();
|
||||||
|
void intLeftHandler();
|
||||||
|
void intRightHandler();
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t _pinDown = 0;
|
||||||
|
uint8_t _pinUp = 0;
|
||||||
|
uint8_t _pinLeft = 0;
|
||||||
|
uint8_t _pinRight = 0;
|
||||||
|
char _eventDown = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||||
|
char _eventUp = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||||
|
char _eventLeft = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||||
|
char _eventRight = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||||
|
char _eventPressed = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||||
|
const char *_originName;
|
||||||
|
};
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#include "TrackballInterruptImpl1.h"
|
||||||
|
#include "InputBroker.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
TrackballInterruptImpl1 *trackballInterruptImpl1;
|
||||||
|
|
||||||
|
TrackballInterruptImpl1::TrackballInterruptImpl1() : TrackballInterruptBase("trackball1") {}
|
||||||
|
|
||||||
|
void TrackballInterruptImpl1::init()
|
||||||
|
{
|
||||||
|
#if !HAS_TRACKBALL
|
||||||
|
// Input device is disabled.
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
uint8_t pinUp = TB_UP;
|
||||||
|
uint8_t pinDown = TB_DOWN;
|
||||||
|
uint8_t pinLeft = TB_LEFT;
|
||||||
|
uint8_t pinRight = TB_RIGHT;
|
||||||
|
uint8_t pinPress = TB_PRESS;
|
||||||
|
|
||||||
|
char eventDown = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN);
|
||||||
|
char eventUp = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP);
|
||||||
|
char eventLeft = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT);
|
||||||
|
char eventRight = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT);
|
||||||
|
char eventPressed = static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT);
|
||||||
|
|
||||||
|
TrackballInterruptBase::init(pinDown, pinUp, pinLeft, pinRight, pinPress, eventDown, eventUp, eventLeft, eventRight,
|
||||||
|
eventPressed, TrackballInterruptImpl1::handleIntDown, TrackballInterruptImpl1::handleIntUp,
|
||||||
|
TrackballInterruptImpl1::handleIntLeft, TrackballInterruptImpl1::handleIntRight,
|
||||||
|
TrackballInterruptImpl1::handleIntPressed);
|
||||||
|
inputBroker->registerSource(this);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackballInterruptImpl1::handleIntDown()
|
||||||
|
{
|
||||||
|
trackballInterruptImpl1->intDownHandler();
|
||||||
|
}
|
||||||
|
void TrackballInterruptImpl1::handleIntUp()
|
||||||
|
{
|
||||||
|
trackballInterruptImpl1->intUpHandler();
|
||||||
|
}
|
||||||
|
void TrackballInterruptImpl1::handleIntLeft()
|
||||||
|
{
|
||||||
|
trackballInterruptImpl1->intLeftHandler();
|
||||||
|
}
|
||||||
|
void TrackballInterruptImpl1::handleIntRight()
|
||||||
|
{
|
||||||
|
trackballInterruptImpl1->intRightHandler();
|
||||||
|
}
|
||||||
|
void TrackballInterruptImpl1::handleIntPressed()
|
||||||
|
{
|
||||||
|
trackballInterruptImpl1->intPressHandler();
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "TrackballInterruptBase.h"
|
||||||
|
|
||||||
|
class TrackballInterruptImpl1 : public TrackballInterruptBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TrackballInterruptImpl1();
|
||||||
|
void init();
|
||||||
|
static void handleIntDown();
|
||||||
|
static void handleIntUp();
|
||||||
|
static void handleIntLeft();
|
||||||
|
static void handleIntRight();
|
||||||
|
static void handleIntPressed();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern TrackballInterruptImpl1 *trackballInterruptImpl1;
|
||||||
@@ -23,7 +23,7 @@ void UpDownInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinPress,
|
|||||||
attachInterrupt(this->_pinDown, onIntDown, RISING);
|
attachInterrupt(this->_pinDown, onIntDown, RISING);
|
||||||
attachInterrupt(this->_pinUp, onIntUp, RISING);
|
attachInterrupt(this->_pinUp, onIntUp, RISING);
|
||||||
|
|
||||||
LOG_DEBUG("GPIO initialized (%d, %d, %d)\n", this->_pinDown, this->_pinUp, pinPress);
|
LOG_DEBUG("Up/down/press GPIO initialized (%d, %d, %d)\n", this->_pinUp, this->_pinDown, pinPress);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpDownInterruptBase::intPressHandler()
|
void UpDownInterruptBase::intPressHandler()
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ CardKbI2cImpl::CardKbI2cImpl() : KbI2cBase("cardKB") {}
|
|||||||
|
|
||||||
void CardKbI2cImpl::init()
|
void CardKbI2cImpl::init()
|
||||||
{
|
{
|
||||||
if (cardkb_found.address != CARDKB_ADDR) {
|
if (cardkb_found.address != CARDKB_ADDR && cardkb_found.address != TDECK_KB_ADDR) {
|
||||||
disable();
|
disable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ void write_to_14004(const TwoWire * i2cBus, uint8_t reg, uint8_t data)
|
|||||||
|
|
||||||
int32_t KbI2cBase::runOnce()
|
int32_t KbI2cBase::runOnce()
|
||||||
{
|
{
|
||||||
if (cardkb_found.address != CARDKB_ADDR) {
|
if (cardkb_found.address != CARDKB_ADDR && cardkb_found.address != TDECK_KB_ADDR) {
|
||||||
// Input device is not detected.
|
// Input device is not detected.
|
||||||
return INT32_MAX;
|
return INT32_MAX;
|
||||||
}
|
}
|
||||||
@@ -85,9 +85,9 @@ int32_t KbI2cBase::runOnce()
|
|||||||
e.kbchar = PrintDataBuf;
|
e.kbchar = PrintDataBuf;
|
||||||
this->notifyObservers(&e);
|
this->notifyObservers(&e);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (kb_model == 0x00 || kb_model == 0x10) {
|
||||||
// m5 cardkb
|
// m5 cardkb and T-Deck
|
||||||
i2cBus->requestFrom(CARDKB_ADDR, 1);
|
i2cBus->requestFrom(kb_model == 0x00 ? CARDKB_ADDR : TDECK_KB_ADDR, 1);
|
||||||
|
|
||||||
while (i2cBus->available()) {
|
while (i2cBus->available()) {
|
||||||
char c = i2cBus->read();
|
char c = i2cBus->read();
|
||||||
@@ -132,6 +132,8 @@ int32_t KbI2cBase::runOnce()
|
|||||||
this->notifyObservers(&e);
|
this->notifyObservers(&e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
LOG_WARN("Unknown kb_model 0x%02x\n", kb_model);
|
||||||
}
|
}
|
||||||
return 500;
|
return 300;
|
||||||
}
|
}
|
||||||
|
|||||||
+74
-17
@@ -47,13 +47,12 @@ NRF52Bluetooth *nrf52Bluetooth;
|
|||||||
|
|
||||||
#if HAS_WIFI
|
#if HAS_WIFI
|
||||||
#include "mesh/api/WiFiServerAPI.h"
|
#include "mesh/api/WiFiServerAPI.h"
|
||||||
#include "mqtt/MQTT.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_ETHERNET
|
#if HAS_ETHERNET
|
||||||
#include "mesh/api/ethServerAPI.h"
|
#include "mesh/api/ethServerAPI.h"
|
||||||
#include "mqtt/MQTT.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
#include "mqtt/MQTT.h"
|
||||||
|
|
||||||
#include "LLCC68Interface.h"
|
#include "LLCC68Interface.h"
|
||||||
#include "RF95Interface.h"
|
#include "RF95Interface.h"
|
||||||
@@ -97,7 +96,7 @@ ScanI2C::DeviceAddress screen_found = ScanI2C::ADDRESS_NONE;
|
|||||||
|
|
||||||
// The I2C address of the cardkb or RAK14004 (if found)
|
// The I2C address of the cardkb or RAK14004 (if found)
|
||||||
ScanI2C::DeviceAddress cardkb_found = ScanI2C::ADDRESS_NONE;
|
ScanI2C::DeviceAddress cardkb_found = ScanI2C::ADDRESS_NONE;
|
||||||
// 0x02 for RAK14004 and 0x00 for cardkb
|
// 0x02 for RAK14004, 0x00 for cardkb, 0x10 for T-Deck
|
||||||
uint8_t kb_model;
|
uint8_t kb_model;
|
||||||
|
|
||||||
// The I2C address of the RTC Module (if found)
|
// The I2C address of the RTC Module (if found)
|
||||||
@@ -111,6 +110,11 @@ ScanI2C::FoundDevice rgb_found = ScanI2C::FoundDevice(ScanI2C::DeviceType::NONE,
|
|||||||
ATECCX08A atecc;
|
ATECCX08A atecc;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
Adafruit_DRV2605 drv;
|
||||||
|
#endif
|
||||||
|
bool isVibrating = false;
|
||||||
|
|
||||||
bool eink_found = true;
|
bool eink_found = true;
|
||||||
|
|
||||||
uint32_t serialSinceMsec;
|
uint32_t serialSinceMsec;
|
||||||
@@ -170,7 +174,7 @@ SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0);
|
|||||||
RadioInterface *rIf = NULL;
|
RadioInterface *rIf = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some platforms (nrf52) might provide an alterate version that supresses calling delay from sleep.
|
* Some platforms (nrf52) might provide an alterate version that suppresses calling delay from sleep.
|
||||||
*/
|
*/
|
||||||
__attribute__((weak, noinline)) bool loopCanSleep()
|
__attribute__((weak, noinline)) bool loopCanSleep()
|
||||||
{
|
{
|
||||||
@@ -215,6 +219,16 @@ void setup()
|
|||||||
digitalWrite(VEXT_ENABLE, 0); // turn on the display power
|
digitalWrite(VEXT_ENABLE, 0); // turn on the display power
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef VGNSS_CTRL
|
||||||
|
pinMode(VGNSS_CTRL, OUTPUT);
|
||||||
|
digitalWrite(VGNSS_CTRL, LOW);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(VTFT_CTRL)
|
||||||
|
pinMode(VTFT_CTRL, OUTPUT);
|
||||||
|
digitalWrite(VTFT_CTRL, LOW);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef RESET_OLED
|
#ifdef RESET_OLED
|
||||||
pinMode(RESET_OLED, OUTPUT);
|
pinMode(RESET_OLED, OUTPUT);
|
||||||
digitalWrite(RESET_OLED, 1);
|
digitalWrite(RESET_OLED, 1);
|
||||||
@@ -241,6 +255,19 @@ void setup()
|
|||||||
|
|
||||||
fsInit();
|
fsInit();
|
||||||
|
|
||||||
|
#if defined(_SEEED_XIAO_NRF52840_SENSE_H_)
|
||||||
|
|
||||||
|
pinMode(CHARGE_LED, INPUT); // sets to detect if charge LED is on or off to see if USB is plugged in
|
||||||
|
|
||||||
|
pinMode(HICHG, OUTPUT);
|
||||||
|
digitalWrite(HICHG, LOW); // 100 mA charging current if set to LOW and 50mA (actually about 20mA) if set to HIGH
|
||||||
|
|
||||||
|
pinMode(BAT_READ, OUTPUT);
|
||||||
|
digitalWrite(BAT_READ, LOW); // This is pin P0_14 = 14 and by pullling low to GND it provices path to read on pin 32 (P0,31)
|
||||||
|
// PIN_VBAT the voltage from divider on XIAO board
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef I2C_SDA1
|
#ifdef I2C_SDA1
|
||||||
Wire1.begin(I2C_SDA1, I2C_SCL1);
|
Wire1.begin(I2C_SDA1, I2C_SCL1);
|
||||||
#endif
|
#endif
|
||||||
@@ -261,10 +288,11 @@ void setup()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RAK4630
|
#ifdef RAK4630
|
||||||
|
#ifdef PIN_3V3_EN
|
||||||
// We need to enable 3.3V periphery in order to scan it
|
// We need to enable 3.3V periphery in order to scan it
|
||||||
pinMode(PIN_3V3_EN, OUTPUT);
|
pinMode(PIN_3V3_EN, OUTPUT);
|
||||||
digitalWrite(PIN_3V3_EN, HIGH);
|
digitalWrite(PIN_3V3_EN, HIGH);
|
||||||
|
#endif
|
||||||
#ifndef USE_EINK
|
#ifndef USE_EINK
|
||||||
// RAK-12039 set pin for Air quality sensor
|
// RAK-12039 set pin for Air quality sensor
|
||||||
pinMode(AQ_SET_PIN, OUTPUT);
|
pinMode(AQ_SET_PIN, OUTPUT);
|
||||||
@@ -272,6 +300,15 @@ void setup()
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef T_DECK
|
||||||
|
// enable keyboard
|
||||||
|
pinMode(KB_POWERON, OUTPUT);
|
||||||
|
digitalWrite(KB_POWERON, HIGH);
|
||||||
|
// There needs to be a delay after power on, give LILYGO-KEYBOARD some startup time
|
||||||
|
// otherwise keyboard and touch screen will not work
|
||||||
|
delay(800);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Currently only the tbeam has a PMU
|
// Currently only the tbeam has a PMU
|
||||||
// PMU initialization needs to be placed before i2c scanning
|
// PMU initialization needs to be placed before i2c scanning
|
||||||
power = new Power();
|
power = new Power();
|
||||||
@@ -344,25 +381,33 @@ void setup()
|
|||||||
kb_model = 0x02;
|
kb_model = 0x02;
|
||||||
break;
|
break;
|
||||||
case ScanI2C::DeviceType::CARDKB:
|
case ScanI2C::DeviceType::CARDKB:
|
||||||
|
kb_model = 0x00;
|
||||||
|
break;
|
||||||
|
case ScanI2C::DeviceType::TDECKKB:
|
||||||
|
// assign an arbitrary value to distinguish from other models
|
||||||
|
kb_model = 0x10;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// use this as default since it's also just zero
|
// use this as default since it's also just zero
|
||||||
|
LOG_WARN("kb_info.type is unknown(0x%02x), setting kb_model=0x00\n", kb_info.type);
|
||||||
kb_model = 0x00;
|
kb_model = 0x00;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pmu_found = i2cScanner->exists(ScanI2C::DeviceType::PMU_AXP192_AXP2101);
|
pmu_found = i2cScanner->exists(ScanI2C::DeviceType::PMU_AXP192_AXP2101);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There are a bunch of sensors that have no further logic than to be found and stuffed into the
|
* There are a bunch of sensors that have no further logic than to be found and stuffed into the
|
||||||
* nodeTelemetrySensorsMap singleton. This wraps that logic in a temporary scope to declare the temporary field
|
* nodeTelemetrySensorsMap singleton. This wraps that logic in a temporary scope to declare the temporary field
|
||||||
* "found".
|
* "found".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Only one supported RGB LED currently
|
// Only one supported RGB LED currently
|
||||||
|
#ifdef HAS_NCP5623
|
||||||
rgb_found = i2cScanner->find(ScanI2C::DeviceType::NCP5623);
|
rgb_found = i2cScanner->find(ScanI2C::DeviceType::NCP5623);
|
||||||
|
|
||||||
// Start the RGB LED at 50%
|
// Start the RGB LED at 50%
|
||||||
#ifdef RAK4630
|
|
||||||
if (rgb_found.type == ScanI2C::NCP5623) {
|
if (rgb_found.type == ScanI2C::NCP5623) {
|
||||||
rgb.begin();
|
rgb.begin();
|
||||||
rgb.setCurrent(10);
|
rgb.setCurrent(10);
|
||||||
@@ -429,6 +474,11 @@ void setup()
|
|||||||
#ifdef ARCH_NRF52
|
#ifdef ARCH_NRF52
|
||||||
nrf52Setup();
|
nrf52Setup();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ARCH_RP2040
|
||||||
|
rp2040Setup();
|
||||||
|
#endif
|
||||||
|
|
||||||
// We do this as early as possible because this loads preferences from flash
|
// We do this as early as possible because this loads preferences from flash
|
||||||
// but we need to do this after main cpu iniot (esp32setup), because we need the random seed set
|
// but we need to do this after main cpu iniot (esp32setup), because we need the random seed set
|
||||||
nodeDB.init();
|
nodeDB.init();
|
||||||
@@ -461,10 +511,19 @@ void setup()
|
|||||||
|
|
||||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||||
if (acc_info.type != ScanI2C::DeviceType::NONE) {
|
if (acc_info.type != ScanI2C::DeviceType::NONE) {
|
||||||
|
config.display.wake_on_tap_or_motion = true;
|
||||||
|
moduleConfig.external_notification.enabled = true;
|
||||||
accelerometerThread = new AccelerometerThread(acc_info.type);
|
accelerometerThread = new AccelerometerThread(acc_info.type);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
drv.begin();
|
||||||
|
drv.selectLibrary(1);
|
||||||
|
// I2C trigger by sending 'go' command
|
||||||
|
drv.setMode(DRV2605_MODE_INTTRIG);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Init our SPI controller (must be before screen and lora)
|
// Init our SPI controller (must be before screen and lora)
|
||||||
initSPI();
|
initSPI();
|
||||||
#ifdef ARCH_RP2040
|
#ifdef ARCH_RP2040
|
||||||
@@ -517,7 +576,7 @@ void setup()
|
|||||||
|
|
||||||
// Don't call screen setup until after nodedb is setup (because we need
|
// Don't call screen setup until after nodedb is setup (because we need
|
||||||
// the current region name)
|
// the current region name)
|
||||||
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER)
|
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7789_CS)
|
||||||
screen->setup();
|
screen->setup();
|
||||||
#else
|
#else
|
||||||
if (screen_found.port != ScanI2C::I2CPort::NO_I2C)
|
if (screen_found.port != ScanI2C::I2CPort::NO_I2C)
|
||||||
@@ -654,9 +713,7 @@ void setup()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAS_WIFI || HAS_ETHERNET
|
|
||||||
mqttInit();
|
mqttInit();
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ARCH_PORTDUINO
|
#ifndef ARCH_PORTDUINO
|
||||||
// Initialize Wifi
|
// Initialize Wifi
|
||||||
@@ -701,7 +758,7 @@ uint32_t rebootAtMsec; // If not zero we will reboot at this time (used to reb
|
|||||||
uint32_t shutdownAtMsec; // If not zero we will shutdown at this time (used to shutdown from python or mobile client)
|
uint32_t shutdownAtMsec; // If not zero we will shutdown at this time (used to shutdown from python or mobile client)
|
||||||
|
|
||||||
// If a thread does something that might need for it to be rescheduled ASAP it can set this flag
|
// If a thread does something that might need for it to be rescheduled ASAP it can set this flag
|
||||||
// This will supress the current delay and instead try to run ASAP.
|
// This will suppress the current delay and instead try to run ASAP.
|
||||||
bool runASAP;
|
bool runASAP;
|
||||||
|
|
||||||
extern meshtastic_DeviceMetadata getDeviceMetadata()
|
extern meshtastic_DeviceMetadata getDeviceMetadata()
|
||||||
|
|||||||
+8
-2
@@ -38,6 +38,12 @@ extern bool isUSBPowered;
|
|||||||
extern ATECCX08A atecc;
|
extern ATECCX08A atecc;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
#include <Adafruit_DRV2605.h>
|
||||||
|
extern Adafruit_DRV2605 drv;
|
||||||
|
#endif
|
||||||
|
extern bool isVibrating;
|
||||||
|
|
||||||
extern int TCPPort; // set by Portduino
|
extern int TCPPort; // set by Portduino
|
||||||
|
|
||||||
// Global Screen singleton.
|
// Global Screen singleton.
|
||||||
@@ -59,10 +65,10 @@ extern uint32_t shutdownAtMsec;
|
|||||||
extern uint32_t serialSinceMsec;
|
extern uint32_t serialSinceMsec;
|
||||||
|
|
||||||
// If a thread does something that might need for it to be rescheduled ASAP it can set this flag
|
// If a thread does something that might need for it to be rescheduled ASAP it can set this flag
|
||||||
// This will supress the current delay and instead try to run ASAP.
|
// This will suppress the current delay and instead try to run ASAP.
|
||||||
extern bool runASAP;
|
extern bool runASAP;
|
||||||
|
|
||||||
void nrf52Setup(), esp32Setup(), nrf52Loop(), esp32Loop(), clearBonds();
|
void nrf52Setup(), esp32Setup(), nrf52Loop(), esp32Loop(), rp2040Setup(), clearBonds();
|
||||||
|
|
||||||
meshtastic_DeviceMetadata getDeviceMetadata();
|
meshtastic_DeviceMetadata getDeviceMetadata();
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ class Channels
|
|||||||
/// The index of the primary channel
|
/// The index of the primary channel
|
||||||
ChannelIndex primaryIndex = 0;
|
ChannelIndex primaryIndex = 0;
|
||||||
|
|
||||||
/** The channel index that was requested for sending/receving. Note: if this channel is a secondary
|
/** The channel index that was requested for sending/receiving. Note: if this channel is a secondary
|
||||||
channel and does not have a PSK, we will use the PSK from the primary channel. If this channel is disabled
|
channel and does not have a PSK, we will use the PSK from the primary channel. If this channel is disabled
|
||||||
no sending or receiving will be allowed */
|
no sending or receiving will be allowed */
|
||||||
ChannelIndex activeChannelIndex = 0;
|
ChannelIndex activeChannelIndex = 0;
|
||||||
|
|||||||
@@ -21,7 +21,12 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
|
|||||||
{
|
{
|
||||||
if (wasSeenRecently(p)) { // Note: this will also add a recent packet record
|
if (wasSeenRecently(p)) { // Note: this will also add a recent packet record
|
||||||
printPacket("Ignoring incoming msg, because we've already seen it", p);
|
printPacket("Ignoring incoming msg, because we've already seen it", p);
|
||||||
Router::cancelSending(p->from, p->id); // cancel rebroadcast of this message *if* there was already one
|
if (config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER &&
|
||||||
|
config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER_CLIENT &&
|
||||||
|
config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER) {
|
||||||
|
// cancel rebroadcast of this message *if* there was already one, unless we're a router/repeater!
|
||||||
|
Router::cancelSending(p->from, p->id);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class FloodingRouter : public Router, protected PacketHistory
|
|||||||
/**
|
/**
|
||||||
* Should this incoming filter be dropped?
|
* Should this incoming filter be dropped?
|
||||||
*
|
*
|
||||||
* Called immedately on receiption, before any further processing.
|
* Called immediately on reception, before any further processing.
|
||||||
* @return true to abandon the packet
|
* @return true to abandon the packet
|
||||||
*/
|
*/
|
||||||
virtual bool shouldFilterReceived(const meshtastic_MeshPacket *p) override;
|
virtual bool shouldFilterReceived(const meshtastic_MeshPacket *p) override;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ meshtastic_MeshPacket *MeshModule::currentReply;
|
|||||||
|
|
||||||
MeshModule::MeshModule(const char *_name) : name(_name)
|
MeshModule::MeshModule(const char *_name) : name(_name)
|
||||||
{
|
{
|
||||||
// Can't trust static initalizer order, so we check each time
|
// Can't trust static initializer order, so we check each time
|
||||||
if (!modules)
|
if (!modules)
|
||||||
modules = new std::vector<MeshModule *>();
|
modules = new std::vector<MeshModule *>();
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ meshtastic_MeshPacket *MeshModule::allocAckNak(meshtastic_Routing_Error err, Nod
|
|||||||
c.error_reason = err;
|
c.error_reason = err;
|
||||||
c.which_variant = meshtastic_Routing_error_reason_tag;
|
c.which_variant = meshtastic_Routing_error_reason_tag;
|
||||||
|
|
||||||
// Now that we have moded sendAckNak up one level into the class heirarchy we can no longer assume we are a RoutingPlugin
|
// Now that we have moded sendAckNak up one level into the class hierarchy we can no longer assume we are a RoutingPlugin
|
||||||
// So we manually call pb_encode_to_bytes and specify routing port number
|
// So we manually call pb_encode_to_bytes and specify routing port number
|
||||||
// auto p = allocDataProtobuf(c);
|
// auto p = allocDataProtobuf(c);
|
||||||
meshtastic_MeshPacket *p = router->allocForSending();
|
meshtastic_MeshPacket *p = router->allocForSending();
|
||||||
@@ -169,7 +169,7 @@ void MeshModule::callPlugins(const meshtastic_MeshPacket &mp, RxSource src)
|
|||||||
// Note: if the message started with the local node or a module asked to ignore the request, we don't want to send a
|
// Note: if the message started with the local node or a module asked to ignore the request, we don't want to send a
|
||||||
// no response reply
|
// no response reply
|
||||||
|
|
||||||
// No one wanted to reply to this requst, tell the requster that happened
|
// No one wanted to reply to this request, tell the requster that happened
|
||||||
LOG_DEBUG("No one responded, send a nak\n");
|
LOG_DEBUG("No one responded, send a nak\n");
|
||||||
|
|
||||||
// SECURITY NOTE! I considered sending back a different error code if we didn't find the psk (i.e. !isDecoded)
|
// SECURITY NOTE! I considered sending back a different error code if we didn't find the psk (i.e. !isDecoded)
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ typedef struct _UIFrameEvent {
|
|||||||
* A key concept for this is that your module should use a particular "portnum" for each message type you want to receive
|
* A key concept for this is that your module should use a particular "portnum" for each message type you want to receive
|
||||||
* and handle.
|
* and handle.
|
||||||
*
|
*
|
||||||
* Interally we use modules to implement the core meshtastic text messaging and gps position sharing features. You
|
* Internally we use modules to implement the core meshtastic text messaging and gps position sharing features. You
|
||||||
* can use these classes as examples for how to write your own custom module. See here: (FIXME)
|
* can use these classes as examples for how to write your own custom module. See here: (FIXME)
|
||||||
*/
|
*/
|
||||||
class MeshModule
|
class MeshModule
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ arbitrating to select a node number and keeping the current nodedb.
|
|||||||
|
|
||||||
/* Broadcast when a newly powered mesh node wants to find a node num it can use
|
/* Broadcast when a newly powered mesh node wants to find a node num it can use
|
||||||
|
|
||||||
The algoritm is as follows:
|
The algorithm is as follows:
|
||||||
* when a node starts up, it broadcasts their user and the normal flow is for all other nodes to reply with their User as well (so
|
* when a node starts up, it broadcasts their user and the normal flow is for all other nodes to reply with their User as well (so
|
||||||
the new node can build its node db)
|
the new node can build its node db)
|
||||||
* If a node ever receives a User (not just the first broadcast) message where the sender node number equals our node number, that
|
* If a node ever receives a User (not just the first broadcast) message where the sender node number equals our node number, that
|
||||||
@@ -52,13 +52,18 @@ FIXME in the initial proof of concept we just skip the entire want/deny flow and
|
|||||||
|
|
||||||
MeshService service;
|
MeshService service;
|
||||||
|
|
||||||
|
static MemoryDynamic<meshtastic_MqttClientProxyMessage> staticMqttClientProxyMessagePool;
|
||||||
|
|
||||||
static MemoryDynamic<meshtastic_QueueStatus> staticQueueStatusPool;
|
static MemoryDynamic<meshtastic_QueueStatus> staticQueueStatusPool;
|
||||||
|
|
||||||
|
Allocator<meshtastic_MqttClientProxyMessage> &mqttClientProxyMessagePool = staticMqttClientProxyMessagePool;
|
||||||
|
|
||||||
Allocator<meshtastic_QueueStatus> &queueStatusPool = staticQueueStatusPool;
|
Allocator<meshtastic_QueueStatus> &queueStatusPool = staticQueueStatusPool;
|
||||||
|
|
||||||
#include "Router.h"
|
#include "Router.h"
|
||||||
|
|
||||||
MeshService::MeshService() : toPhoneQueue(MAX_RX_TOPHONE), toPhoneQueueStatusQueue(MAX_RX_TOPHONE)
|
MeshService::MeshService()
|
||||||
|
: toPhoneQueue(MAX_RX_TOPHONE), toPhoneQueueStatusQueue(MAX_RX_TOPHONE), toPhoneMqttProxyQueue(MAX_RX_TOPHONE)
|
||||||
{
|
{
|
||||||
lastQueueStatus = {0, 0, 16, 0};
|
lastQueueStatus = {0, 0, 16, 0};
|
||||||
}
|
}
|
||||||
@@ -269,6 +274,20 @@ void MeshService::sendToPhone(meshtastic_MeshPacket *p)
|
|||||||
fromNum++;
|
fromNum++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MeshService::sendMqttMessageToClientProxy(meshtastic_MqttClientProxyMessage *m)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("Sending mqtt message on topic '%s' to client for proxying to server\n", m->topic);
|
||||||
|
if (toPhoneMqttProxyQueue.numFree() == 0) {
|
||||||
|
LOG_WARN("MqttClientProxyMessagePool queue is full, discarding oldest\n");
|
||||||
|
meshtastic_MqttClientProxyMessage *d = toPhoneMqttProxyQueue.dequeuePtr(0);
|
||||||
|
if (d)
|
||||||
|
releaseMqttClientProxyMessageToPool(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(toPhoneMqttProxyQueue.enqueue(m, 0));
|
||||||
|
fromNum++;
|
||||||
|
}
|
||||||
|
|
||||||
meshtastic_NodeInfoLite *MeshService::refreshLocalMeshNode()
|
meshtastic_NodeInfoLite *MeshService::refreshLocalMeshNode()
|
||||||
{
|
{
|
||||||
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
|
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
|
||||||
|
|||||||
+14
-1
@@ -15,6 +15,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern Allocator<meshtastic_QueueStatus> &queueStatusPool;
|
extern Allocator<meshtastic_QueueStatus> &queueStatusPool;
|
||||||
|
extern Allocator<meshtastic_MqttClientProxyMessage> &mqttClientProxyMessagePool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Top level app for this service. keeps the mesh, the radio config and the queue of received packets.
|
* Top level app for this service. keeps the mesh, the radio config and the queue of received packets.
|
||||||
@@ -34,6 +35,9 @@ class MeshService
|
|||||||
// keep list of QueueStatus packets to be send to the phone
|
// keep list of QueueStatus packets to be send to the phone
|
||||||
PointerQueue<meshtastic_QueueStatus> toPhoneQueueStatusQueue;
|
PointerQueue<meshtastic_QueueStatus> toPhoneQueueStatusQueue;
|
||||||
|
|
||||||
|
// keep list of MqttClientProxyMessages to be send to the client for delivery
|
||||||
|
PointerQueue<meshtastic_MqttClientProxyMessage> toPhoneMqttProxyQueue;
|
||||||
|
|
||||||
// This holds the last QueueStatus send
|
// This holds the last QueueStatus send
|
||||||
meshtastic_QueueStatus lastQueueStatus;
|
meshtastic_QueueStatus lastQueueStatus;
|
||||||
|
|
||||||
@@ -67,9 +71,15 @@ class MeshService
|
|||||||
/// Return the next QueueStatus packet destined to the phone.
|
/// Return the next QueueStatus packet destined to the phone.
|
||||||
meshtastic_QueueStatus *getQueueStatusForPhone() { return toPhoneQueueStatusQueue.dequeuePtr(0); }
|
meshtastic_QueueStatus *getQueueStatusForPhone() { return toPhoneQueueStatusQueue.dequeuePtr(0); }
|
||||||
|
|
||||||
|
/// Return the next MqttClientProxyMessage packet destined to the phone.
|
||||||
|
meshtastic_MqttClientProxyMessage *getMqttClientProxyMessageForPhone() { return toPhoneMqttProxyQueue.dequeuePtr(0); }
|
||||||
|
|
||||||
// Release QueueStatus packet to pool
|
// Release QueueStatus packet to pool
|
||||||
void releaseQueueStatusToPool(meshtastic_QueueStatus *p) { queueStatusPool.release(p); }
|
void releaseQueueStatusToPool(meshtastic_QueueStatus *p) { queueStatusPool.release(p); }
|
||||||
|
|
||||||
|
// Release MqttClientProxyMessage packet to pool
|
||||||
|
void releaseMqttClientProxyMessageToPool(meshtastic_MqttClientProxyMessage *p) { mqttClientProxyMessagePool.release(p); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a ToRadio buffer parse it and properly handle it (setup radio, owner or send packet into the mesh)
|
* Given a ToRadio buffer parse it and properly handle it (setup radio, owner or send packet into the mesh)
|
||||||
* Called by PhoneAPI.handleToRadio. Note: p is a scratch buffer, this function is allowed to write to it but it can not keep
|
* Called by PhoneAPI.handleToRadio. Note: p is a scratch buffer, this function is allowed to write to it but it can not keep
|
||||||
@@ -103,11 +113,14 @@ class MeshService
|
|||||||
/// Send a packet to the phone
|
/// Send a packet to the phone
|
||||||
void sendToPhone(meshtastic_MeshPacket *p);
|
void sendToPhone(meshtastic_MeshPacket *p);
|
||||||
|
|
||||||
|
/// Send an MQTT message to the phone for client proxying
|
||||||
|
void sendMqttMessageToClientProxy(meshtastic_MqttClientProxyMessage *m);
|
||||||
|
|
||||||
bool isToPhoneQueueEmpty();
|
bool isToPhoneQueueEmpty();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Called when our gps position has changed - updates nodedb and sends Location message out into the mesh
|
/// Called when our gps position has changed - updates nodedb and sends Location message out into the mesh
|
||||||
/// returns 0 to allow futher processing
|
/// returns 0 to allow further processing
|
||||||
int onGPSChanged(const meshtastic::GPSStatus *arg);
|
int onGPSChanged(const meshtastic::GPSStatus *arg);
|
||||||
|
|
||||||
/// Handle a packet that just arrived from the radio. This method does _ReliableRouternot_ free the provided packet. If it
|
/// Handle a packet that just arrived from the radio. This method does _ReliableRouternot_ free the provided packet. If it
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ typedef uint32_t PacketId; // A packet sequence number
|
|||||||
#define ERRNO_OK 0
|
#define ERRNO_OK 0
|
||||||
#define ERRNO_NO_INTERFACES 33
|
#define ERRNO_NO_INTERFACES 33
|
||||||
#define ERRNO_UNKNOWN 32 // pick something that doesn't conflict with RH_ROUTER_ERROR_UNABLE_TO_DELIVER
|
#define ERRNO_UNKNOWN 32 // pick something that doesn't conflict with RH_ROUTER_ERROR_UNABLE_TO_DELIVER
|
||||||
#define ERRNO_DISABLED 34 // the itnerface is disabled
|
#define ERRNO_DISABLED 34 // the interface is disabled
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Source of a received message
|
* Source of a received message
|
||||||
|
|||||||
+15
-5
@@ -138,7 +138,7 @@ bool NodeDB::factoryReset()
|
|||||||
// third, write everything to disk
|
// third, write everything to disk
|
||||||
saveToDisk();
|
saveToDisk();
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
// This will erase what's in NVS including ssl keys, persistant variables and ble pairing
|
// This will erase what's in NVS including ssl keys, persistent variables and ble pairing
|
||||||
nvs_flash_erase();
|
nvs_flash_erase();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ARCH_NRF52
|
#ifdef ARCH_NRF52
|
||||||
@@ -165,7 +165,8 @@ void NodeDB::installDefaultConfig()
|
|||||||
config.has_network = true;
|
config.has_network = true;
|
||||||
config.has_bluetooth = true;
|
config.has_bluetooth = true;
|
||||||
config.device.rebroadcast_mode = meshtastic_Config_DeviceConfig_RebroadcastMode_ALL;
|
config.device.rebroadcast_mode = meshtastic_Config_DeviceConfig_RebroadcastMode_ALL;
|
||||||
config.lora.sx126x_rx_boosted_gain = false;
|
|
||||||
|
config.lora.sx126x_rx_boosted_gain = true;
|
||||||
config.lora.tx_enabled =
|
config.lora.tx_enabled =
|
||||||
true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off)
|
true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off)
|
||||||
config.lora.override_duty_cycle = false;
|
config.lora.override_duty_cycle = false;
|
||||||
@@ -184,7 +185,7 @@ void NodeDB::installDefaultConfig()
|
|||||||
// FIXME: Default to bluetooth capability of platform as default
|
// FIXME: Default to bluetooth capability of platform as default
|
||||||
config.bluetooth.enabled = true;
|
config.bluetooth.enabled = true;
|
||||||
config.bluetooth.fixed_pin = defaultBLEPin;
|
config.bluetooth.fixed_pin = defaultBLEPin;
|
||||||
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER)
|
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7789_CS)
|
||||||
bool hasScreen = true;
|
bool hasScreen = true;
|
||||||
#else
|
#else
|
||||||
bool hasScreen = screen_found.port != ScanI2C::I2CPort::NO_I2C;
|
bool hasScreen = screen_found.port != ScanI2C::I2CPort::NO_I2C;
|
||||||
@@ -195,6 +196,11 @@ void NodeDB::installDefaultConfig()
|
|||||||
config.position.position_flags =
|
config.position.position_flags =
|
||||||
(meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE_MSL);
|
(meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE_MSL);
|
||||||
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
config.display.screen_on_secs = 30;
|
||||||
|
config.display.wake_on_tap_or_motion = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
initConfigIntervals();
|
initConfigIntervals();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,6 +239,10 @@ void NodeDB::installDefaultModuleConfig()
|
|||||||
moduleConfig.external_notification.alert_message = true;
|
moduleConfig.external_notification.alert_message = true;
|
||||||
moduleConfig.external_notification.output_ms = 1000;
|
moduleConfig.external_notification.output_ms = 1000;
|
||||||
moduleConfig.external_notification.nag_timeout = 60;
|
moduleConfig.external_notification.nag_timeout = 60;
|
||||||
|
#endif
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
// Don't worry about the other settings, we'll use the DRV2056 behavior for notifications
|
||||||
|
moduleConfig.external_notification.enabled = true;
|
||||||
#endif
|
#endif
|
||||||
moduleConfig.has_canned_message = true;
|
moduleConfig.has_canned_message = true;
|
||||||
|
|
||||||
@@ -911,9 +921,9 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
|
|||||||
error_code = code;
|
error_code = code;
|
||||||
error_address = address;
|
error_address = address;
|
||||||
|
|
||||||
// Currently portuino is mostly used for simulation. Make sue the user notices something really bad happend
|
// Currently portuino is mostly used for simulation. Make sure the user notices something really bad happened
|
||||||
#ifdef ARCH_PORTDUINO
|
#ifdef ARCH_PORTDUINO
|
||||||
LOG_ERROR("A critical failure occurred, portduino is exiting...");
|
LOG_ERROR("A critical failure occurred, portduino is exiting...");
|
||||||
exit(2);
|
exit(2);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
+2
-2
@@ -56,7 +56,7 @@ class NodeDB
|
|||||||
meshtastic_NodeInfoLite *updateGUIforNode = NULL; // if currently showing this node, we think you should update the GUI
|
meshtastic_NodeInfoLite *updateGUIforNode = NULL; // if currently showing this node, we think you should update the GUI
|
||||||
Observable<const meshtastic::NodeStatus *> newStatus;
|
Observable<const meshtastic::NodeStatus *> newStatus;
|
||||||
|
|
||||||
/// don't do mesh based algoritm for node id assignment (initially)
|
/// don't do mesh based algorithm for node id assignment (initially)
|
||||||
/// instead just store in flash - possibly even in the initial alpha release do this hack
|
/// instead just store in flash - possibly even in the initial alpha release do this hack
|
||||||
NodeDB();
|
NodeDB();
|
||||||
|
|
||||||
@@ -252,4 +252,4 @@ extern uint32_t error_address;
|
|||||||
#define Module_Config_size \
|
#define Module_Config_size \
|
||||||
(ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + \
|
(ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + \
|
||||||
ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + \
|
ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + \
|
||||||
ModuleConfig_TelemetryConfig_size + ModuleConfig_size)
|
ModuleConfig_TelemetryConfig_size + ModuleConfig_size)
|
||||||
|
|||||||
+25
-2
@@ -18,6 +18,8 @@
|
|||||||
#error ToRadio is too big
|
#error ToRadio is too big
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "mqtt/MQTT.h"
|
||||||
|
|
||||||
PhoneAPI::PhoneAPI()
|
PhoneAPI::PhoneAPI()
|
||||||
{
|
{
|
||||||
lastContactMsec = millis();
|
lastContactMsec = millis();
|
||||||
@@ -54,6 +56,7 @@ void PhoneAPI::close()
|
|||||||
unobserve(&xModem.packetReady);
|
unobserve(&xModem.packetReady);
|
||||||
releasePhonePacket(); // Don't leak phone packets on shutdown
|
releasePhonePacket(); // Don't leak phone packets on shutdown
|
||||||
releaseQueueStatusPhonePacket();
|
releaseQueueStatusPhonePacket();
|
||||||
|
releaseMqttClientProxyPhonePacket();
|
||||||
|
|
||||||
onConnectionChanged(false);
|
onConnectionChanged(false);
|
||||||
}
|
}
|
||||||
@@ -98,6 +101,12 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength)
|
|||||||
LOG_INFO("Got xmodem packet\n");
|
LOG_INFO("Got xmodem packet\n");
|
||||||
xModem.handlePacket(toRadioScratch.xmodemPacket);
|
xModem.handlePacket(toRadioScratch.xmodemPacket);
|
||||||
break;
|
break;
|
||||||
|
case meshtastic_ToRadio_mqttClientProxyMessage_tag:
|
||||||
|
LOG_INFO("Got MqttClientProxy message\n");
|
||||||
|
if (mqtt && moduleConfig.mqtt.proxy_to_client_enabled) {
|
||||||
|
mqtt->onClientProxyReceive(toRadioScratch.mqttClientProxyMessage);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// Ignore nop messages
|
// Ignore nop messages
|
||||||
// LOG_DEBUG("Error: unexpected ToRadio variant\n");
|
// LOG_DEBUG("Error: unexpected ToRadio variant\n");
|
||||||
@@ -295,12 +304,16 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_SEND_PACKETS:
|
case STATE_SEND_PACKETS:
|
||||||
// Do we have a message from the mesh?
|
// Do we have a message from the mesh or packet from the local device?
|
||||||
LOG_INFO("getFromRadio=STATE_SEND_PACKETS\n");
|
LOG_INFO("getFromRadio=STATE_SEND_PACKETS\n");
|
||||||
if (queueStatusPacketForPhone) {
|
if (queueStatusPacketForPhone) {
|
||||||
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_queueStatus_tag;
|
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_queueStatus_tag;
|
||||||
fromRadioScratch.queueStatus = *queueStatusPacketForPhone;
|
fromRadioScratch.queueStatus = *queueStatusPacketForPhone;
|
||||||
releaseQueueStatusPhonePacket();
|
releaseQueueStatusPhonePacket();
|
||||||
|
} else if (mqttClientProxyMessageForPhone) {
|
||||||
|
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_mqttClientProxyMessage_tag;
|
||||||
|
fromRadioScratch.mqttClientProxyMessage = *mqttClientProxyMessageForPhone;
|
||||||
|
releaseMqttClientProxyPhonePacket();
|
||||||
} else if (xmodemPacketForPhone.control != meshtastic_XModem_Control_NUL) {
|
} else if (xmodemPacketForPhone.control != meshtastic_XModem_Control_NUL) {
|
||||||
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_xmodemPacket_tag;
|
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_xmodemPacket_tag;
|
||||||
fromRadioScratch.xmodemPacket = xmodemPacketForPhone;
|
fromRadioScratch.xmodemPacket = xmodemPacketForPhone;
|
||||||
@@ -353,6 +366,14 @@ void PhoneAPI::releaseQueueStatusPhonePacket()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhoneAPI::releaseMqttClientProxyPhonePacket()
|
||||||
|
{
|
||||||
|
if (mqttClientProxyMessageForPhone) {
|
||||||
|
service.releaseMqttClientProxyMessageToPool(mqttClientProxyMessageForPhone);
|
||||||
|
mqttClientProxyMessageForPhone = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if we have data available to send to the phone
|
* Return true if we have data available to send to the phone
|
||||||
*/
|
*/
|
||||||
@@ -381,7 +402,9 @@ bool PhoneAPI::available()
|
|||||||
case STATE_SEND_PACKETS: {
|
case STATE_SEND_PACKETS: {
|
||||||
if (!queueStatusPacketForPhone)
|
if (!queueStatusPacketForPhone)
|
||||||
queueStatusPacketForPhone = service.getQueueStatusForPhone();
|
queueStatusPacketForPhone = service.getQueueStatusForPhone();
|
||||||
bool hasPacket = !!queueStatusPacketForPhone;
|
if (!mqttClientProxyMessageForPhone)
|
||||||
|
mqttClientProxyMessageForPhone = service.getMqttClientProxyMessageForPhone();
|
||||||
|
bool hasPacket = !!queueStatusPacketForPhone || !!mqttClientProxyMessageForPhone;
|
||||||
if (hasPacket)
|
if (hasPacket)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,9 @@ class PhoneAPI
|
|||||||
// Keep QueueStatus packet just as packetForPhone
|
// Keep QueueStatus packet just as packetForPhone
|
||||||
meshtastic_QueueStatus *queueStatusPacketForPhone = NULL;
|
meshtastic_QueueStatus *queueStatusPacketForPhone = NULL;
|
||||||
|
|
||||||
|
// Keep MqttClientProxyMessage packet just as packetForPhone
|
||||||
|
meshtastic_MqttClientProxyMessage *mqttClientProxyMessageForPhone = NULL;
|
||||||
|
|
||||||
/// We temporarily keep the nodeInfo here between the call to available and getFromRadio
|
/// We temporarily keep the nodeInfo here between the call to available and getFromRadio
|
||||||
meshtastic_NodeInfo nodeInfoForPhone = meshtastic_NodeInfo_init_default;
|
meshtastic_NodeInfo nodeInfoForPhone = meshtastic_NodeInfo_init_default;
|
||||||
|
|
||||||
@@ -126,6 +129,8 @@ class PhoneAPI
|
|||||||
|
|
||||||
void releaseQueueStatusPhonePacket();
|
void releaseQueueStatusPhonePacket();
|
||||||
|
|
||||||
|
void releaseMqttClientProxyPhonePacket();
|
||||||
|
|
||||||
/// begin a new connection
|
/// begin a new connection
|
||||||
void handleStartConfig();
|
void handleStartConfig();
|
||||||
|
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ bool RF95Interface::isChannelActive()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
/** Could we send right now (i.e. either not actively receiving or transmitting)? */
|
||||||
bool RF95Interface::isActivelyReceiving()
|
bool RF95Interface::isActivelyReceiving()
|
||||||
{
|
{
|
||||||
return lora->isReceiving();
|
return lora->isReceiving();
|
||||||
@@ -201,7 +201,7 @@ bool RF95Interface::isActivelyReceiving()
|
|||||||
bool RF95Interface::sleep()
|
bool RF95Interface::sleep()
|
||||||
{
|
{
|
||||||
// put chipset into sleep mode
|
// put chipset into sleep mode
|
||||||
setStandby(); // First cancel any active receving/sending
|
setStandby(); // First cancel any active receiving/sending
|
||||||
lora->sleep();
|
lora->sleep();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -196,8 +196,9 @@ uint32_t RadioInterface::getRetransmissionMsec(const meshtastic_MeshPacket *p)
|
|||||||
// LOG_DEBUG("Waiting for flooding message with airtime %d and slotTime is %d\n", packetAirtime, slotTimeMsec);
|
// LOG_DEBUG("Waiting for flooding message with airtime %d and slotTime is %d\n", packetAirtime, slotTimeMsec);
|
||||||
float channelUtil = airTime->channelUtilizationPercent();
|
float channelUtil = airTime->channelUtilizationPercent();
|
||||||
uint8_t CWsize = map(channelUtil, 0, 100, CWmin, CWmax);
|
uint8_t CWsize = map(channelUtil, 0, 100, CWmin, CWmax);
|
||||||
// Assuming we pick max. of CWsize and there will be a receiver with SNR at half the range
|
// Assuming we pick max. of CWsize and there will be a client with SNR at half the range
|
||||||
return 2 * packetAirtime + (pow(2, CWsize) + pow(2, int((CWmax + CWmin) / 2))) * slotTimeMsec + PROCESSING_TIME_MSEC;
|
return 2 * packetAirtime + (pow(2, CWsize) + 2 * CWmax + pow(2, int((CWmax + CWmin) / 2))) * slotTimeMsec +
|
||||||
|
PROCESSING_TIME_MSEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The delay to use when we want to send something */
|
/** The delay to use when we want to send something */
|
||||||
@@ -307,7 +308,7 @@ bool RadioInterface::init()
|
|||||||
preflightSleepObserver.observe(&preflightSleep);
|
preflightSleepObserver.observe(&preflightSleep);
|
||||||
notifyDeepSleepObserver.observe(¬ifyDeepSleep);
|
notifyDeepSleepObserver.observe(¬ifyDeepSleep);
|
||||||
|
|
||||||
// we now expect interfaces to operate in promiscous mode
|
// we now expect interfaces to operate in promiscuous mode
|
||||||
// radioIf.setThisAddress(nodeDB.getNodeNum()); // Note: we must do this here, because the nodenum isn't inited at constructor
|
// radioIf.setThisAddress(nodeDB.getNodeNum()); // Note: we must do this here, because the nodenum isn't inited at constructor
|
||||||
// time.
|
// time.
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This structure has to exactly match the wire layout when sent over the radio link. Used to keep compatibility
|
* This structure has to exactly match the wire layout when sent over the radio link. Used to keep compatibility
|
||||||
* wtih the old radiohead implementation.
|
* with the old radiohead implementation.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NodeNum to, from; // can be 1 byte or four bytes
|
NodeNum to, from; // can be 1 byte or four bytes
|
||||||
@@ -75,7 +75,7 @@ class RadioInterface
|
|||||||
uint32_t lastTxStart = 0L;
|
uint32_t lastTxStart = 0L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A temporary buffer used for sending/receving packets, sized to hold the biggest buffer we might need
|
* A temporary buffer used for sending/receiving packets, sized to hold the biggest buffer we might need
|
||||||
* */
|
* */
|
||||||
uint8_t radiobuf[MAX_RHPACKETLEN];
|
uint8_t radiobuf[MAX_RHPACKETLEN];
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ class RadioInterface
|
|||||||
virtual void saveFreq(float savedFreq);
|
virtual void saveFreq(float savedFreq);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the chanel we selected for later reuse.
|
* Save the channel we selected for later reuse.
|
||||||
*/
|
*/
|
||||||
virtual void saveChannelNum(uint32_t savedChannelNum);
|
virtual void saveChannelNum(uint32_t savedChannelNum);
|
||||||
|
|
||||||
@@ -206,7 +206,7 @@ class RadioInterface
|
|||||||
/**
|
/**
|
||||||
* Convert our modemConfig enum into wf, sf, etc...
|
* Convert our modemConfig enum into wf, sf, etc...
|
||||||
*
|
*
|
||||||
* These paramaters will be pull from the channelSettings global
|
* These parameters will be pull from the channelSettings global
|
||||||
*/
|
*/
|
||||||
void applyModemConfig();
|
void applyModemConfig();
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ void INTERRUPT_ATTR RadioLibInterface::isrTxLevel0()
|
|||||||
*/
|
*/
|
||||||
RadioLibInterface *RadioLibInterface::instance;
|
RadioLibInterface *RadioLibInterface::instance;
|
||||||
|
|
||||||
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
/** Could we send right now (i.e. either not actively receiving or transmitting)? */
|
||||||
bool RadioLibInterface::canSendImmediately()
|
bool RadioLibInterface::canSendImmediately()
|
||||||
{
|
{
|
||||||
// We wait _if_ we are partially though receiving a packet (rather than just merely waiting for one).
|
// We wait _if_ we are partially though receiving a packet (rather than just merely waiting for one).
|
||||||
|
|||||||
+1
-7
@@ -12,9 +12,7 @@ extern "C" {
|
|||||||
#include "mesh/compression/unishox2.h"
|
#include "mesh/compression/unishox2.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAS_WIFI || HAS_ETHERNET
|
|
||||||
#include "mqtt/MQTT.h"
|
#include "mqtt/MQTT.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Router todo
|
* Router todo
|
||||||
@@ -248,7 +246,6 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
|
|||||||
|
|
||||||
bool shouldActuallyEncrypt = true;
|
bool shouldActuallyEncrypt = true;
|
||||||
|
|
||||||
#if HAS_WIFI || HAS_ETHERNET
|
|
||||||
if (moduleConfig.mqtt.enabled) {
|
if (moduleConfig.mqtt.enabled) {
|
||||||
// check if we should send decrypted packets to mqtt
|
// check if we should send decrypted packets to mqtt
|
||||||
|
|
||||||
@@ -272,7 +269,6 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
|
|||||||
if (mqtt && !shouldActuallyEncrypt)
|
if (mqtt && !shouldActuallyEncrypt)
|
||||||
mqtt->onSend(*p, chIndex);
|
mqtt->onSend(*p, chIndex);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
auto encodeResult = perhapsEncode(p);
|
auto encodeResult = perhapsEncode(p);
|
||||||
if (encodeResult != meshtastic_Routing_Error_NONE) {
|
if (encodeResult != meshtastic_Routing_Error_NONE) {
|
||||||
@@ -280,14 +276,12 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
|
|||||||
return encodeResult; // FIXME - this isn't a valid ErrorCode
|
return encodeResult; // FIXME - this isn't a valid ErrorCode
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAS_WIFI || HAS_ETHERNET
|
|
||||||
if (moduleConfig.mqtt.enabled) {
|
if (moduleConfig.mqtt.enabled) {
|
||||||
// the packet is now encrypted.
|
// the packet is now encrypted.
|
||||||
// check if we should send encrypted packets to mqtt
|
// check if we should send encrypted packets to mqtt
|
||||||
if (mqtt && shouldActuallyEncrypt)
|
if (mqtt && shouldActuallyEncrypt)
|
||||||
mqtt->onSend(*p, chIndex);
|
mqtt->onSend(*p, chIndex);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(iface); // This should have been detected already in sendLocal (or we just received a packet from outside)
|
assert(iface); // This should have been detected already in sendLocal (or we just received a packet from outside)
|
||||||
@@ -405,7 +399,7 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p)
|
|||||||
if (compressed_len >= p->decoded.payload.size) {
|
if (compressed_len >= p->decoded.payload.size) {
|
||||||
|
|
||||||
LOG_DEBUG("Not using compressing message.\n");
|
LOG_DEBUG("Not using compressing message.\n");
|
||||||
// Set the uncompressed payload varient anyway. Shouldn't hurt?
|
// Set the uncompressed payload variant anyway. Shouldn't hurt?
|
||||||
// p->decoded.which_payloadVariant = Data_payload_tag;
|
// p->decoded.which_payloadVariant = Data_payload_tag;
|
||||||
|
|
||||||
// Otherwise we use the compressor
|
// Otherwise we use the compressor
|
||||||
|
|||||||
+1
-1
@@ -90,7 +90,7 @@ class Router : protected concurrency::OSThread
|
|||||||
*
|
*
|
||||||
* FIXME, move this into the new RoutingModule and do the filtering there using the regular module logic
|
* FIXME, move this into the new RoutingModule and do the filtering there using the regular module logic
|
||||||
*
|
*
|
||||||
* Called immedately on receiption, before any further processing.
|
* Called immediately on reception, before any further processing.
|
||||||
* @return true to abandon the packet
|
* @return true to abandon the packet
|
||||||
*/
|
*/
|
||||||
virtual bool shouldFilterReceived(const meshtastic_MeshPacket *p) { return false; }
|
virtual bool shouldFilterReceived(const meshtastic_MeshPacket *p) { return false; }
|
||||||
|
|||||||
@@ -70,12 +70,25 @@ template <typename T> bool SX126xInterface<T>::init()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SX126X_TXEN) && (SX126X_TXEN != RADIOLIB_NC)
|
#if defined(SX126X_TXEN) && (SX126X_TXEN != RADIOLIB_NC)
|
||||||
// lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX
|
// If SX126X_TXEN is connected to the MCU, we are manually controlling RX and TX.
|
||||||
|
// But lora.begin (called above) sets Dio2 as RF switch control, which is not true here, so set it back to false.
|
||||||
if (res == RADIOLIB_ERR_NONE) {
|
if (res == RADIOLIB_ERR_NONE) {
|
||||||
LOG_DEBUG("SX126X_TX/RX EN pins defined. Setting RF Switch: RXEN=%i, TXEN=%i\n", SX126X_RXEN, SX126X_TXEN);
|
LOG_DEBUG("SX126X_TXEN pin defined. Setting RF Switch: RXEN=%i, TXEN=%i\n", SX126X_RXEN, SX126X_TXEN);
|
||||||
res = lora.setDio2AsRfSwitch(false);
|
res = lora.setDio2AsRfSwitch(false);
|
||||||
lora.setRfSwitchPins(SX126X_RXEN, SX126X_TXEN);
|
lora.setRfSwitchPins(SX126X_RXEN, SX126X_TXEN);
|
||||||
}
|
}
|
||||||
|
#elif defined(SX126X_RXEN) && (SX126X_RXEN != RADIOLIB_NC && defined(E22_TXEN_CONNECTED_TO_DIO2))
|
||||||
|
// Otherwise, if SX126X_RXEN is connected to the MCU, and E22_TXEN_CONNECTED_TO_DIO2 is defined, we are letting the
|
||||||
|
// E22 control RX and TX via DIO2. In this configuration, the E22's TXEN and DIO2 pins are connected to each other,
|
||||||
|
// but not to the MCU.
|
||||||
|
// However, we must still connect the E22's RXEN pin to the MCU, define SX126X_RXEN accordingly, and then call
|
||||||
|
// setRfSwitchPins, otherwise RX sensitivity (observed via RSSI) is greatly diminished.
|
||||||
|
LOG_DEBUG("SX126X_RXEN and E22_TXEN_CONNECTED_TO_DIO2 are defined; value of res: %d", res);
|
||||||
|
if (res == RADIOLIB_ERR_NONE) {
|
||||||
|
LOG_DEBUG("SX126X_TXEN is RADIOLIB_NC, but SX126X_RXEN and E22_TXEN_CONNECTED_TO_DIO2 are both defined; calling "
|
||||||
|
"lora.setRfSwitchPins.");
|
||||||
|
lora.setRfSwitchPins(SX126X_RXEN, SX126X_TXEN);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (config.lora.sx126x_rx_boosted_gain) {
|
if (config.lora.sx126x_rx_boosted_gain) {
|
||||||
@@ -249,7 +262,7 @@ template <typename T> bool SX126xInterface<T>::isChannelActive()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
/** Could we send right now (i.e. either not actively receiving or transmitting)? */
|
||||||
template <typename T> bool SX126xInterface<T>::isActivelyReceiving()
|
template <typename T> bool SX126xInterface<T>::isActivelyReceiving()
|
||||||
{
|
{
|
||||||
// The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet
|
// The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet
|
||||||
@@ -299,4 +312,4 @@ template <typename T> bool SX126xInterface<T>::sleep()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -242,7 +242,7 @@ template <typename T> bool SX128xInterface<T>::isChannelActive()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
/** Could we send right now (i.e. either not actively receiving or transmitting)? */
|
||||||
template <typename T> bool SX128xInterface<T>::isActivelyReceiving()
|
template <typename T> bool SX128xInterface<T>::isActivelyReceiving()
|
||||||
{
|
{
|
||||||
uint16_t irq = lora.getIrqStatus();
|
uint16_t irq = lora.getIrqStatus();
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include "Router.h"
|
#include "Router.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Most modules are only interested in sending/receving one particular portnum. This baseclass simplifies that common
|
* Most modules are only interested in sending/receiving one particular portnum. This baseclass simplifies that common
|
||||||
* case.
|
* case.
|
||||||
*/
|
*/
|
||||||
class SinglePortModule : public MeshModule
|
class SinglePortModule : public MeshModule
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ uint8_t usx_code_94[94];
|
|||||||
uint8_t usx_vcodes[] = {0x00, 0x40, 0x60, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xD8, 0xE0, 0xE4, 0xE8, 0xEC,
|
uint8_t usx_vcodes[] = {0x00, 0x40, 0x60, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xD8, 0xE0, 0xE4, 0xE8, 0xEC,
|
||||||
0xEE, 0xF0, 0xF2, 0xF4, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF};
|
0xEE, 0xF0, 0xF2, 0xF4, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF};
|
||||||
|
|
||||||
/// Length of each veritical code
|
/// Length of each vertical code
|
||||||
uint8_t usx_vcode_lens[] = {2, 3, 3, 4, 4, 4, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
|
uint8_t usx_vcode_lens[] = {2, 3, 3, 4, 4, 4, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
|
||||||
|
|
||||||
/// Vertical Codes and Set number for frequent sequences in sets USX_SYM and USX_NUM. First 3 bits indicate set (USX_SYM/USX_NUM)
|
/// Vertical Codes and Set number for frequent sequences in sets USX_SYM and USX_NUM. First 3 bits indicate set (USX_SYM/USX_NUM)
|
||||||
@@ -188,7 +188,7 @@ int append_switch_code(char *out, int olen, int ol, uint8_t state)
|
|||||||
return ol;
|
return ol;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Appends given horizontal and veritical code bits to out
|
/// Appends given horizontal and vertical code bits to out
|
||||||
int append_code(char *out, int olen, int ol, uint8_t code, uint8_t *state, const uint8_t usx_hcodes[],
|
int append_code(char *out, int olen, int ol, uint8_t code, uint8_t *state, const uint8_t usx_hcodes[],
|
||||||
const uint8_t usx_hcode_lens[])
|
const uint8_t usx_hcode_lens[])
|
||||||
{
|
{
|
||||||
@@ -888,7 +888,7 @@ int read8bitCode(const char *in, int len, int bit_no)
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The list of veritical codes is split into 5 sections. Used by readVCodeIdx()
|
/// The list of vertical codes is split into 5 sections. Used by readVCodeIdx()
|
||||||
#define SECTION_COUNT 5
|
#define SECTION_COUNT 5
|
||||||
/// Used by readVCodeIdx() for finding the section under which the code read using read8bitCode() falls
|
/// Used by readVCodeIdx() for finding the section under which the code read using read8bitCode() falls
|
||||||
uint8_t usx_vsections[] = {0x7F, 0xBF, 0xDF, 0xEF, 0xFF};
|
uint8_t usx_vsections[] = {0x7F, 0xBF, 0xDF, 0xEF, 0xFF};
|
||||||
@@ -915,7 +915,7 @@ uint8_t usx_vcode_lookup[36] = {(1 << 5) + 0, (1 << 5) + 0, (2 << 5) + 1, (2
|
|||||||
/// compared to using a 256 uint8_t buffer to decode the next 8 bits read by read8bitCode() \n
|
/// compared to using a 256 uint8_t buffer to decode the next 8 bits read by read8bitCode() \n
|
||||||
/// by splitting the list of vertical codes. \n
|
/// by splitting the list of vertical codes. \n
|
||||||
/// Decoder is designed for using less memory, not speed. \n
|
/// Decoder is designed for using less memory, not speed. \n
|
||||||
/// Returns the veritical code index or 99 if match could not be found. \n
|
/// Returns the vertical code index or 99 if match could not be found. \n
|
||||||
/// Also updates bit_no_p with how many ever bits used by the vertical code.
|
/// Also updates bit_no_p with how many ever bits used by the vertical code.
|
||||||
int readVCodeIdx(const char *in, int len, int *bit_no_p)
|
int readVCodeIdx(const char *in, int len, int *bit_no_p)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -198,45 +198,45 @@
|
|||||||
2, 2, 2, 2, 0 \
|
2, 2, 2, 2, 0 \
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Default frequently occuring sequences. When composition of text is know beforehand, the other sequences in this section can be
|
/// Default frequently occurring sequences. When composition of text is know beforehand, the other sequences in this section can
|
||||||
/// used to achieve more compression.
|
/// be used to achieve more compression.
|
||||||
#define USX_FREQ_SEQ_DFLT \
|
#define USX_FREQ_SEQ_DFLT \
|
||||||
(const char *[]) \
|
(const char *[]) \
|
||||||
{ \
|
{ \
|
||||||
"\": \"", "\": ", "</", "=\"", "\":\"", "://" \
|
"\": \"", "\": ", "</", "=\"", "\":\"", "://" \
|
||||||
}
|
}
|
||||||
/// Frequently occuring sequences in text content
|
/// Frequently occurring sequences in text content
|
||||||
#define USX_FREQ_SEQ_TXT \
|
#define USX_FREQ_SEQ_TXT \
|
||||||
(const char *[]) \
|
(const char *[]) \
|
||||||
{ \
|
{ \
|
||||||
" the ", " and ", "tion", " with", "ing", "ment" \
|
" the ", " and ", "tion", " with", "ing", "ment" \
|
||||||
}
|
}
|
||||||
/// Frequently occuring sequences in URL content
|
/// Frequently occurring sequences in URL content
|
||||||
#define USX_FREQ_SEQ_URL \
|
#define USX_FREQ_SEQ_URL \
|
||||||
(const char *[]) \
|
(const char *[]) \
|
||||||
{ \
|
{ \
|
||||||
"https://", "www.", ".com", "http://", ".org", ".net" \
|
"https://", "www.", ".com", "http://", ".org", ".net" \
|
||||||
}
|
}
|
||||||
/// Frequently occuring sequences in JSON content
|
/// Frequently occurring sequences in JSON content
|
||||||
#define USX_FREQ_SEQ_JSON \
|
#define USX_FREQ_SEQ_JSON \
|
||||||
(const char *[]) \
|
(const char *[]) \
|
||||||
{ \
|
{ \
|
||||||
"\": \"", "\": ", "\",", "}}}", "\":\"", "}}" \
|
"\": \"", "\": ", "\",", "}}}", "\":\"", "}}" \
|
||||||
}
|
}
|
||||||
/// Frequently occuring sequences in HTML content
|
/// Frequently occurring sequences in HTML content
|
||||||
#define USX_FREQ_SEQ_HTML \
|
#define USX_FREQ_SEQ_HTML \
|
||||||
(const char *[]) \
|
(const char *[]) \
|
||||||
{ \
|
{ \
|
||||||
"</", "=\"", "div", "href", "class", "<p>" \
|
"</", "=\"", "div", "href", "class", "<p>" \
|
||||||
}
|
}
|
||||||
/// Frequently occuring sequences in XML content
|
/// Frequently occurring sequences in XML content
|
||||||
#define USX_FREQ_SEQ_XML \
|
#define USX_FREQ_SEQ_XML \
|
||||||
(const char *[]) \
|
(const char *[]) \
|
||||||
{ \
|
{ \
|
||||||
"</", "=\"", "\">", "<?xml version=\"1.0\"", "xmlns:", "://" \
|
"</", "=\"", "\">", "<?xml version=\"1.0\"", "xmlns:", "://" \
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Commonly occuring templates (ISO Date/Time, ISO Date, US Phone number, ISO Time, Unused)
|
/// Commonly occurring templates (ISO Date/Time, ISO Date, US Phone number, ISO Time, Unused)
|
||||||
#define USX_TEMPLATES \
|
#define USX_TEMPLATES \
|
||||||
(const char *[]) \
|
(const char *[]) \
|
||||||
{ \
|
{ \
|
||||||
@@ -333,8 +333,8 @@ extern int unishox2_decompress_simple(const char *in, int len, char *out);
|
|||||||
* @param[in] olen length of 'out' buffer in bytes. Can be omitted if sufficient buffer is provided
|
* @param[in] olen length of 'out' buffer in bytes. Can be omitted if sufficient buffer is provided
|
||||||
* @param[in] usx_hcodes Horizontal codes (array of bytes). See macro section for samples.
|
* @param[in] usx_hcodes Horizontal codes (array of bytes). See macro section for samples.
|
||||||
* @param[in] usx_hcode_lens Length of each element in usx_hcodes array
|
* @param[in] usx_hcode_lens Length of each element in usx_hcodes array
|
||||||
* @param[in] usx_freq_seq Frequently occuring sequences. See USX_FREQ_SEQ_* macros for samples
|
* @param[in] usx_freq_seq Frequently occurring sequences. See USX_FREQ_SEQ_* macros for samples
|
||||||
* @param[in] usx_templates Templates of frequently occuring patterns. See USX_TEMPLATES macro.
|
* @param[in] usx_templates Templates of frequently occurring patterns. See USX_TEMPLATES macro.
|
||||||
*/
|
*/
|
||||||
extern int unishox2_compress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen),
|
extern int unishox2_compress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen),
|
||||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[], const char *usx_freq_seq[],
|
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[], const char *usx_freq_seq[],
|
||||||
@@ -352,8 +352,8 @@ extern int unishox2_compress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(ch
|
|||||||
* @param[in] olen length of 'out' buffer in bytes. Can be omitted if sufficient buffer is provided
|
* @param[in] olen length of 'out' buffer in bytes. Can be omitted if sufficient buffer is provided
|
||||||
* @param[in] usx_hcodes Horizontal codes (array of bytes). See macro section for samples.
|
* @param[in] usx_hcodes Horizontal codes (array of bytes). See macro section for samples.
|
||||||
* @param[in] usx_hcode_lens Length of each element in usx_hcodes array
|
* @param[in] usx_hcode_lens Length of each element in usx_hcodes array
|
||||||
* @param[in] usx_freq_seq Frequently occuring sequences. See USX_FREQ_SEQ_* macros for samples
|
* @param[in] usx_freq_seq Frequently occurring sequences. See USX_FREQ_SEQ_* macros for samples
|
||||||
* @param[in] usx_templates Templates of frequently occuring patterns. See USX_TEMPLATES macro.
|
* @param[in] usx_templates Templates of frequently occurring patterns. See USX_TEMPLATES macro.
|
||||||
*/
|
*/
|
||||||
extern int unishox2_decompress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen),
|
extern int unishox2_decompress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen),
|
||||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[], const char *usx_freq_seq[],
|
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[], const char *usx_freq_seq[],
|
||||||
@@ -373,7 +373,7 @@ extern int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_
|
|||||||
const char *usx_freq_seq[], const char *usx_templates[], struct us_lnk_lst *prev_lines);
|
const char *usx_freq_seq[], const char *usx_templates[], struct us_lnk_lst *prev_lines);
|
||||||
/**
|
/**
|
||||||
* More Comprehensive API for de-compressing array of strings \n
|
* More Comprehensive API for de-compressing array of strings \n
|
||||||
* This function is not be used in conjuction with unishox2_compress_lines()
|
* This function is not be used in conjunction with unishox2_compress_lines()
|
||||||
*
|
*
|
||||||
* See unishox2_decompress() function for parameter definitions. \n
|
* See unishox2_decompress() function for parameter definitions. \n
|
||||||
* Typically an array is compressed using unishox2_compress_lines() and \n
|
* Typically an array is compressed using unishox2_compress_lines() and \n
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ static int32_t reconnectETH()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME this is kinda yucky, instead we should just have an observable for 'wifireconnected'
|
// FIXME this is kinda yucky, instead we should just have an observable for 'wifireconnected'
|
||||||
if (mqtt && !mqtt->connected()) {
|
if (mqtt && !moduleConfig.mqtt.proxy_to_client_enabled && !mqtt->isConnectedDirectly()) {
|
||||||
mqtt->reconnect();
|
mqtt->reconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,6 @@ static int32_t reconnectETH()
|
|||||||
perhapsSetRTC(RTCQualityNTP, &tv);
|
perhapsSetRTC(RTCQualityNTP, &tv);
|
||||||
|
|
||||||
ntp_renew = millis() + 43200 * 1000; // success, refresh every 12 hours
|
ntp_renew = millis() + 43200 * 1000; // success, refresh every 12 hours
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("NTP Update failed\n");
|
LOG_ERROR("NTP Update failed\n");
|
||||||
ntp_renew = millis() + 300 * 1000; // failure, retry every 5 minutes
|
ntp_renew = millis() + 300 * 1000; // failure, retry every 5 minutes
|
||||||
@@ -170,7 +169,6 @@ bool initEthernet()
|
|||||||
ethEvent = new Periodic("ethConnect", reconnectETH);
|
ethEvent = new Periodic("ethConnect", reconnectETH);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("Not using Ethernet\n");
|
LOG_INFO("Not using Ethernet\n");
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ typedef struct _meshtastic_DeviceState {
|
|||||||
/* The mesh's nodes with their available gpio pins for RemoteHardware module */
|
/* The mesh's nodes with their available gpio pins for RemoteHardware module */
|
||||||
pb_size_t node_remote_hardware_pins_count;
|
pb_size_t node_remote_hardware_pins_count;
|
||||||
meshtastic_NodeRemoteHardwarePin node_remote_hardware_pins[12];
|
meshtastic_NodeRemoteHardwarePin node_remote_hardware_pins[12];
|
||||||
/* New lite version of NodeDB to decrease */
|
/* New lite version of NodeDB to decrease memory footprint */
|
||||||
pb_size_t node_db_lite_count;
|
pb_size_t node_db_lite_count;
|
||||||
meshtastic_NodeInfoLite node_db_lite[80];
|
meshtastic_NodeInfoLite node_db_lite[80];
|
||||||
} meshtastic_DeviceState;
|
} meshtastic_DeviceState;
|
||||||
@@ -323,7 +323,7 @@ extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePin_msg;
|
|||||||
#define meshtastic_DeviceState_size 35056
|
#define meshtastic_DeviceState_size 35056
|
||||||
#define meshtastic_NodeInfoLite_size 151
|
#define meshtastic_NodeInfoLite_size 151
|
||||||
#define meshtastic_NodeRemoteHardwarePin_size 29
|
#define meshtastic_NodeRemoteHardwarePin_size 29
|
||||||
#define meshtastic_OEMStore_size 3152
|
#define meshtastic_OEMStore_size 3154
|
||||||
#define meshtastic_PositionLite_size 28
|
#define meshtastic_PositionLite_size 28
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
|
|||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define meshtastic_LocalConfig_size 461
|
#define meshtastic_LocalConfig_size 461
|
||||||
#define meshtastic_LocalModuleConfig_size 545
|
#define meshtastic_LocalModuleConfig_size 547
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ PB_BIND(meshtastic_Data, meshtastic_Data, 2)
|
|||||||
PB_BIND(meshtastic_Waypoint, meshtastic_Waypoint, AUTO)
|
PB_BIND(meshtastic_Waypoint, meshtastic_Waypoint, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(meshtastic_MqttClientProxyMessage, meshtastic_MqttClientProxyMessage, 2)
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(meshtastic_MeshPacket, meshtastic_MeshPacket, 2)
|
PB_BIND(meshtastic_MeshPacket, meshtastic_MeshPacket, 2)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ typedef enum _meshtastic_HardwareModel {
|
|||||||
meshtastic_HardwareModel_TLORA_T3_S3 = 16,
|
meshtastic_HardwareModel_TLORA_T3_S3 = 16,
|
||||||
/* B&Q Consulting Nano G1 Explorer: https://wiki.uniteng.com/en/meshtastic/nano-g1-explorer */
|
/* B&Q Consulting Nano G1 Explorer: https://wiki.uniteng.com/en/meshtastic/nano-g1-explorer */
|
||||||
meshtastic_HardwareModel_NANO_G1_EXPLORER = 17,
|
meshtastic_HardwareModel_NANO_G1_EXPLORER = 17,
|
||||||
|
/* B&Q Consulting Nano G2 Ultra: https://wiki.uniteng.com/en/meshtastic/nano-g2-ultra */
|
||||||
|
meshtastic_HardwareModel_NANO_G2_ULTRA = 18,
|
||||||
/* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */
|
/* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */
|
||||||
meshtastic_HardwareModel_STATION_G1 = 25,
|
meshtastic_HardwareModel_STATION_G1 = 25,
|
||||||
/* RAK11310 (RP2040 + SX1262) */
|
/* RAK11310 (RP2040 + SX1262) */
|
||||||
@@ -97,6 +99,14 @@ typedef enum _meshtastic_HardwareModel {
|
|||||||
meshtastic_HardwareModel_BETAFPV_900_NANO_TX = 46,
|
meshtastic_HardwareModel_BETAFPV_900_NANO_TX = 46,
|
||||||
/* Raspberry Pi Pico (W) with Waveshare SX1262 LoRa Node Module */
|
/* Raspberry Pi Pico (W) with Waveshare SX1262 LoRa Node Module */
|
||||||
meshtastic_HardwareModel_RPI_PICO = 47,
|
meshtastic_HardwareModel_RPI_PICO = 47,
|
||||||
|
/* Heltec Wireless Tracker with ESP32-S3 CPU, built-in GPS, and TFT */
|
||||||
|
meshtastic_HardwareModel_HELTEC_WIRELESS_TRACKER = 48,
|
||||||
|
/* Heltec Wireless Paper with ESP32-S3 CPU and E-Ink display */
|
||||||
|
meshtastic_HardwareModel_HELTEC_WIRELESS_PAPER = 49,
|
||||||
|
/* LilyGo T-Deck with ESP32-S3 CPU, Keyboard, and IPS display */
|
||||||
|
meshtastic_HardwareModel_T_DECK = 50,
|
||||||
|
/* LilyGo T-Watch S3 with ESP32-S3 CPU and IPS display */
|
||||||
|
meshtastic_HardwareModel_T_WATCH_S3 = 51,
|
||||||
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
|
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------ */
|
------------------------------------------------------------------------------------------------------------------------------------------ */
|
||||||
@@ -220,9 +230,9 @@ typedef enum _meshtastic_Routing_Error {
|
|||||||
to make sure that critical packets are sent ASAP.
|
to make sure that critical packets are sent ASAP.
|
||||||
In the case of meshtastic that means we want to send protocol acks as soon as possible
|
In the case of meshtastic that means we want to send protocol acks as soon as possible
|
||||||
(to prevent unneeded retransmissions), we want routing messages to be sent next,
|
(to prevent unneeded retransmissions), we want routing messages to be sent next,
|
||||||
then messages marked as reliable and finally ‘background’ packets like periodic position updates.
|
then messages marked as reliable and finally 'background' packets like periodic position updates.
|
||||||
So I bit the bullet and implemented a new (internal - not sent over the air)
|
So I bit the bullet and implemented a new (internal - not sent over the air)
|
||||||
field in MeshPacket called ‘priority’.
|
field in MeshPacket called 'priority'.
|
||||||
And the transmission queue in the router object is now a priority queue. */
|
And the transmission queue in the router object is now a priority queue. */
|
||||||
typedef enum _meshtastic_MeshPacket_Priority {
|
typedef enum _meshtastic_MeshPacket_Priority {
|
||||||
/* Treated as Priority.DEFAULT */
|
/* Treated as Priority.DEFAULT */
|
||||||
@@ -462,6 +472,22 @@ typedef struct _meshtastic_Waypoint {
|
|||||||
uint32_t icon;
|
uint32_t icon;
|
||||||
} meshtastic_Waypoint;
|
} meshtastic_Waypoint;
|
||||||
|
|
||||||
|
typedef PB_BYTES_ARRAY_T(435) meshtastic_MqttClientProxyMessage_data_t;
|
||||||
|
/* This message will be proxied over the PhoneAPI for the client to deliver to the MQTT server */
|
||||||
|
typedef struct _meshtastic_MqttClientProxyMessage {
|
||||||
|
/* The MQTT topic this message will be sent /received on */
|
||||||
|
char topic[60];
|
||||||
|
pb_size_t which_payload_variant;
|
||||||
|
union {
|
||||||
|
/* Bytes */
|
||||||
|
meshtastic_MqttClientProxyMessage_data_t data;
|
||||||
|
/* Text */
|
||||||
|
char text[435];
|
||||||
|
} payload_variant;
|
||||||
|
/* Whether the message should be retained (or not) */
|
||||||
|
bool retained;
|
||||||
|
} meshtastic_MqttClientProxyMessage;
|
||||||
|
|
||||||
typedef PB_BYTES_ARRAY_T(256) meshtastic_MeshPacket_encrypted_t;
|
typedef PB_BYTES_ARRAY_T(256) meshtastic_MeshPacket_encrypted_t;
|
||||||
/* A packet envelope sent/received over the mesh
|
/* A packet envelope sent/received over the mesh
|
||||||
only payload_variant is sent in the payload portion of the LORA packet.
|
only payload_variant is sent in the payload portion of the LORA packet.
|
||||||
@@ -683,6 +709,8 @@ typedef struct _meshtastic_ToRadio {
|
|||||||
(Sending this message is optional for clients) */
|
(Sending this message is optional for clients) */
|
||||||
bool disconnect;
|
bool disconnect;
|
||||||
meshtastic_XModem xmodemPacket;
|
meshtastic_XModem xmodemPacket;
|
||||||
|
/* MQTT Client Proxy Message (for client / phone subscribed to MQTT sending to device) */
|
||||||
|
meshtastic_MqttClientProxyMessage mqttClientProxyMessage;
|
||||||
};
|
};
|
||||||
} meshtastic_ToRadio;
|
} meshtastic_ToRadio;
|
||||||
|
|
||||||
@@ -780,6 +808,8 @@ typedef struct _meshtastic_FromRadio {
|
|||||||
meshtastic_XModem xmodemPacket;
|
meshtastic_XModem xmodemPacket;
|
||||||
/* Device metadata message */
|
/* Device metadata message */
|
||||||
meshtastic_DeviceMetadata metadata;
|
meshtastic_DeviceMetadata metadata;
|
||||||
|
/* MQTT Client Proxy Message (device sending to client / phone for publishing to MQTT) */
|
||||||
|
meshtastic_MqttClientProxyMessage mqttClientProxyMessage;
|
||||||
};
|
};
|
||||||
} meshtastic_FromRadio;
|
} meshtastic_FromRadio;
|
||||||
|
|
||||||
@@ -836,6 +866,7 @@ extern "C" {
|
|||||||
#define meshtastic_Data_portnum_ENUMTYPE meshtastic_PortNum
|
#define meshtastic_Data_portnum_ENUMTYPE meshtastic_PortNum
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define meshtastic_MeshPacket_priority_ENUMTYPE meshtastic_MeshPacket_Priority
|
#define meshtastic_MeshPacket_priority_ENUMTYPE meshtastic_MeshPacket_Priority
|
||||||
#define meshtastic_MeshPacket_delayed_ENUMTYPE meshtastic_MeshPacket_Delayed
|
#define meshtastic_MeshPacket_delayed_ENUMTYPE meshtastic_MeshPacket_Delayed
|
||||||
|
|
||||||
@@ -862,6 +893,7 @@ extern "C" {
|
|||||||
#define meshtastic_Routing_init_default {0, {meshtastic_RouteDiscovery_init_default}}
|
#define meshtastic_Routing_init_default {0, {meshtastic_RouteDiscovery_init_default}}
|
||||||
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Waypoint_init_default {0, 0, 0, 0, 0, "", "", 0}
|
#define meshtastic_Waypoint_init_default {0, 0, 0, 0, 0, "", "", 0}
|
||||||
|
#define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0}
|
||||||
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN}
|
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN}
|
||||||
#define meshtastic_NodeInfo_init_default {0, false, meshtastic_User_init_default, false, meshtastic_Position_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0}
|
#define meshtastic_NodeInfo_init_default {0, false, meshtastic_User_init_default, false, meshtastic_Position_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0}
|
||||||
#define meshtastic_MyNodeInfo_init_default {0, 0, 0, "", _meshtastic_CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
|
#define meshtastic_MyNodeInfo_init_default {0, 0, 0, "", _meshtastic_CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
|
||||||
@@ -879,6 +911,7 @@ extern "C" {
|
|||||||
#define meshtastic_Routing_init_zero {0, {meshtastic_RouteDiscovery_init_zero}}
|
#define meshtastic_Routing_init_zero {0, {meshtastic_RouteDiscovery_init_zero}}
|
||||||
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_Waypoint_init_zero {0, 0, 0, 0, 0, "", "", 0}
|
#define meshtastic_Waypoint_init_zero {0, 0, 0, 0, 0, "", "", 0}
|
||||||
|
#define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0}
|
||||||
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN}
|
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN}
|
||||||
#define meshtastic_NodeInfo_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_Position_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0}
|
#define meshtastic_NodeInfo_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_Position_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0}
|
||||||
#define meshtastic_MyNodeInfo_init_zero {0, 0, 0, "", _meshtastic_CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
|
#define meshtastic_MyNodeInfo_init_zero {0, 0, 0, "", _meshtastic_CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}
|
||||||
@@ -940,6 +973,10 @@ extern "C" {
|
|||||||
#define meshtastic_Waypoint_name_tag 6
|
#define meshtastic_Waypoint_name_tag 6
|
||||||
#define meshtastic_Waypoint_description_tag 7
|
#define meshtastic_Waypoint_description_tag 7
|
||||||
#define meshtastic_Waypoint_icon_tag 8
|
#define meshtastic_Waypoint_icon_tag 8
|
||||||
|
#define meshtastic_MqttClientProxyMessage_topic_tag 1
|
||||||
|
#define meshtastic_MqttClientProxyMessage_data_tag 2
|
||||||
|
#define meshtastic_MqttClientProxyMessage_text_tag 3
|
||||||
|
#define meshtastic_MqttClientProxyMessage_retained_tag 4
|
||||||
#define meshtastic_MeshPacket_from_tag 1
|
#define meshtastic_MeshPacket_from_tag 1
|
||||||
#define meshtastic_MeshPacket_to_tag 2
|
#define meshtastic_MeshPacket_to_tag 2
|
||||||
#define meshtastic_MeshPacket_channel_tag 3
|
#define meshtastic_MeshPacket_channel_tag 3
|
||||||
@@ -988,6 +1025,7 @@ extern "C" {
|
|||||||
#define meshtastic_ToRadio_want_config_id_tag 3
|
#define meshtastic_ToRadio_want_config_id_tag 3
|
||||||
#define meshtastic_ToRadio_disconnect_tag 4
|
#define meshtastic_ToRadio_disconnect_tag 4
|
||||||
#define meshtastic_ToRadio_xmodemPacket_tag 5
|
#define meshtastic_ToRadio_xmodemPacket_tag 5
|
||||||
|
#define meshtastic_ToRadio_mqttClientProxyMessage_tag 6
|
||||||
#define meshtastic_Compressed_portnum_tag 1
|
#define meshtastic_Compressed_portnum_tag 1
|
||||||
#define meshtastic_Compressed_data_tag 2
|
#define meshtastic_Compressed_data_tag 2
|
||||||
#define meshtastic_Neighbor_node_id_tag 1
|
#define meshtastic_Neighbor_node_id_tag 1
|
||||||
@@ -1018,6 +1056,7 @@ extern "C" {
|
|||||||
#define meshtastic_FromRadio_queueStatus_tag 11
|
#define meshtastic_FromRadio_queueStatus_tag 11
|
||||||
#define meshtastic_FromRadio_xmodemPacket_tag 12
|
#define meshtastic_FromRadio_xmodemPacket_tag 12
|
||||||
#define meshtastic_FromRadio_metadata_tag 13
|
#define meshtastic_FromRadio_metadata_tag 13
|
||||||
|
#define meshtastic_FromRadio_mqttClientProxyMessage_tag 14
|
||||||
|
|
||||||
/* Struct field encoding specification for nanopb */
|
/* Struct field encoding specification for nanopb */
|
||||||
#define meshtastic_Position_FIELDLIST(X, a) \
|
#define meshtastic_Position_FIELDLIST(X, a) \
|
||||||
@@ -1094,6 +1133,14 @@ X(a, STATIC, SINGULAR, FIXED32, icon, 8)
|
|||||||
#define meshtastic_Waypoint_CALLBACK NULL
|
#define meshtastic_Waypoint_CALLBACK NULL
|
||||||
#define meshtastic_Waypoint_DEFAULT NULL
|
#define meshtastic_Waypoint_DEFAULT NULL
|
||||||
|
|
||||||
|
#define meshtastic_MqttClientProxyMessage_FIELDLIST(X, a) \
|
||||||
|
X(a, STATIC, SINGULAR, STRING, topic, 1) \
|
||||||
|
X(a, STATIC, ONEOF, BYTES, (payload_variant,data,payload_variant.data), 2) \
|
||||||
|
X(a, STATIC, ONEOF, STRING, (payload_variant,text,payload_variant.text), 3) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, retained, 4)
|
||||||
|
#define meshtastic_MqttClientProxyMessage_CALLBACK NULL
|
||||||
|
#define meshtastic_MqttClientProxyMessage_DEFAULT NULL
|
||||||
|
|
||||||
#define meshtastic_MeshPacket_FIELDLIST(X, a) \
|
#define meshtastic_MeshPacket_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, FIXED32, from, 1) \
|
X(a, STATIC, SINGULAR, FIXED32, from, 1) \
|
||||||
X(a, STATIC, SINGULAR, FIXED32, to, 2) \
|
X(a, STATIC, SINGULAR, FIXED32, to, 2) \
|
||||||
@@ -1175,7 +1222,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,moduleConfig,moduleConfig),
|
|||||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,channel,channel), 10) \
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,channel,channel), 10) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,queueStatus,queueStatus), 11) \
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,queueStatus,queueStatus), 11) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,xmodemPacket,xmodemPacket), 12) \
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,xmodemPacket,xmodemPacket), 12) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,metadata,metadata), 13)
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,metadata,metadata), 13) \
|
||||||
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,mqttClientProxyMessage,mqttClientProxyMessage), 14)
|
||||||
#define meshtastic_FromRadio_CALLBACK NULL
|
#define meshtastic_FromRadio_CALLBACK NULL
|
||||||
#define meshtastic_FromRadio_DEFAULT NULL
|
#define meshtastic_FromRadio_DEFAULT NULL
|
||||||
#define meshtastic_FromRadio_payload_variant_packet_MSGTYPE meshtastic_MeshPacket
|
#define meshtastic_FromRadio_payload_variant_packet_MSGTYPE meshtastic_MeshPacket
|
||||||
@@ -1188,16 +1236,19 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,metadata,metadata), 13)
|
|||||||
#define meshtastic_FromRadio_payload_variant_queueStatus_MSGTYPE meshtastic_QueueStatus
|
#define meshtastic_FromRadio_payload_variant_queueStatus_MSGTYPE meshtastic_QueueStatus
|
||||||
#define meshtastic_FromRadio_payload_variant_xmodemPacket_MSGTYPE meshtastic_XModem
|
#define meshtastic_FromRadio_payload_variant_xmodemPacket_MSGTYPE meshtastic_XModem
|
||||||
#define meshtastic_FromRadio_payload_variant_metadata_MSGTYPE meshtastic_DeviceMetadata
|
#define meshtastic_FromRadio_payload_variant_metadata_MSGTYPE meshtastic_DeviceMetadata
|
||||||
|
#define meshtastic_FromRadio_payload_variant_mqttClientProxyMessage_MSGTYPE meshtastic_MqttClientProxyMessage
|
||||||
|
|
||||||
#define meshtastic_ToRadio_FIELDLIST(X, a) \
|
#define meshtastic_ToRadio_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,packet,packet), 1) \
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,packet,packet), 1) \
|
||||||
X(a, STATIC, ONEOF, UINT32, (payload_variant,want_config_id,want_config_id), 3) \
|
X(a, STATIC, ONEOF, UINT32, (payload_variant,want_config_id,want_config_id), 3) \
|
||||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,disconnect,disconnect), 4) \
|
X(a, STATIC, ONEOF, BOOL, (payload_variant,disconnect,disconnect), 4) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,xmodemPacket,xmodemPacket), 5)
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,xmodemPacket,xmodemPacket), 5) \
|
||||||
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,mqttClientProxyMessage,mqttClientProxyMessage), 6)
|
||||||
#define meshtastic_ToRadio_CALLBACK NULL
|
#define meshtastic_ToRadio_CALLBACK NULL
|
||||||
#define meshtastic_ToRadio_DEFAULT NULL
|
#define meshtastic_ToRadio_DEFAULT NULL
|
||||||
#define meshtastic_ToRadio_payload_variant_packet_MSGTYPE meshtastic_MeshPacket
|
#define meshtastic_ToRadio_payload_variant_packet_MSGTYPE meshtastic_MeshPacket
|
||||||
#define meshtastic_ToRadio_payload_variant_xmodemPacket_MSGTYPE meshtastic_XModem
|
#define meshtastic_ToRadio_payload_variant_xmodemPacket_MSGTYPE meshtastic_XModem
|
||||||
|
#define meshtastic_ToRadio_payload_variant_mqttClientProxyMessage_MSGTYPE meshtastic_MqttClientProxyMessage
|
||||||
|
|
||||||
#define meshtastic_Compressed_FIELDLIST(X, a) \
|
#define meshtastic_Compressed_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, UENUM, portnum, 1) \
|
X(a, STATIC, SINGULAR, UENUM, portnum, 1) \
|
||||||
@@ -1239,6 +1290,7 @@ extern const pb_msgdesc_t meshtastic_RouteDiscovery_msg;
|
|||||||
extern const pb_msgdesc_t meshtastic_Routing_msg;
|
extern const pb_msgdesc_t meshtastic_Routing_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_Data_msg;
|
extern const pb_msgdesc_t meshtastic_Data_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_Waypoint_msg;
|
extern const pb_msgdesc_t meshtastic_Waypoint_msg;
|
||||||
|
extern const pb_msgdesc_t meshtastic_MqttClientProxyMessage_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_MeshPacket_msg;
|
extern const pb_msgdesc_t meshtastic_MeshPacket_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_NodeInfo_msg;
|
extern const pb_msgdesc_t meshtastic_NodeInfo_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_MyNodeInfo_msg;
|
extern const pb_msgdesc_t meshtastic_MyNodeInfo_msg;
|
||||||
@@ -1258,6 +1310,7 @@ extern const pb_msgdesc_t meshtastic_DeviceMetadata_msg;
|
|||||||
#define meshtastic_Routing_fields &meshtastic_Routing_msg
|
#define meshtastic_Routing_fields &meshtastic_Routing_msg
|
||||||
#define meshtastic_Data_fields &meshtastic_Data_msg
|
#define meshtastic_Data_fields &meshtastic_Data_msg
|
||||||
#define meshtastic_Waypoint_fields &meshtastic_Waypoint_msg
|
#define meshtastic_Waypoint_fields &meshtastic_Waypoint_msg
|
||||||
|
#define meshtastic_MqttClientProxyMessage_fields &meshtastic_MqttClientProxyMessage_msg
|
||||||
#define meshtastic_MeshPacket_fields &meshtastic_MeshPacket_msg
|
#define meshtastic_MeshPacket_fields &meshtastic_MeshPacket_msg
|
||||||
#define meshtastic_NodeInfo_fields &meshtastic_NodeInfo_msg
|
#define meshtastic_NodeInfo_fields &meshtastic_NodeInfo_msg
|
||||||
#define meshtastic_MyNodeInfo_fields &meshtastic_MyNodeInfo_msg
|
#define meshtastic_MyNodeInfo_fields &meshtastic_MyNodeInfo_msg
|
||||||
@@ -1274,9 +1327,10 @@ extern const pb_msgdesc_t meshtastic_DeviceMetadata_msg;
|
|||||||
#define meshtastic_Compressed_size 243
|
#define meshtastic_Compressed_size 243
|
||||||
#define meshtastic_Data_size 270
|
#define meshtastic_Data_size 270
|
||||||
#define meshtastic_DeviceMetadata_size 46
|
#define meshtastic_DeviceMetadata_size 46
|
||||||
#define meshtastic_FromRadio_size 330
|
#define meshtastic_FromRadio_size 510
|
||||||
#define meshtastic_LogRecord_size 81
|
#define meshtastic_LogRecord_size 81
|
||||||
#define meshtastic_MeshPacket_size 321
|
#define meshtastic_MeshPacket_size 321
|
||||||
|
#define meshtastic_MqttClientProxyMessage_size 501
|
||||||
#define meshtastic_MyNodeInfo_size 179
|
#define meshtastic_MyNodeInfo_size 179
|
||||||
#define meshtastic_NeighborInfo_size 142
|
#define meshtastic_NeighborInfo_size 142
|
||||||
#define meshtastic_Neighbor_size 11
|
#define meshtastic_Neighbor_size 11
|
||||||
@@ -1285,7 +1339,7 @@ extern const pb_msgdesc_t meshtastic_DeviceMetadata_msg;
|
|||||||
#define meshtastic_QueueStatus_size 23
|
#define meshtastic_QueueStatus_size 23
|
||||||
#define meshtastic_RouteDiscovery_size 40
|
#define meshtastic_RouteDiscovery_size 40
|
||||||
#define meshtastic_Routing_size 42
|
#define meshtastic_Routing_size 42
|
||||||
#define meshtastic_ToRadio_size 324
|
#define meshtastic_ToRadio_size 504
|
||||||
#define meshtastic_User_size 77
|
#define meshtastic_User_size 77
|
||||||
#define meshtastic_Waypoint_size 165
|
#define meshtastic_Waypoint_size 165
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ PB_BIND(meshtastic_ModuleConfig_TelemetryConfig, meshtastic_ModuleConfig_Telemet
|
|||||||
PB_BIND(meshtastic_ModuleConfig_CannedMessageConfig, meshtastic_ModuleConfig_CannedMessageConfig, AUTO)
|
PB_BIND(meshtastic_ModuleConfig_CannedMessageConfig, meshtastic_ModuleConfig_CannedMessageConfig, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(meshtastic_ModuleConfig_AmbientLightingConfig, meshtastic_ModuleConfig_AmbientLightingConfig, AUTO)
|
||||||
|
|
||||||
|
|
||||||
PB_BIND(meshtastic_RemoteHardwarePin, meshtastic_RemoteHardwarePin, AUTO)
|
PB_BIND(meshtastic_RemoteHardwarePin, meshtastic_RemoteHardwarePin, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -112,6 +112,8 @@ typedef struct _meshtastic_ModuleConfig_MQTTConfig {
|
|||||||
/* The root topic to use for MQTT messages. Default is "msh".
|
/* The root topic to use for MQTT messages. Default is "msh".
|
||||||
This is useful if you want to use a single MQTT server for multiple meshtastic networks and separate them via ACLs */
|
This is useful if you want to use a single MQTT server for multiple meshtastic networks and separate them via ACLs */
|
||||||
char root[16];
|
char root[16];
|
||||||
|
/* If true, we can use the connected phone / client to proxy messages to MQTT instead of a direct connection */
|
||||||
|
bool proxy_to_client_enabled;
|
||||||
} meshtastic_ModuleConfig_MQTTConfig;
|
} meshtastic_ModuleConfig_MQTTConfig;
|
||||||
|
|
||||||
/* NeighborInfoModule Config */
|
/* NeighborInfoModule Config */
|
||||||
@@ -279,6 +281,20 @@ typedef struct _meshtastic_ModuleConfig_CannedMessageConfig {
|
|||||||
bool send_bell;
|
bool send_bell;
|
||||||
} meshtastic_ModuleConfig_CannedMessageConfig;
|
} meshtastic_ModuleConfig_CannedMessageConfig;
|
||||||
|
|
||||||
|
/* Ambient Lighting Module - Settings for control of onboard LEDs to allow users to adjust the brightness levels and respective color levels.
|
||||||
|
Initially created for the RAK14001 RGB LED module. */
|
||||||
|
typedef struct _meshtastic_ModuleConfig_AmbientLightingConfig {
|
||||||
|
/* Sets LED to on or off. */
|
||||||
|
bool led_state;
|
||||||
|
/* Sets the overall current for the LED, firmware side range for the RAK14001 is 1-31, but users should be given a range of 0-100% */
|
||||||
|
uint8_t current;
|
||||||
|
uint8_t red; /* Red level */
|
||||||
|
/* Sets the green level of the LED, firmware side values are 0-255, but users should be given a range of 0-100% */
|
||||||
|
uint8_t green; /* Green level */
|
||||||
|
/* Sets the blue level of the LED, firmware side values are 0-255, but users should be given a range of 0-100% */
|
||||||
|
uint8_t blue; /* Blue level */
|
||||||
|
} meshtastic_ModuleConfig_AmbientLightingConfig;
|
||||||
|
|
||||||
/* A GPIO pin definition for remote hardware module */
|
/* A GPIO pin definition for remote hardware module */
|
||||||
typedef struct _meshtastic_RemoteHardwarePin {
|
typedef struct _meshtastic_RemoteHardwarePin {
|
||||||
/* GPIO Pin number (must match Arduino) */
|
/* GPIO Pin number (must match Arduino) */
|
||||||
@@ -324,6 +340,8 @@ typedef struct _meshtastic_ModuleConfig {
|
|||||||
meshtastic_ModuleConfig_RemoteHardwareConfig remote_hardware;
|
meshtastic_ModuleConfig_RemoteHardwareConfig remote_hardware;
|
||||||
/* TODO: REPLACE */
|
/* TODO: REPLACE */
|
||||||
meshtastic_ModuleConfig_NeighborInfoConfig neighbor_info;
|
meshtastic_ModuleConfig_NeighborInfoConfig neighbor_info;
|
||||||
|
/* TODO: REPLACE */
|
||||||
|
meshtastic_ModuleConfig_AmbientLightingConfig ambient_lighting;
|
||||||
} payload_variant;
|
} payload_variant;
|
||||||
} meshtastic_ModuleConfig;
|
} meshtastic_ModuleConfig;
|
||||||
|
|
||||||
@@ -370,12 +388,13 @@ extern "C" {
|
|||||||
#define meshtastic_ModuleConfig_CannedMessageConfig_inputbroker_event_ccw_ENUMTYPE meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar
|
#define meshtastic_ModuleConfig_CannedMessageConfig_inputbroker_event_ccw_ENUMTYPE meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar
|
||||||
#define meshtastic_ModuleConfig_CannedMessageConfig_inputbroker_event_press_ENUMTYPE meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar
|
#define meshtastic_ModuleConfig_CannedMessageConfig_inputbroker_event_press_ENUMTYPE meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar
|
||||||
|
|
||||||
|
|
||||||
#define meshtastic_RemoteHardwarePin_type_ENUMTYPE meshtastic_RemoteHardwarePinType
|
#define meshtastic_RemoteHardwarePin_type_ENUMTYPE meshtastic_RemoteHardwarePinType
|
||||||
|
|
||||||
|
|
||||||
/* Initializer values for message structs */
|
/* Initializer values for message structs */
|
||||||
#define meshtastic_ModuleConfig_init_default {0, {meshtastic_ModuleConfig_MQTTConfig_init_default}}
|
#define meshtastic_ModuleConfig_init_default {0, {meshtastic_ModuleConfig_MQTTConfig_init_default}}
|
||||||
#define meshtastic_ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0, 0, ""}
|
#define meshtastic_ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0, 0, "", 0}
|
||||||
#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_default {0, 0, 0, {meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default}}
|
#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_default {0, 0, 0, {meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default}}
|
||||||
#define meshtastic_ModuleConfig_NeighborInfoConfig_init_default {0, 0}
|
#define meshtastic_ModuleConfig_NeighborInfoConfig_init_default {0, 0}
|
||||||
#define meshtastic_ModuleConfig_AudioConfig_init_default {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
|
#define meshtastic_ModuleConfig_AudioConfig_init_default {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
|
||||||
@@ -385,9 +404,10 @@ extern "C" {
|
|||||||
#define meshtastic_ModuleConfig_RangeTestConfig_init_default {0, 0, 0}
|
#define meshtastic_ModuleConfig_RangeTestConfig_init_default {0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_TelemetryConfig_init_default {0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_ModuleConfig_TelemetryConfig_init_default {0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_CannedMessageConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
|
#define meshtastic_ModuleConfig_CannedMessageConfig_init_default {0, 0, 0, 0, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
|
||||||
|
#define meshtastic_ModuleConfig_AmbientLightingConfig_init_default {0, 0, 0, 0, 0}
|
||||||
#define meshtastic_RemoteHardwarePin_init_default {0, "", _meshtastic_RemoteHardwarePinType_MIN}
|
#define meshtastic_RemoteHardwarePin_init_default {0, "", _meshtastic_RemoteHardwarePinType_MIN}
|
||||||
#define meshtastic_ModuleConfig_init_zero {0, {meshtastic_ModuleConfig_MQTTConfig_init_zero}}
|
#define meshtastic_ModuleConfig_init_zero {0, {meshtastic_ModuleConfig_MQTTConfig_init_zero}}
|
||||||
#define meshtastic_ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0, 0, ""}
|
#define meshtastic_ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0, 0, "", 0}
|
||||||
#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero {0, 0, 0, {meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero}}
|
#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero {0, 0, 0, {meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero}}
|
||||||
#define meshtastic_ModuleConfig_NeighborInfoConfig_init_zero {0, 0}
|
#define meshtastic_ModuleConfig_NeighborInfoConfig_init_zero {0, 0}
|
||||||
#define meshtastic_ModuleConfig_AudioConfig_init_zero {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
|
#define meshtastic_ModuleConfig_AudioConfig_init_zero {0, 0, _meshtastic_ModuleConfig_AudioConfig_Audio_Baud_MIN, 0, 0, 0, 0}
|
||||||
@@ -397,6 +417,7 @@ extern "C" {
|
|||||||
#define meshtastic_ModuleConfig_RangeTestConfig_init_zero {0, 0, 0}
|
#define meshtastic_ModuleConfig_RangeTestConfig_init_zero {0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_TelemetryConfig_init_zero {0, 0, 0, 0, 0, 0, 0}
|
#define meshtastic_ModuleConfig_TelemetryConfig_init_zero {0, 0, 0, 0, 0, 0, 0}
|
||||||
#define meshtastic_ModuleConfig_CannedMessageConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
|
#define meshtastic_ModuleConfig_CannedMessageConfig_init_zero {0, 0, 0, 0, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN, 0, 0, "", 0}
|
||||||
|
#define meshtastic_ModuleConfig_AmbientLightingConfig_init_zero {0, 0, 0, 0, 0}
|
||||||
#define meshtastic_RemoteHardwarePin_init_zero {0, "", _meshtastic_RemoteHardwarePinType_MIN}
|
#define meshtastic_RemoteHardwarePin_init_zero {0, "", _meshtastic_RemoteHardwarePinType_MIN}
|
||||||
|
|
||||||
/* Field tags (for use in manual encoding/decoding) */
|
/* Field tags (for use in manual encoding/decoding) */
|
||||||
@@ -408,6 +429,7 @@ extern "C" {
|
|||||||
#define meshtastic_ModuleConfig_MQTTConfig_json_enabled_tag 6
|
#define meshtastic_ModuleConfig_MQTTConfig_json_enabled_tag 6
|
||||||
#define meshtastic_ModuleConfig_MQTTConfig_tls_enabled_tag 7
|
#define meshtastic_ModuleConfig_MQTTConfig_tls_enabled_tag 7
|
||||||
#define meshtastic_ModuleConfig_MQTTConfig_root_tag 8
|
#define meshtastic_ModuleConfig_MQTTConfig_root_tag 8
|
||||||
|
#define meshtastic_ModuleConfig_MQTTConfig_proxy_to_client_enabled_tag 9
|
||||||
#define meshtastic_ModuleConfig_NeighborInfoConfig_enabled_tag 1
|
#define meshtastic_ModuleConfig_NeighborInfoConfig_enabled_tag 1
|
||||||
#define meshtastic_ModuleConfig_NeighborInfoConfig_update_interval_tag 2
|
#define meshtastic_ModuleConfig_NeighborInfoConfig_update_interval_tag 2
|
||||||
#define meshtastic_ModuleConfig_AudioConfig_codec2_enabled_tag 1
|
#define meshtastic_ModuleConfig_AudioConfig_codec2_enabled_tag 1
|
||||||
@@ -465,6 +487,11 @@ extern "C" {
|
|||||||
#define meshtastic_ModuleConfig_CannedMessageConfig_enabled_tag 9
|
#define meshtastic_ModuleConfig_CannedMessageConfig_enabled_tag 9
|
||||||
#define meshtastic_ModuleConfig_CannedMessageConfig_allow_input_source_tag 10
|
#define meshtastic_ModuleConfig_CannedMessageConfig_allow_input_source_tag 10
|
||||||
#define meshtastic_ModuleConfig_CannedMessageConfig_send_bell_tag 11
|
#define meshtastic_ModuleConfig_CannedMessageConfig_send_bell_tag 11
|
||||||
|
#define meshtastic_ModuleConfig_AmbientLightingConfig_led_state_tag 1
|
||||||
|
#define meshtastic_ModuleConfig_AmbientLightingConfig_current_tag 2
|
||||||
|
#define meshtastic_ModuleConfig_AmbientLightingConfig_red_tag 3
|
||||||
|
#define meshtastic_ModuleConfig_AmbientLightingConfig_green_tag 4
|
||||||
|
#define meshtastic_ModuleConfig_AmbientLightingConfig_blue_tag 5
|
||||||
#define meshtastic_RemoteHardwarePin_gpio_pin_tag 1
|
#define meshtastic_RemoteHardwarePin_gpio_pin_tag 1
|
||||||
#define meshtastic_RemoteHardwarePin_name_tag 2
|
#define meshtastic_RemoteHardwarePin_name_tag 2
|
||||||
#define meshtastic_RemoteHardwarePin_type_tag 3
|
#define meshtastic_RemoteHardwarePin_type_tag 3
|
||||||
@@ -481,6 +508,7 @@ extern "C" {
|
|||||||
#define meshtastic_ModuleConfig_audio_tag 8
|
#define meshtastic_ModuleConfig_audio_tag 8
|
||||||
#define meshtastic_ModuleConfig_remote_hardware_tag 9
|
#define meshtastic_ModuleConfig_remote_hardware_tag 9
|
||||||
#define meshtastic_ModuleConfig_neighbor_info_tag 10
|
#define meshtastic_ModuleConfig_neighbor_info_tag 10
|
||||||
|
#define meshtastic_ModuleConfig_ambient_lighting_tag 11
|
||||||
|
|
||||||
/* Struct field encoding specification for nanopb */
|
/* Struct field encoding specification for nanopb */
|
||||||
#define meshtastic_ModuleConfig_FIELDLIST(X, a) \
|
#define meshtastic_ModuleConfig_FIELDLIST(X, a) \
|
||||||
@@ -493,7 +521,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,telemetry,payload_variant.te
|
|||||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,canned_message,payload_variant.canned_message), 7) \
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,canned_message,payload_variant.canned_message), 7) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,audio,payload_variant.audio), 8) \
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,audio,payload_variant.audio), 8) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,remote_hardware,payload_variant.remote_hardware), 9) \
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,remote_hardware,payload_variant.remote_hardware), 9) \
|
||||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,neighbor_info,payload_variant.neighbor_info), 10)
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,neighbor_info,payload_variant.neighbor_info), 10) \
|
||||||
|
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,ambient_lighting,payload_variant.ambient_lighting), 11)
|
||||||
#define meshtastic_ModuleConfig_CALLBACK NULL
|
#define meshtastic_ModuleConfig_CALLBACK NULL
|
||||||
#define meshtastic_ModuleConfig_DEFAULT NULL
|
#define meshtastic_ModuleConfig_DEFAULT NULL
|
||||||
#define meshtastic_ModuleConfig_payload_variant_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig
|
#define meshtastic_ModuleConfig_payload_variant_mqtt_MSGTYPE meshtastic_ModuleConfig_MQTTConfig
|
||||||
@@ -506,6 +535,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,neighbor_info,payload_varian
|
|||||||
#define meshtastic_ModuleConfig_payload_variant_audio_MSGTYPE meshtastic_ModuleConfig_AudioConfig
|
#define meshtastic_ModuleConfig_payload_variant_audio_MSGTYPE meshtastic_ModuleConfig_AudioConfig
|
||||||
#define meshtastic_ModuleConfig_payload_variant_remote_hardware_MSGTYPE meshtastic_ModuleConfig_RemoteHardwareConfig
|
#define meshtastic_ModuleConfig_payload_variant_remote_hardware_MSGTYPE meshtastic_ModuleConfig_RemoteHardwareConfig
|
||||||
#define meshtastic_ModuleConfig_payload_variant_neighbor_info_MSGTYPE meshtastic_ModuleConfig_NeighborInfoConfig
|
#define meshtastic_ModuleConfig_payload_variant_neighbor_info_MSGTYPE meshtastic_ModuleConfig_NeighborInfoConfig
|
||||||
|
#define meshtastic_ModuleConfig_payload_variant_ambient_lighting_MSGTYPE meshtastic_ModuleConfig_AmbientLightingConfig
|
||||||
|
|
||||||
#define meshtastic_ModuleConfig_MQTTConfig_FIELDLIST(X, a) \
|
#define meshtastic_ModuleConfig_MQTTConfig_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
|
X(a, STATIC, SINGULAR, BOOL, enabled, 1) \
|
||||||
@@ -515,7 +545,8 @@ X(a, STATIC, SINGULAR, STRING, password, 4) \
|
|||||||
X(a, STATIC, SINGULAR, BOOL, encryption_enabled, 5) \
|
X(a, STATIC, SINGULAR, BOOL, encryption_enabled, 5) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, json_enabled, 6) \
|
X(a, STATIC, SINGULAR, BOOL, json_enabled, 6) \
|
||||||
X(a, STATIC, SINGULAR, BOOL, tls_enabled, 7) \
|
X(a, STATIC, SINGULAR, BOOL, tls_enabled, 7) \
|
||||||
X(a, STATIC, SINGULAR, STRING, root, 8)
|
X(a, STATIC, SINGULAR, STRING, root, 8) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, proxy_to_client_enabled, 9)
|
||||||
#define meshtastic_ModuleConfig_MQTTConfig_CALLBACK NULL
|
#define meshtastic_ModuleConfig_MQTTConfig_CALLBACK NULL
|
||||||
#define meshtastic_ModuleConfig_MQTTConfig_DEFAULT NULL
|
#define meshtastic_ModuleConfig_MQTTConfig_DEFAULT NULL
|
||||||
|
|
||||||
@@ -616,6 +647,15 @@ X(a, STATIC, SINGULAR, BOOL, send_bell, 11)
|
|||||||
#define meshtastic_ModuleConfig_CannedMessageConfig_CALLBACK NULL
|
#define meshtastic_ModuleConfig_CannedMessageConfig_CALLBACK NULL
|
||||||
#define meshtastic_ModuleConfig_CannedMessageConfig_DEFAULT NULL
|
#define meshtastic_ModuleConfig_CannedMessageConfig_DEFAULT NULL
|
||||||
|
|
||||||
|
#define meshtastic_ModuleConfig_AmbientLightingConfig_FIELDLIST(X, a) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, led_state, 1) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, current, 2) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, red, 3) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, green, 4) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, blue, 5)
|
||||||
|
#define meshtastic_ModuleConfig_AmbientLightingConfig_CALLBACK NULL
|
||||||
|
#define meshtastic_ModuleConfig_AmbientLightingConfig_DEFAULT NULL
|
||||||
|
|
||||||
#define meshtastic_RemoteHardwarePin_FIELDLIST(X, a) \
|
#define meshtastic_RemoteHardwarePin_FIELDLIST(X, a) \
|
||||||
X(a, STATIC, SINGULAR, UINT32, gpio_pin, 1) \
|
X(a, STATIC, SINGULAR, UINT32, gpio_pin, 1) \
|
||||||
X(a, STATIC, SINGULAR, STRING, name, 2) \
|
X(a, STATIC, SINGULAR, STRING, name, 2) \
|
||||||
@@ -634,6 +674,7 @@ extern const pb_msgdesc_t meshtastic_ModuleConfig_StoreForwardConfig_msg;
|
|||||||
extern const pb_msgdesc_t meshtastic_ModuleConfig_RangeTestConfig_msg;
|
extern const pb_msgdesc_t meshtastic_ModuleConfig_RangeTestConfig_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_ModuleConfig_TelemetryConfig_msg;
|
extern const pb_msgdesc_t meshtastic_ModuleConfig_TelemetryConfig_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_ModuleConfig_CannedMessageConfig_msg;
|
extern const pb_msgdesc_t meshtastic_ModuleConfig_CannedMessageConfig_msg;
|
||||||
|
extern const pb_msgdesc_t meshtastic_ModuleConfig_AmbientLightingConfig_msg;
|
||||||
extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg;
|
extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg;
|
||||||
|
|
||||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||||
@@ -648,20 +689,22 @@ extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg;
|
|||||||
#define meshtastic_ModuleConfig_RangeTestConfig_fields &meshtastic_ModuleConfig_RangeTestConfig_msg
|
#define meshtastic_ModuleConfig_RangeTestConfig_fields &meshtastic_ModuleConfig_RangeTestConfig_msg
|
||||||
#define meshtastic_ModuleConfig_TelemetryConfig_fields &meshtastic_ModuleConfig_TelemetryConfig_msg
|
#define meshtastic_ModuleConfig_TelemetryConfig_fields &meshtastic_ModuleConfig_TelemetryConfig_msg
|
||||||
#define meshtastic_ModuleConfig_CannedMessageConfig_fields &meshtastic_ModuleConfig_CannedMessageConfig_msg
|
#define meshtastic_ModuleConfig_CannedMessageConfig_fields &meshtastic_ModuleConfig_CannedMessageConfig_msg
|
||||||
|
#define meshtastic_ModuleConfig_AmbientLightingConfig_fields &meshtastic_ModuleConfig_AmbientLightingConfig_msg
|
||||||
#define meshtastic_RemoteHardwarePin_fields &meshtastic_RemoteHardwarePin_msg
|
#define meshtastic_RemoteHardwarePin_fields &meshtastic_RemoteHardwarePin_msg
|
||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
|
#define meshtastic_ModuleConfig_AmbientLightingConfig_size 14
|
||||||
#define meshtastic_ModuleConfig_AudioConfig_size 19
|
#define meshtastic_ModuleConfig_AudioConfig_size 19
|
||||||
#define meshtastic_ModuleConfig_CannedMessageConfig_size 49
|
#define meshtastic_ModuleConfig_CannedMessageConfig_size 49
|
||||||
#define meshtastic_ModuleConfig_ExternalNotificationConfig_size 40
|
#define meshtastic_ModuleConfig_ExternalNotificationConfig_size 40
|
||||||
#define meshtastic_ModuleConfig_MQTTConfig_size 220
|
#define meshtastic_ModuleConfig_MQTTConfig_size 222
|
||||||
#define meshtastic_ModuleConfig_NeighborInfoConfig_size 8
|
#define meshtastic_ModuleConfig_NeighborInfoConfig_size 8
|
||||||
#define meshtastic_ModuleConfig_RangeTestConfig_size 10
|
#define meshtastic_ModuleConfig_RangeTestConfig_size 10
|
||||||
#define meshtastic_ModuleConfig_RemoteHardwareConfig_size 96
|
#define meshtastic_ModuleConfig_RemoteHardwareConfig_size 96
|
||||||
#define meshtastic_ModuleConfig_SerialConfig_size 28
|
#define meshtastic_ModuleConfig_SerialConfig_size 28
|
||||||
#define meshtastic_ModuleConfig_StoreForwardConfig_size 22
|
#define meshtastic_ModuleConfig_StoreForwardConfig_size 22
|
||||||
#define meshtastic_ModuleConfig_TelemetryConfig_size 26
|
#define meshtastic_ModuleConfig_TelemetryConfig_size 26
|
||||||
#define meshtastic_ModuleConfig_size 223
|
#define meshtastic_ModuleConfig_size 225
|
||||||
#define meshtastic_RemoteHardwarePin_size 21
|
#define meshtastic_RemoteHardwarePin_size 21
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ typedef struct _meshtastic_EnvironmentMetrics {
|
|||||||
float relative_humidity;
|
float relative_humidity;
|
||||||
/* Barometric pressure in hPA measured */
|
/* Barometric pressure in hPA measured */
|
||||||
float barometric_pressure;
|
float barometric_pressure;
|
||||||
/* Gas resistance in mOhm measured */
|
/* Gas resistance in MOhm measured */
|
||||||
float gas_resistance;
|
float gas_resistance;
|
||||||
/* Voltage measured */
|
/* Voltage measured */
|
||||||
float voltage;
|
float voltage;
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res)
|
|||||||
|
|
||||||
if (params->getQueryParameter("all", valueAll)) {
|
if (params->getQueryParameter("all", valueAll)) {
|
||||||
|
|
||||||
// If all is ture, return all the buffers we have available
|
// If all is true, return all the buffers we have available
|
||||||
// to us at this point in time.
|
// to us at this point in time.
|
||||||
if (valueAll == "true") {
|
if (valueAll == "true") {
|
||||||
while (len) {
|
while (len) {
|
||||||
@@ -179,7 +179,7 @@ void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res)
|
|||||||
res->write(txBuf, len);
|
res->write(txBuf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
// the param "all" was not spcified. Return just one protobuf
|
// the param "all" was not specified. Return just one protobuf
|
||||||
} else {
|
} else {
|
||||||
len = webAPI.getFromRadio(txBuf);
|
len = webAPI.getFromRadio(txBuf);
|
||||||
res->write(txBuf, len);
|
res->write(txBuf, len);
|
||||||
@@ -460,7 +460,7 @@ void handleFormUpload(HTTPRequest *req, HTTPResponse *res)
|
|||||||
HTTPBodyParser *parser;
|
HTTPBodyParser *parser;
|
||||||
std::string contentType = req->getHeader("Content-Type");
|
std::string contentType = req->getHeader("Content-Type");
|
||||||
|
|
||||||
// The content type may have additional properties after a semicolon, for exampel:
|
// The content type may have additional properties after a semicolon, for example:
|
||||||
// Content-Type: text/html;charset=utf-8
|
// Content-Type: text/html;charset=utf-8
|
||||||
// Content-Type: multipart/form-data;boundary=------s0m3w31rdch4r4c73rs
|
// Content-Type: multipart/form-data;boundary=------s0m3w31rdch4r4c73rs
|
||||||
// As we're interested only in the actual mime _type_, we strip everything after the
|
// As we're interested only in the actual mime _type_, we strip everything after the
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#include "esp_task_wdt.h"
|
#include "esp_task_wdt.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Persistant Data Storage
|
// Persistent Data Storage
|
||||||
#include <Preferences.h>
|
#include <Preferences.h>
|
||||||
Preferences prefs;
|
Preferences prefs;
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ size_t pb_encode_to_bytes(uint8_t *destbuf, size_t destbufsize, const pb_msgdesc
|
|||||||
if (!pb_encode(&stream, fields, src_struct)) {
|
if (!pb_encode(&stream, fields, src_struct)) {
|
||||||
LOG_ERROR("Panic: can't encode protobuf reason='%s'\n", PB_GET_ERROR(&stream));
|
LOG_ERROR("Panic: can't encode protobuf reason='%s'\n", PB_GET_ERROR(&stream));
|
||||||
assert(
|
assert(
|
||||||
0); // If this asser fails it probably means you made a field too large for the max limits specified in mesh.options
|
0); // If this assert fails it probably means you made a field too large for the max limits specified in mesh.options
|
||||||
} else {
|
} else {
|
||||||
return stream.bytes_written;
|
return stream.bytes_written;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,7 @@
|
|||||||
#include "unistd.h"
|
#include "unistd.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_WIFI || HAS_ETHERNET
|
|
||||||
#include "mqtt/MQTT.h"
|
#include "mqtt/MQTT.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DEFAULT_REBOOT_SECONDS 7
|
#define DEFAULT_REBOOT_SECONDS 7
|
||||||
|
|
||||||
@@ -567,7 +565,7 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r
|
|||||||
if (conn.wifi.status.is_connected) {
|
if (conn.wifi.status.is_connected) {
|
||||||
conn.wifi.rssi = WiFi.RSSI();
|
conn.wifi.rssi = WiFi.RSSI();
|
||||||
conn.wifi.status.ip_address = WiFi.localIP();
|
conn.wifi.status.ip_address = WiFi.localIP();
|
||||||
conn.wifi.status.is_mqtt_connected = mqtt && mqtt->connected();
|
conn.wifi.status.is_mqtt_connected = mqtt && mqtt->isConnectedDirectly();
|
||||||
conn.wifi.status.is_syslog_connected = false; // FIXME wire this up
|
conn.wifi.status.is_syslog_connected = false; // FIXME wire this up
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -578,7 +576,7 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r
|
|||||||
if (Ethernet.linkStatus() == LinkON) {
|
if (Ethernet.linkStatus() == LinkON) {
|
||||||
conn.ethernet.status.is_connected = true;
|
conn.ethernet.status.is_connected = true;
|
||||||
conn.ethernet.status.ip_address = Ethernet.localIP();
|
conn.ethernet.status.ip_address = Ethernet.localIP();
|
||||||
conn.ethernet.status.is_mqtt_connected = mqtt && mqtt->connected();
|
conn.ethernet.status.is_mqtt_connected = mqtt && mqtt->isConnectedDirectly();
|
||||||
conn.ethernet.status.is_syslog_connected = false; // FIXME wire this up
|
conn.ethernet.status.is_syslog_connected = false; // FIXME wire this up
|
||||||
} else {
|
} else {
|
||||||
conn.ethernet.status.is_connected = false;
|
conn.ethernet.status.is_connected = false;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include "FSCommon.h"
|
#include "FSCommon.h"
|
||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "PowerFSM.h" // neede for button bypass
|
#include "PowerFSM.h" // needed for button bypass
|
||||||
#include "detect/ScanI2C.h"
|
#include "detect/ScanI2C.h"
|
||||||
#include "mesh/generated/meshtastic/cannedmessages.pb.h"
|
#include "mesh/generated/meshtastic/cannedmessages.pb.h"
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
#include "graphics/fonts/OLEDDisplayFontsUA.h"
|
#include "graphics/fonts/OLEDDisplayFontsUA.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
|
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS) || defined(ST7789_CS)
|
||||||
// The screen is bigger so use bigger fonts
|
// The screen is bigger so use bigger fonts
|
||||||
#define FONT_SMALL ArialMT_Plain_16
|
#define FONT_SMALL ArialMT_Plain_16
|
||||||
#define FONT_MEDIUM ArialMT_Plain_24
|
#define FONT_MEDIUM ArialMT_Plain_24
|
||||||
@@ -123,8 +123,8 @@ int CannedMessageModule::splitConfiguredMessages()
|
|||||||
int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
||||||
{
|
{
|
||||||
if ((strlen(moduleConfig.canned_message.allow_input_source) > 0) &&
|
if ((strlen(moduleConfig.canned_message.allow_input_source) > 0) &&
|
||||||
(strcmp(moduleConfig.canned_message.allow_input_source, event->source) != 0) &&
|
(strcasecmp(moduleConfig.canned_message.allow_input_source, event->source) != 0) &&
|
||||||
(strcmp(moduleConfig.canned_message.allow_input_source, "_any") != 0)) {
|
(strcasecmp(moduleConfig.canned_message.allow_input_source, "_any") != 0)) {
|
||||||
// Event source is not accepted.
|
// Event source is not accepted.
|
||||||
// Event only accepted if source matches the configured one, or
|
// Event only accepted if source matches the configured one, or
|
||||||
// the configured one is "_any" (or if there is no configured
|
// the configured one is "_any" (or if there is no configured
|
||||||
@@ -164,12 +164,21 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
|||||||
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) ||
|
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) ||
|
||||||
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) {
|
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) {
|
||||||
LOG_DEBUG("Canned message event (%x)\n", event->kbchar);
|
LOG_DEBUG("Canned message event (%x)\n", event->kbchar);
|
||||||
if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
// tweak for left/right events generated via trackball/touch with empty kbchar
|
||||||
|
if (!event->kbchar) {
|
||||||
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
||||||
|
this->payload = 0xb4;
|
||||||
|
this->destSelect = true;
|
||||||
|
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
|
||||||
|
this->payload = 0xb7;
|
||||||
|
this->destSelect = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// pass the pressed key
|
// pass the pressed key
|
||||||
this->payload = event->kbchar;
|
this->payload = event->kbchar;
|
||||||
this->lastTouchMillis = millis();
|
|
||||||
validEvent = true;
|
|
||||||
}
|
}
|
||||||
|
this->lastTouchMillis = millis();
|
||||||
|
validEvent = true;
|
||||||
}
|
}
|
||||||
if (event->inputEvent == static_cast<char>(ANYKEY)) {
|
if (event->inputEvent == static_cast<char>(ANYKEY)) {
|
||||||
LOG_DEBUG("Canned message event any key pressed\n");
|
LOG_DEBUG("Canned message event any key pressed\n");
|
||||||
@@ -225,7 +234,7 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
(this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE)) {
|
(this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE)) {
|
||||||
return INT32_MAX;
|
return INT32_MAX;
|
||||||
}
|
}
|
||||||
LOG_DEBUG("Check status\n");
|
// LOG_DEBUG("Check status\n");
|
||||||
UIFrameEvent e = {false, true};
|
UIFrameEvent e = {false, true};
|
||||||
if (this->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) {
|
if (this->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) {
|
||||||
// TODO: might have some feedback of sendig state
|
// TODO: might have some feedback of sendig state
|
||||||
@@ -300,8 +309,7 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
||||||
LOG_DEBUG("MOVE DOWN (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
LOG_DEBUG("MOVE DOWN (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
||||||
}
|
}
|
||||||
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT || this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) {
|
||||||
e.frameChanged = true;
|
|
||||||
switch (this->payload) {
|
switch (this->payload) {
|
||||||
case 0xb4: // left
|
case 0xb4: // left
|
||||||
if (this->destSelect) {
|
if (this->destSelect) {
|
||||||
@@ -347,38 +355,49 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x08: // backspace
|
|
||||||
if (this->freetext.length() > 0) {
|
|
||||||
if (this->cursor == this->freetext.length()) {
|
|
||||||
this->freetext = this->freetext.substring(0, this->freetext.length() - 1);
|
|
||||||
} else {
|
|
||||||
this->freetext = this->freetext.substring(0, this->cursor - 1) +
|
|
||||||
this->freetext.substring(this->cursor, this->freetext.length());
|
|
||||||
}
|
|
||||||
this->cursor--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x09: // tab
|
|
||||||
if (this->destSelect) {
|
|
||||||
this->destSelect = false;
|
|
||||||
} else {
|
|
||||||
this->destSelect = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
if (this->cursor == this->freetext.length()) {
|
|
||||||
this->freetext += this->payload;
|
|
||||||
} else {
|
|
||||||
this->freetext =
|
|
||||||
this->freetext.substring(0, this->cursor) + this->payload + this->freetext.substring(this->cursor);
|
|
||||||
}
|
|
||||||
this->cursor += 1;
|
|
||||||
if (this->freetext.length() > meshtastic_Constants_DATA_PAYLOAD_LEN) {
|
|
||||||
this->cursor = meshtastic_Constants_DATA_PAYLOAD_LEN;
|
|
||||||
this->freetext = this->freetext.substring(0, meshtastic_Constants_DATA_PAYLOAD_LEN);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
||||||
|
e.frameChanged = true;
|
||||||
|
switch (this->payload) {
|
||||||
|
case 0x08: // backspace
|
||||||
|
if (this->freetext.length() > 0) {
|
||||||
|
if (this->cursor == this->freetext.length()) {
|
||||||
|
this->freetext = this->freetext.substring(0, this->freetext.length() - 1);
|
||||||
|
} else {
|
||||||
|
this->freetext = this->freetext.substring(0, this->cursor - 1) +
|
||||||
|
this->freetext.substring(this->cursor, this->freetext.length());
|
||||||
|
}
|
||||||
|
this->cursor--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x09: // tab
|
||||||
|
if (this->destSelect) {
|
||||||
|
this->destSelect = false;
|
||||||
|
} else {
|
||||||
|
this->destSelect = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xb4: // left
|
||||||
|
case 0xb7: // right
|
||||||
|
// already handled above
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (this->cursor == this->freetext.length()) {
|
||||||
|
this->freetext += this->payload;
|
||||||
|
} else {
|
||||||
|
this->freetext =
|
||||||
|
this->freetext.substring(0, this->cursor) + this->payload + this->freetext.substring(this->cursor);
|
||||||
|
}
|
||||||
|
this->cursor += 1;
|
||||||
|
if (this->freetext.length() > meshtastic_Constants_DATA_PAYLOAD_LEN) {
|
||||||
|
this->cursor = meshtastic_Constants_DATA_PAYLOAD_LEN;
|
||||||
|
this->freetext = this->freetext.substring(0, meshtastic_Constants_DATA_PAYLOAD_LEN);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this->lastTouchMillis = millis();
|
this->lastTouchMillis = millis();
|
||||||
this->notifyObservers(&e);
|
this->notifyObservers(&e);
|
||||||
@@ -406,6 +425,11 @@ const char *CannedMessageModule::getNextMessage()
|
|||||||
{
|
{
|
||||||
return this->messages[this->getNextIndex()];
|
return this->messages[this->getNextIndex()];
|
||||||
}
|
}
|
||||||
|
const char *CannedMessageModule::getMessageByIndex(int index)
|
||||||
|
{
|
||||||
|
return (index >= 0 && index < this->messagesCount) ? this->messages[index] : "";
|
||||||
|
}
|
||||||
|
|
||||||
const char *CannedMessageModule::getNodeName(NodeNum node)
|
const char *CannedMessageModule::getNodeName(NodeNum node)
|
||||||
{
|
{
|
||||||
if (node == NODENUM_BROADCAST) {
|
if (node == NODENUM_BROADCAST) {
|
||||||
@@ -482,12 +506,31 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
|||||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||||
display->setFont(FONT_SMALL);
|
display->setFont(FONT_SMALL);
|
||||||
display->drawStringf(0 + x, 0 + y, buffer, "To: %s", cannedMessageModule->getNodeName(this->dest));
|
display->drawStringf(0 + x, 0 + y, buffer, "To: %s", cannedMessageModule->getNodeName(this->dest));
|
||||||
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL, cannedMessageModule->getPrevMessage());
|
int lines = (display->getHeight() / FONT_HEIGHT_SMALL) - 1;
|
||||||
display->fillRect(0 + x, 0 + y + FONT_HEIGHT_SMALL * 2, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
|
if (lines == 3) {
|
||||||
display->setColor(BLACK);
|
// static (old) behavior for small displays
|
||||||
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * 2, cannedMessageModule->getCurrentMessage());
|
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL, cannedMessageModule->getPrevMessage());
|
||||||
display->setColor(WHITE);
|
display->fillRect(0 + x, 0 + y + FONT_HEIGHT_SMALL * 2, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
|
||||||
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * 3, cannedMessageModule->getNextMessage());
|
display->setColor(BLACK);
|
||||||
|
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * 2, cannedMessageModule->getCurrentMessage());
|
||||||
|
display->setColor(WHITE);
|
||||||
|
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * 3, cannedMessageModule->getNextMessage());
|
||||||
|
} else {
|
||||||
|
// use entire display height for larger displays
|
||||||
|
int topMsg = (messagesCount > lines && currentMessageIndex >= lines - 1) ? currentMessageIndex - lines + 2 : 0;
|
||||||
|
for (int i = 0; i < std::min(messagesCount, lines); i++) {
|
||||||
|
if (i == currentMessageIndex - topMsg) {
|
||||||
|
display->fillRect(0 + x, 0 + y + FONT_HEIGHT_SMALL * (i + 1), x + display->getWidth(),
|
||||||
|
y + FONT_HEIGHT_SMALL);
|
||||||
|
display->setColor(BLACK);
|
||||||
|
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * (i + 1), cannedMessageModule->getCurrentMessage());
|
||||||
|
display->setColor(WHITE);
|
||||||
|
} else {
|
||||||
|
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * (i + 1),
|
||||||
|
cannedMessageModule->getMessageByIndex(topMsg + i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
|
|||||||
const char *getCurrentMessage();
|
const char *getCurrentMessage();
|
||||||
const char *getPrevMessage();
|
const char *getPrevMessage();
|
||||||
const char *getNextMessage();
|
const char *getNextMessage();
|
||||||
|
const char *getMessageByIndex(int index);
|
||||||
const char *getNodeName(NodeNum node);
|
const char *getNodeName(NodeNum node);
|
||||||
bool shouldDraw();
|
bool shouldDraw();
|
||||||
void eventUp();
|
void eventUp();
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
#ifdef RAK4630
|
#ifdef HAS_NCP5623
|
||||||
#include <graphics/RAKled.h>
|
#include <graphics/RAKled.h>
|
||||||
NCP5623 rgb;
|
NCP5623 rgb;
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ int32_t ExternalNotificationModule::runOnce()
|
|||||||
millis()) {
|
millis()) {
|
||||||
getExternal(2) ? setExternalOff(2) : setExternalOn(2);
|
getExternal(2) ? setExternalOff(2) : setExternalOn(2);
|
||||||
}
|
}
|
||||||
#ifdef RAK4630
|
#ifdef HAS_NCP5623
|
||||||
if (rgb_found.type == ScanI2C::NCP5623) {
|
if (rgb_found.type == ScanI2C::NCP5623) {
|
||||||
green = (green + 50) % 255;
|
green = (green + 50) % 255;
|
||||||
red = abs(red - green) % 255;
|
red = abs(red - green) % 255;
|
||||||
@@ -93,6 +93,10 @@ int32_t ExternalNotificationModule::runOnce()
|
|||||||
rgb.setColor(red, green, blue);
|
rgb.setColor(red, green, blue);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
drv.go();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// now let the PWM buzzer play
|
// now let the PWM buzzer play
|
||||||
@@ -124,14 +128,18 @@ void ExternalNotificationModule::setExternalOn(uint8_t index)
|
|||||||
digitalWrite(moduleConfig.external_notification.output_buzzer, true);
|
digitalWrite(moduleConfig.external_notification.output_buzzer, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
digitalWrite(output, (moduleConfig.external_notification.active ? true : false));
|
if (output > 0)
|
||||||
|
digitalWrite(output, (moduleConfig.external_notification.active ? true : false));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef RAK4630
|
#ifdef HAS_NCP5623
|
||||||
if (rgb_found.type == ScanI2C::NCP5623) {
|
if (rgb_found.type == ScanI2C::NCP5623) {
|
||||||
rgb.setColor(red, green, blue);
|
rgb.setColor(red, green, blue);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
drv.go();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExternalNotificationModule::setExternalOff(uint8_t index)
|
void ExternalNotificationModule::setExternalOff(uint8_t index)
|
||||||
@@ -149,11 +157,12 @@ void ExternalNotificationModule::setExternalOff(uint8_t index)
|
|||||||
digitalWrite(moduleConfig.external_notification.output_buzzer, false);
|
digitalWrite(moduleConfig.external_notification.output_buzzer, false);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
digitalWrite(output, (moduleConfig.external_notification.active ? false : true));
|
if (output > 0)
|
||||||
|
digitalWrite(output, (moduleConfig.external_notification.active ? false : true));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RAK4630
|
#ifdef HAS_NCP5623
|
||||||
if (rgb_found.type == ScanI2C::NCP5623) {
|
if (rgb_found.type == ScanI2C::NCP5623) {
|
||||||
red = 0;
|
red = 0;
|
||||||
green = 0;
|
green = 0;
|
||||||
@@ -161,6 +170,9 @@ void ExternalNotificationModule::setExternalOff(uint8_t index)
|
|||||||
rgb.setColor(red, green, blue);
|
rgb.setColor(red, green, blue);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
drv.stop();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExternalNotificationModule::getExternal(uint8_t index)
|
bool ExternalNotificationModule::getExternal(uint8_t index)
|
||||||
@@ -174,6 +186,9 @@ void ExternalNotificationModule::stopNow()
|
|||||||
nagCycleCutoff = 1; // small value
|
nagCycleCutoff = 1; // small value
|
||||||
isNagging = false;
|
isNagging = false;
|
||||||
setIntervalFromNow(0);
|
setIntervalFromNow(0);
|
||||||
|
#ifdef T_WATCH_S3
|
||||||
|
drv.stop();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ExternalNotificationModule::ExternalNotificationModule()
|
ExternalNotificationModule::ExternalNotificationModule()
|
||||||
@@ -185,7 +200,6 @@ ExternalNotificationModule::ExternalNotificationModule()
|
|||||||
without having to configure it from the PythonAPI or WebUI.
|
without having to configure it from the PythonAPI or WebUI.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// moduleConfig.external_notification.enabled = true;
|
|
||||||
// moduleConfig.external_notification.alert_message = true;
|
// moduleConfig.external_notification.alert_message = true;
|
||||||
// moduleConfig.external_notification.alert_message_buzzer = true;
|
// moduleConfig.external_notification.alert_message_buzzer = true;
|
||||||
// moduleConfig.external_notification.alert_message_vibra = true;
|
// moduleConfig.external_notification.alert_message_vibra = true;
|
||||||
@@ -213,8 +227,10 @@ ExternalNotificationModule::ExternalNotificationModule()
|
|||||||
: EXT_NOTIFICATION_MODULE_OUTPUT;
|
: EXT_NOTIFICATION_MODULE_OUTPUT;
|
||||||
|
|
||||||
// Set the direction of a pin
|
// Set the direction of a pin
|
||||||
LOG_INFO("Using Pin %i in digital mode\n", output);
|
if (output > 0) {
|
||||||
pinMode(output, OUTPUT);
|
LOG_INFO("Using Pin %i in digital mode\n", output);
|
||||||
|
pinMode(output, OUTPUT);
|
||||||
|
}
|
||||||
setExternalOff(0);
|
setExternalOff(0);
|
||||||
externalTurnedOn[0] = 0;
|
externalTurnedOn[0] = 0;
|
||||||
if (moduleConfig.external_notification.output_vibra) {
|
if (moduleConfig.external_notification.output_vibra) {
|
||||||
@@ -235,7 +251,7 @@ ExternalNotificationModule::ExternalNotificationModule()
|
|||||||
LOG_INFO("Using Pin %i in PWM mode\n", config.device.buzzer_gpio);
|
LOG_INFO("Using Pin %i in PWM mode\n", config.device.buzzer_gpio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef RAK4630
|
#ifdef HAS_NCP5623
|
||||||
if (rgb_found.type == ScanI2C::NCP5623) {
|
if (rgb_found.type == ScanI2C::NCP5623) {
|
||||||
rgb.begin();
|
rgb.begin();
|
||||||
rgb.setCurrent(10);
|
rgb.setCurrent(10);
|
||||||
@@ -250,7 +266,12 @@ ExternalNotificationModule::ExternalNotificationModule()
|
|||||||
ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshPacket &mp)
|
ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshPacket &mp)
|
||||||
{
|
{
|
||||||
if (moduleConfig.external_notification.enabled) {
|
if (moduleConfig.external_notification.enabled) {
|
||||||
|
#if T_WATCH_S3
|
||||||
|
drv.setWaveform(0, 75);
|
||||||
|
drv.setWaveform(1, 56);
|
||||||
|
drv.setWaveform(2, 0);
|
||||||
|
drv.go();
|
||||||
|
#endif
|
||||||
if (getFrom(&mp) != nodeDB.getNodeNum()) {
|
if (getFrom(&mp) != nodeDB.getNodeNum()) {
|
||||||
|
|
||||||
// Check if the message contains a bell character. Don't do this loop for every pin, just once.
|
// Check if the message contains a bell character. Don't do this loop for every pin, just once.
|
||||||
@@ -343,7 +364,6 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
|
|||||||
}
|
}
|
||||||
setIntervalFromNow(0); // run once so we know if we should do something
|
setIntervalFromNow(0); // run once so we know if we should do something
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("External Notification Module Disabled\n");
|
LOG_INFO("External Notification Module Disabled\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "input/InputBroker.h"
|
#include "input/InputBroker.h"
|
||||||
#include "input/RotaryEncoderInterruptImpl1.h"
|
#include "input/RotaryEncoderInterruptImpl1.h"
|
||||||
|
#include "input/TrackballInterruptImpl1.h"
|
||||||
#include "input/UpDownInterruptImpl1.h"
|
#include "input/UpDownInterruptImpl1.h"
|
||||||
#include "input/cardKbI2cImpl.h"
|
#include "input/cardKbI2cImpl.h"
|
||||||
#include "modules/AdminModule.h"
|
#include "modules/AdminModule.h"
|
||||||
@@ -24,7 +25,7 @@
|
|||||||
#include "modules/esp32/AudioModule.h"
|
#include "modules/esp32/AudioModule.h"
|
||||||
#include "modules/esp32/StoreForwardModule.h"
|
#include "modules/esp32/StoreForwardModule.h"
|
||||||
#endif
|
#endif
|
||||||
#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
|
#if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)
|
||||||
#include "modules/ExternalNotificationModule.h"
|
#include "modules/ExternalNotificationModule.h"
|
||||||
#include "modules/RangeTestModule.h"
|
#include "modules/RangeTestModule.h"
|
||||||
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2)
|
#if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||||
@@ -60,6 +61,10 @@ void setupModules()
|
|||||||
cardKbI2cImpl = new CardKbI2cImpl();
|
cardKbI2cImpl = new CardKbI2cImpl();
|
||||||
cardKbI2cImpl->init();
|
cardKbI2cImpl->init();
|
||||||
#endif
|
#endif
|
||||||
|
#if HAS_TRACKBALL
|
||||||
|
trackballInterruptImpl1 = new TrackballInterruptImpl1();
|
||||||
|
trackballInterruptImpl1->init();
|
||||||
|
#endif
|
||||||
#if HAS_SCREEN
|
#if HAS_SCREEN
|
||||||
cannedMessageModule = new CannedMessageModule();
|
cannedMessageModule = new CannedMessageModule();
|
||||||
#endif
|
#endif
|
||||||
@@ -81,7 +86,7 @@ void setupModules()
|
|||||||
|
|
||||||
storeForwardModule = new StoreForwardModule();
|
storeForwardModule = new StoreForwardModule();
|
||||||
#endif
|
#endif
|
||||||
#if defined(ARCH_ESP32) || defined(ARCH_NRF52)
|
#if defined(ARCH_ESP32) || defined(ARCH_NRF52) || defined(ARCH_RP2040)
|
||||||
externalNotificationModule = new ExternalNotificationModule();
|
externalNotificationModule = new ExternalNotificationModule();
|
||||||
new RangeTestModule();
|
new RangeTestModule();
|
||||||
#endif
|
#endif
|
||||||
@@ -92,4 +97,4 @@ void setupModules()
|
|||||||
// NOTE! This module must be added LAST because it likes to check for replies from other modules and avoid sending extra
|
// NOTE! This module must be added LAST because it likes to check for replies from other modules and avoid sending extra
|
||||||
// acks
|
// acks
|
||||||
routingModule = new RoutingModule();
|
routingModule = new RoutingModule();
|
||||||
}
|
}
|
||||||
@@ -52,11 +52,22 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
|
|||||||
|
|
||||||
nodeDB.updatePosition(getFrom(&mp), p);
|
nodeDB.updatePosition(getFrom(&mp), p);
|
||||||
|
|
||||||
|
// Only respond to location requests on the channel where we broadcast location.
|
||||||
|
if (channels.getByIndex(mp.channel).role == meshtastic_Channel_Role_PRIMARY) {
|
||||||
|
ignoreRequest = false;
|
||||||
|
} else {
|
||||||
|
ignoreRequest = true;
|
||||||
|
}
|
||||||
|
|
||||||
return false; // Let others look at this message also if they want
|
return false; // Let others look at this message also if they want
|
||||||
}
|
}
|
||||||
|
|
||||||
meshtastic_MeshPacket *PositionModule::allocReply()
|
meshtastic_MeshPacket *PositionModule::allocReply()
|
||||||
{
|
{
|
||||||
|
if (ignoreRequest) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
meshtastic_NodeInfoLite *node = service.refreshLocalMeshNode(); // should guarantee there is now a position
|
meshtastic_NodeInfoLite *node = service.refreshLocalMeshNode(); // should guarantee there is now a position
|
||||||
assert(node->has_position);
|
assert(node->has_position);
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user