mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-10 20:07:45 +00:00
Compare commits
216 Commits
v2.3.4.ea6
...
v2.3.9.f06
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f06c56a51b | ||
|
|
ac22a503de | ||
|
|
676319a9ca | ||
|
|
5d9800b7c2 | ||
|
|
0c89aff0f6 | ||
|
|
5e160b21c7 | ||
|
|
75dc8cccec | ||
|
|
147de75a02 | ||
|
|
5371f134ba | ||
|
|
8105c0440a | ||
|
|
cbf20e4cee | ||
|
|
c009c0db1e | ||
|
|
2c99f11073 | ||
|
|
0d57d29cbd | ||
|
|
353c7e07d1 | ||
|
|
77a66e1dce | ||
|
|
e98c3bf5d0 | ||
|
|
5e9d48d0d7 | ||
|
|
8e91f895a6 | ||
|
|
b155a5b6dc | ||
|
|
2c30923e3e | ||
|
|
0afe2d459f | ||
|
|
0b239e618d | ||
|
|
e9ebdfeff2 | ||
|
|
6fb7d7f2d7 | ||
|
|
70712d859c | ||
|
|
4d9081b3b1 | ||
|
|
7643a1acb1 | ||
|
|
61216e579e | ||
|
|
e31bb2d513 | ||
|
|
a8c38c4580 | ||
|
|
85e0372d26 | ||
|
|
53bd9de9b8 | ||
|
|
13ad524538 | ||
|
|
5f90f45ac4 | ||
|
|
dc0593c5a7 | ||
|
|
df3cceb108 | ||
|
|
827dcfca4a | ||
|
|
9fb6148aff | ||
|
|
6c1377aa39 | ||
|
|
077ca5919a | ||
|
|
668b716119 | ||
|
|
eaa7e21bc7 | ||
|
|
be0e882be1 | ||
|
|
09080d76ad | ||
|
|
d490a332a7 | ||
|
|
5dfa4b837f | ||
|
|
9501f3bda9 | ||
|
|
b69a1cada9 | ||
|
|
06e7d2b845 | ||
|
|
71400103b3 | ||
|
|
40e361e6d0 | ||
|
|
d1b6f11429 | ||
|
|
0527fb10ce | ||
|
|
5f929a8024 | ||
|
|
4f54862d63 | ||
|
|
0f4ac94559 | ||
|
|
45c1b46bd0 | ||
|
|
5095efc55f | ||
|
|
ec92f7a5a3 | ||
|
|
57da37cfbc | ||
|
|
3619ac87b8 | ||
|
|
e51ee91c39 | ||
|
|
21311bbeda | ||
|
|
472db5b237 | ||
|
|
18e69a0906 | ||
|
|
93f77ea7d2 | ||
|
|
ee4c4ae6c9 | ||
|
|
6cc7dee95c | ||
|
|
38c4d35a7b | ||
|
|
e683d8f552 | ||
|
|
e66aec8223 | ||
|
|
a06a01d25e | ||
|
|
f8c3f43ea6 | ||
|
|
dfcabba0b2 | ||
|
|
827bacdfc8 | ||
|
|
5806a266d3 | ||
|
|
30fbcabf84 | ||
|
|
c14043f196 | ||
|
|
e3610a2eb1 | ||
|
|
9baccc80d8 | ||
|
|
ac16ccf40c | ||
|
|
1c0227f90c | ||
|
|
57d296e0db | ||
|
|
9c9d126f6b | ||
|
|
27f0e42d2f | ||
|
|
4599534616 | ||
|
|
7acaec8ef5 | ||
|
|
d0e81b9151 | ||
|
|
c6e940af81 | ||
|
|
3302fbcc53 | ||
|
|
ccbf635eef | ||
|
|
6669b22db3 | ||
|
|
ec2b854ea2 | ||
|
|
378a2d723e | ||
|
|
5dd08e9533 | ||
|
|
125add9792 | ||
|
|
250cf16bf8 | ||
|
|
8b5fad21b0 | ||
|
|
30d4c3a945 | ||
|
|
45fd5e25ac | ||
|
|
ac6a668362 | ||
|
|
f47b40cf68 | ||
|
|
fd9461505f | ||
|
|
84edaabfe9 | ||
|
|
048f0a1601 | ||
|
|
4a48a3fb52 | ||
|
|
39bbf0d352 | ||
|
|
675d8fe089 | ||
|
|
0406be82d2 | ||
|
|
679e068e19 | ||
|
|
952393ca0f | ||
|
|
a231cd2ad0 | ||
|
|
ac87c0065f | ||
|
|
9822a85274 | ||
|
|
a957065fe8 | ||
|
|
41f3557491 | ||
|
|
402b0d7e0b | ||
|
|
13ebda6b2f | ||
|
|
1dd19cec6e | ||
|
|
df718ab294 | ||
|
|
dfc43bae18 | ||
|
|
f6cfdfe881 | ||
|
|
820c5dc8c5 | ||
|
|
1f9c295c9e | ||
|
|
5218aaafcf | ||
|
|
c480f0870c | ||
|
|
9e4ef92e6d | ||
|
|
cf65661c7c | ||
|
|
fb7a878d94 | ||
|
|
e72792afc8 | ||
|
|
ec39e1136a | ||
|
|
94e1f016e5 | ||
|
|
9170fe0580 | ||
|
|
ef9808cdd6 | ||
|
|
0972a8dccb | ||
|
|
419eb13968 | ||
|
|
e7828c4c64 | ||
|
|
44aa248099 | ||
|
|
e0513d4078 | ||
|
|
2100f3135e | ||
|
|
2f36d4990e | ||
|
|
65bde8538f | ||
|
|
7a3570aecf | ||
|
|
4a471ded79 | ||
|
|
eea85d26ca | ||
|
|
64edfb76e0 | ||
|
|
8ac308e73b | ||
|
|
0ae7674982 | ||
|
|
e4b5f2ce14 | ||
|
|
7d77b23eb6 | ||
|
|
a149999cec | ||
|
|
78d915b454 | ||
|
|
4c0b7ea409 | ||
|
|
425a715995 | ||
|
|
2e13aeeacb | ||
|
|
747c713ba9 | ||
|
|
4b5549be8f | ||
|
|
172d271b0b | ||
|
|
2e14234b77 | ||
|
|
d47e9bed19 | ||
|
|
bc085ab840 | ||
|
|
2450031b1b | ||
|
|
2cd877d2eb | ||
|
|
c34956e9d8 | ||
|
|
afb4de21d9 | ||
|
|
86223d8806 | ||
|
|
0632b96fcb | ||
|
|
dcfc9c9f03 | ||
|
|
8a3322fbcb | ||
|
|
55c9c3b298 | ||
|
|
9599549477 | ||
|
|
e813703bf5 | ||
|
|
699ea74672 | ||
|
|
a01069a549 | ||
|
|
3413b9da41 | ||
|
|
7d3175dc83 | ||
|
|
441638c2eb | ||
|
|
2f9b68e08b | ||
|
|
27ae4399bc | ||
|
|
385d7296fe | ||
|
|
d1cd686644 | ||
|
|
1291da746b | ||
|
|
2803fa964e | ||
|
|
1d97544041 | ||
|
|
5b52c31a76 | ||
|
|
00d4c011c7 | ||
|
|
1447148811 | ||
|
|
4f205718f0 | ||
|
|
5047468d9f | ||
|
|
ec3971bce5 | ||
|
|
0a246bfe9b | ||
|
|
f1a1834ee2 | ||
|
|
2a6e26620e | ||
|
|
3f45c2d4f0 | ||
|
|
11adfe05ce | ||
|
|
b4009f9f2f | ||
|
|
917b739e62 | ||
|
|
2c4db16336 | ||
|
|
4c9646f7d9 | ||
|
|
8fd32f3452 | ||
|
|
178877f2d9 | ||
|
|
6de0363eea | ||
|
|
f4a2023dba | ||
|
|
927d07e2c6 | ||
|
|
a4a8556aa2 | ||
|
|
8e29efcb50 | ||
|
|
3bee6ce9c3 | ||
|
|
fcab20fb3b | ||
|
|
2d81c97b98 | ||
|
|
cfd98b2c91 | ||
|
|
6e7405e56b | ||
|
|
77082e35f5 | ||
|
|
daa64b055a | ||
|
|
ec74fba2bd | ||
|
|
e89575bfd1 |
1
.github/workflows/main_matrix.yml
vendored
1
.github/workflows/main_matrix.yml
vendored
@@ -100,6 +100,7 @@ jobs:
|
||||
- board: t-deck
|
||||
- board: picomputer-s3
|
||||
- board: station-g2
|
||||
- board: unphone
|
||||
uses: ./.github/workflows/build_esp32_s3.yml
|
||||
with:
|
||||
board: ${{ matrix.board }}
|
||||
|
||||
2
.github/workflows/package_raspbian.yml
vendored
2
.github/workflows/package_raspbian.yml
vendored
@@ -45,6 +45,7 @@ jobs:
|
||||
|
||||
- name: build .debpkg
|
||||
run: |
|
||||
mkdir -p .debpkg/debian
|
||||
mkdir -p .debpkg/usr/share/doc/meshtasticd/web
|
||||
mkdir -p .debpkg/usr/sbin
|
||||
mkdir -p .debpkg/etc/meshtasticd
|
||||
@@ -55,6 +56,7 @@ jobs:
|
||||
cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml
|
||||
chmod +x .debpkg/usr/sbin/meshtasticd
|
||||
cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service
|
||||
echo "etc/meshtasticd/config.yaml" > .debpkg/debian/conffiles
|
||||
|
||||
- uses: jiro4989/build-deb-action@v3
|
||||
with:
|
||||
|
||||
6
.github/workflows/update_protobufs.yml
vendored
6
.github/workflows/update_protobufs.yml
vendored
@@ -17,9 +17,9 @@ jobs:
|
||||
|
||||
- name: Download nanopb
|
||||
run: |
|
||||
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.7-linux-x86.tar.gz
|
||||
tar xvzf nanopb-0.4.7-linux-x86.tar.gz
|
||||
mv nanopb-0.4.7-linux-x86 nanopb-0.4.7
|
||||
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8-linux-x86.tar.gz
|
||||
tar xvzf nanopb-0.4.8-linux-x86.tar.gz
|
||||
mv nanopb-0.4.8-linux-x86 nanopb-0.4.8
|
||||
|
||||
- name: Re-generate protocol buffers
|
||||
run: |
|
||||
|
||||
@@ -2,14 +2,17 @@
|
||||
extends = esp32_base
|
||||
|
||||
build_src_filter =
|
||||
${esp32_base.build_src_filter} -<nimble/> -<mesh/raspihttp>
|
||||
${esp32_base.build_src_filter} - <libpax/> -<nimble/> -<mesh/raspihttp>
|
||||
|
||||
monitor_speed = 115200
|
||||
|
||||
build_flags =
|
||||
${esp32_base.build_flags}
|
||||
-DHAS_BLUETOOTH=0
|
||||
-DMESHTASTIC_EXCLUDE_PAXCOUNTER
|
||||
-DMESHTASTIC_EXCLUDE_BLUETOOTH
|
||||
|
||||
lib_ignore =
|
||||
${esp32_base.lib_ignore}
|
||||
NimBLE-Arduino
|
||||
NimBLE-Arduino
|
||||
libpax
|
||||
@@ -3,7 +3,7 @@
|
||||
platform = platformio/nordicnrf52@^10.4.0
|
||||
extends = arduino_base
|
||||
|
||||
build_type = debug ; I'm debugging with ICE a lot now
|
||||
build_type = debug
|
||||
build_flags =
|
||||
${arduino_base.build_flags}
|
||||
-DSERIAL_BUFFER_SIZE=1024
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
; The Portduino based sim environment on top of any host OS, all hardware will be simulated
|
||||
[portduino_base]
|
||||
platform = https://github.com/meshtastic/platform-native.git#117acc5e7fcc2047e9ba1dc11789daea26fc36d2
|
||||
platform = https://github.com/meshtastic/platform-native.git#9881bf3721d610cccacf5ae8e3a07839cce75d63
|
||||
framework = arduino
|
||||
|
||||
build_src_filter =
|
||||
@@ -24,7 +24,7 @@ lib_deps =
|
||||
${env.lib_deps}
|
||||
${networking_base.lib_deps}
|
||||
rweather/Crypto@^0.4.0
|
||||
lovyan03/LovyanGFX@^1.1.12
|
||||
https://github.com/lovyan03/LovyanGFX.git#5a39989aa2c9492572255b22f033843ec8900233
|
||||
|
||||
build_flags =
|
||||
${arduino_base.build_flags}
|
||||
|
||||
@@ -38,11 +38,22 @@ Lora:
|
||||
# Busy: 20
|
||||
# Reset: 18
|
||||
|
||||
# Module: sx1268 # SX1268-based modules, tested with Ebyte E22 400M33S
|
||||
# CS: 21
|
||||
# IRQ: 16
|
||||
# Busy: 20
|
||||
# Reset: 18
|
||||
# TXen: 6
|
||||
# RXen: 12
|
||||
# DIO3_TCXO_VOLTAGE: true
|
||||
|
||||
# DIO3_TCXO_VOLTAGE: true # the Waveshare Core1262 and others are known to need this setting
|
||||
|
||||
# TXen: x # TX and RX enable pins
|
||||
# RXen: x
|
||||
|
||||
# ch341_quirk: true # Uncomment this to use the chunked SPI transfer that seems to fix the ch341
|
||||
|
||||
### Set gpio chip to use in /dev/. Defaults to 0.
|
||||
### Notably the Raspberry Pi 5 puts the GPIO header on gpiochip4
|
||||
# gpiochip: 4
|
||||
@@ -96,23 +107,29 @@ Display:
|
||||
# Panel: ILI9341
|
||||
# CS: 8
|
||||
# DC: 25
|
||||
# Backlight: 2
|
||||
# Width: 320
|
||||
# Height: 240
|
||||
# Width: 240
|
||||
# Height: 320
|
||||
# Rotate: true
|
||||
|
||||
Touchscreen:
|
||||
# Module: STMPE610
|
||||
### Note, at least for now, the touchscreen must have a CS pin defined, even if you let Linux manage the CS switching.
|
||||
|
||||
# Module: STMPE610 # Option 1 for Adafruit PiTFT 2.8
|
||||
# CS: 7
|
||||
# IRQ: 24
|
||||
|
||||
# Module: XPT2046
|
||||
# Module: FT5x06 # Option 2 for Adafruit PiTFT 2.8
|
||||
# IRQ: 24
|
||||
# I2CAddr: 0x38
|
||||
|
||||
# Module: XPT2046 # Waveshare 2.8inch
|
||||
# CS: 7
|
||||
# IRQ: 17
|
||||
|
||||
### Configure device for direct keyboard input
|
||||
|
||||
Input:
|
||||
# KeyboardDevice: /dev/input/event0
|
||||
# KeyboardDevice: /dev/input/by-id/usb-_Raspberry_Pi_Internal_Keyboard-event-kbd
|
||||
|
||||
###
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ IF EXIST %FILENAME% IF x%FILENAME:update=%==x%FILENAME% (
|
||||
%PYTHON% -m esptool --baud 115200 write_flash 0x00 %FILENAME%
|
||||
|
||||
@REM Account for S3 and C3 board's different OTA partition
|
||||
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% IF x%FILENAME:station-g2=%==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% IF x%FILENAME:station-g2=%==x%FILENAME% IF x%FILENAME:unphone=%==x%FILENAME% (
|
||||
IF x%FILENAME:esp32c3=%==x%FILENAME% (
|
||||
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota.bin
|
||||
) else (
|
||||
|
||||
@@ -52,7 +52,7 @@ if [ -f "${FILENAME}" ] && [ -n "${FILENAME##*"update"*}" ]; then
|
||||
"$PYTHON" -m esptool erase_flash
|
||||
"$PYTHON" -m esptool write_flash 0x00 ${FILENAME}
|
||||
# Account for S3 board's different OTA partition
|
||||
if [ -n "${FILENAME##*"s3"*}" ] && [ -n "${FILENAME##*"-v3"*}" ] && [ -n "${FILENAME##*"t-deck"*}" ] && [ -n "${FILENAME##*"wireless-paper"*}" ] && [ -n "${FILENAME##*"wireless-tracker"*}" ] && [ -n "${FILENAME##*"station-g2"*}" ]; then
|
||||
if [ -n "${FILENAME##*"s3"*}" ] && [ -n "${FILENAME##*"-v3"*}" ] && [ -n "${FILENAME##*"t-deck"*}" ] && [ -n "${FILENAME##*"wireless-paper"*}" ] && [ -n "${FILENAME##*"wireless-tracker"*}" ] && [ -n "${FILENAME##*"station-g2"*}" ] && [ -n "${FILENAME##*"unphone"*}" ]; then
|
||||
if [ -n "${FILENAME##*"esp32c3"*}" ]; then
|
||||
"$PYTHON" -m esptool write_flash 0x260000 bleota.bin
|
||||
else
|
||||
|
||||
@@ -1 +1 @@
|
||||
cd protobufs && ..\nanopb-0.4.7\generator-bin\protoc.exe --experimental_allow_proto3_optional "--nanopb_out=-S.cpp -v:..\src\mesh\generated\" -I=..\protobufs ..\protobufs\meshtastic\*.proto
|
||||
cd protobufs && ..\nanopb-0.4.8\generator-bin\protoc.exe --experimental_allow_proto3_optional "--nanopb_out=-S.cpp -v:..\src\mesh\generated" -I=..\protobufs\ ..\protobufs\meshtastic\*.proto
|
||||
|
||||
@@ -2,18 +2,10 @@
|
||||
|
||||
set -e
|
||||
|
||||
echo "This script requires https://jpa.kapsi.fi/nanopb/download/ version 0.4.7 to be located in the"
|
||||
echo "This script requires https://jpa.kapsi.fi/nanopb/download/ version 0.4.8 to be located in the"
|
||||
echo "firmware root directory if the following step fails, you should download the correct"
|
||||
echo "prebuilt binaries for your computer into nanopb-0.4.7"
|
||||
echo "prebuilt binaries for your computer into nanopb-0.4.8"
|
||||
|
||||
# the nanopb tool seems to require that the .options file be in the current directory!
|
||||
cd protobufs
|
||||
../nanopb-0.4.7/generator-bin/protoc "--nanopb_out=-S.cpp -v:../src/mesh/generated/" -I=../protobufs meshtastic/*.proto --experimental_allow_proto3_optional
|
||||
|
||||
# sed -i 's/#include "meshtastic/#include "./g' -- *
|
||||
|
||||
# sed -i 's/meshtastic_//g' -- *
|
||||
|
||||
#echo "Regenerating protobuf documentation - if you see an error message"
|
||||
#echo "you can ignore it unless doing a new protobuf release to github."
|
||||
#bin/regen-docs.sh
|
||||
../nanopb-0.4.8/generator-bin/protoc --experimental_allow_proto3_optional "--nanopb_out=-S.cpp -v:../src/mesh/generated/" -I=../protobufs meshtastic/*.proto
|
||||
|
||||
38
boards/CDEBYTE_EoRa-S3.json
Normal file
38
boards/CDEBYTE_EoRa-S3.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-D CDEBYTE_EORA_S3",
|
||||
"-D ARDUINO_USB_CDC_ON_BOOT=1",
|
||||
"-D ARDUINO_USB_MODE=0",
|
||||
"-D ARDUINO_RUNNING_CORE=1",
|
||||
"-D ARDUINO_EVENT_RUNNING_CORE=1",
|
||||
"-D BOARD_HAS_PSRAM"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "dio",
|
||||
"hwids": [["0x303A", "0x1001"]],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "CDEBYTE_EoRa-S3"
|
||||
},
|
||||
"connectivity": ["wifi"],
|
||||
"debug": {
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": ["arduino", "espidf"],
|
||||
"name": "CDEBYTE EoRa-S3",
|
||||
"upload": {
|
||||
"flash_size": "4MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 4194304,
|
||||
"wait_for_upload_port": true,
|
||||
"require_upload_port": true,
|
||||
"speed": 921600
|
||||
},
|
||||
"url": "https://www.cdebyte.com/Module-Testkits-EoRaPI",
|
||||
"vendor": "CDEBYTE"
|
||||
}
|
||||
39
boards/ESP32-S3-WROOM-1-N4.json
Normal file
39
boards/ESP32-S3-WROOM-1-N4.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32s3_out.ld"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-D ARDUINO_USB_CDC_ON_BOOT=0",
|
||||
"-D ARDUINO_USB_MSC_ON_BOOT=0",
|
||||
"-D ARDUINO_USB_DFU_ON_BOOT=0",
|
||||
"-D ARDUINO_USB_MODE=0",
|
||||
"-D ARDUINO_RUNNING_CORE=1",
|
||||
"-D ARDUINO_EVENT_RUNNING_CORE=1"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "qio",
|
||||
"hwids": [["0x303A", "0x1001"]],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "ESP32-S3-WROOM-1-N4"
|
||||
},
|
||||
"connectivity": ["wifi"],
|
||||
"debug": {
|
||||
"default_tool": "esp-builtin",
|
||||
"onboard_tools": ["esp-builtin"],
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": ["arduino", "espidf"],
|
||||
"name": "ESP32-S3-WROOM-1-N4 (4 MB Flash, No PSRAM)",
|
||||
"upload": {
|
||||
"flash_size": "4MB",
|
||||
"maximum_ram_size": 524288,
|
||||
"maximum_size": 4194304,
|
||||
"require_upload_port": true,
|
||||
"speed": 921600
|
||||
},
|
||||
"url": "https://www.espressif.com/sites/default/files/documentation/esp32-s3-wroom-1_wroom-1u_datasheet_en.pdf",
|
||||
"vendor": "Espressif"
|
||||
}
|
||||
52
boards/promicro-nrf52840.json
Normal file
52
boards/promicro-nrf52840.json
Normal file
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "nrf52840_s140_v6.ld"
|
||||
},
|
||||
"core": "nRF5",
|
||||
"cpu": "cortex-m4",
|
||||
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [
|
||||
["0x239A", "0x00B3"],
|
||||
["0x239A", "0x8029"],
|
||||
["0x239A", "0x0029"],
|
||||
["0x239A", "0x002A"],
|
||||
["0x239A", "0x802A"]
|
||||
],
|
||||
"usb_product": "ProMicro compatible nRF52840",
|
||||
"mcu": "nrf52840",
|
||||
"variant": "promicro_diy",
|
||||
"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": "ProMicro compatible nRF52840",
|
||||
"upload": {
|
||||
"maximum_ram_size": 248832,
|
||||
"maximum_size": 815104,
|
||||
"speed": 115200,
|
||||
"protocol": "nrfutil",
|
||||
"protocols": ["nrfutil", "jlink", "nrfjprog", "stlink"],
|
||||
"use_1200bps_touch": true,
|
||||
"require_upload_port": true,
|
||||
"wait_for_upload_port": true
|
||||
},
|
||||
"url": "https://www.nologo.tech/product/otherboard/NRF52840.html",
|
||||
"vendor": "Nologo"
|
||||
}
|
||||
@@ -7,8 +7,7 @@
|
||||
"extra_flags": [
|
||||
"-DBOARD_HAS_PSRAM",
|
||||
"-DLILYGO_TBEAM_S3_CORE",
|
||||
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||
"-DARDUINO_USB_MODE=0",
|
||||
"-DARDUINO_USB_MODE=1",
|
||||
"-DARDUINO_RUNNING_CORE=1",
|
||||
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
||||
],
|
||||
|
||||
34
boards/wiphone.json
Normal file
34
boards/wiphone.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "esp32_out.ld",
|
||||
"partitions": "default_16MB.csv"
|
||||
},
|
||||
"core": "esp32",
|
||||
"extra_flags": [
|
||||
"-DARDUINO_WIPHONE14",
|
||||
"-DBOARD_HAS_PSRAM",
|
||||
"-mfix-esp32-psram-cache-issue",
|
||||
"-mfix-esp32-psram-cache-strategy=memw"
|
||||
],
|
||||
"f_cpu": "240000000L",
|
||||
"f_flash": "40000000L",
|
||||
"flash_mode": "dio",
|
||||
"mcu": "esp32",
|
||||
"variant": "wiphone",
|
||||
"board": "WiPhone"
|
||||
},
|
||||
"connectivity": ["wifi", "bluetooth"],
|
||||
"frameworks": ["arduino", "espidf"],
|
||||
"name": "WIPhone Integrated 1.4",
|
||||
"upload": {
|
||||
"flash_size": "16MB",
|
||||
"maximum_ram_size": 532480,
|
||||
"maximum_size": 6553600,
|
||||
"maximum_data_size": 4521984,
|
||||
"require_upload_port": true,
|
||||
"speed": 921600
|
||||
},
|
||||
"url": "https://www.wiphone.io/",
|
||||
"vendor": "HackEDA"
|
||||
}
|
||||
@@ -74,11 +74,11 @@ build_flags = -Wno-missing-field-initializers
|
||||
monitor_speed = 115200
|
||||
|
||||
lib_deps =
|
||||
jgromes/RadioLib@^6.4.0
|
||||
jgromes/RadioLib@~6.5.0
|
||||
https://github.com/meshtastic/esp8266-oled-ssd1306.git#ee628ee6c9588d4c56c9e3da35f0fc9448ad54a8 ; ESP8266_SSD1306
|
||||
mathertel/OneButton@^2.5.0 ; OneButton library for non-blocking button debounce
|
||||
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
||||
https://github.com/meshtastic/TinyGPSPlus.git#f9f4fef2183514aa52be91d714c1455dd6f26e45
|
||||
https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4
|
||||
https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0
|
||||
nanopb/Nanopb@^0.4.7
|
||||
erriez/ErriezCRC32@^1.0.1
|
||||
@@ -96,7 +96,6 @@ check_flags =
|
||||
framework = arduino
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
mprograms/QMC5883LCompass@^1.2.0
|
||||
end2endzone/NonBlockingRTTTL@^1.3.0
|
||||
https://github.com/meshtastic/SparkFun_ATECCX08a_Arduino_Library.git#5cf62b36c6f30bc72a07bdb2c11fc9a22d1e31da
|
||||
|
||||
@@ -132,3 +131,6 @@ lib_deps =
|
||||
adafruit/Adafruit MPU6050@^2.2.4
|
||||
adafruit/Adafruit LIS3DH@^1.2.4
|
||||
https://github.com/lewisxhe/SensorLib#27fd0f721e20cd09e1f81383f0ba58a54fe84a17
|
||||
adafruit/Adafruit LSM6DS@^4.7.2
|
||||
mprograms/QMC5883LCompass@^1.2.0
|
||||
https://github.com/Sensirion/arduino-i2c-sht4x#1.1.0
|
||||
|
||||
Submodule protobufs updated: 68720ed8db...1bfe0354d1
@@ -1,10 +1,14 @@
|
||||
#include "configuration.h"
|
||||
|
||||
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||
|
||||
#include "PowerFSM.h"
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include "power.h"
|
||||
|
||||
#include <Adafruit_LIS3DH.h>
|
||||
#include <Adafruit_LSM6DS3TRC.h>
|
||||
#include <Adafruit_MPU6050.h>
|
||||
#include <Arduino.h>
|
||||
#include <SensorBMA423.hpp>
|
||||
@@ -108,6 +112,15 @@ class AccelerometerThread : public concurrency::OSThread
|
||||
bmaSensor.enableTiltIRQ();
|
||||
// It corresponds to isDoubleClick interrupt
|
||||
bmaSensor.enableWakeupIRQ();
|
||||
} else if (acceleremoter_type == ScanI2C::DeviceType::LSM6DS3 && lsm.begin_I2C(accelerometer_found.address)) {
|
||||
LOG_DEBUG("LSM6DS3 initializing\n");
|
||||
// Default threshold of 2G, less sensitive options are 4, 8 or 16G
|
||||
lsm.setAccelRange(LSM6DS_ACCEL_RANGE_2_G);
|
||||
#ifndef LSM6DS3_WAKE_THRESH
|
||||
#define LSM6DS3_WAKE_THRESH 20
|
||||
#endif
|
||||
lsm.enableWakeup(config.display.wake_on_tap_or_motion, 1, LSM6DS3_WAKE_THRESH);
|
||||
// Duration is number of occurances needed to trigger, higher threshold is less sensitive
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,6 +146,9 @@ class AccelerometerThread : public concurrency::OSThread
|
||||
wakeScreen();
|
||||
return 500;
|
||||
}
|
||||
} else if (acceleremoter_type == ScanI2C::DeviceType::LSM6DS3 && lsm.shake()) {
|
||||
wakeScreen();
|
||||
return 500;
|
||||
}
|
||||
|
||||
return ACCELEROMETER_CHECK_INTERVAL_MS;
|
||||
@@ -156,6 +172,9 @@ class AccelerometerThread : public concurrency::OSThread
|
||||
ScanI2C::DeviceType acceleremoter_type;
|
||||
Adafruit_MPU6050 mpu;
|
||||
Adafruit_LIS3DH lis;
|
||||
Adafruit_LSM6DS3TRC lsm;
|
||||
};
|
||||
|
||||
} // namespace concurrency
|
||||
|
||||
#endif
|
||||
@@ -5,6 +5,16 @@
|
||||
NCP5623 rgb;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_NEOPIXEL
|
||||
#include <graphics/NeoPixel.h>
|
||||
Adafruit_NeoPixel pixels(NEOPIXEL_COUNT, NEOPIXEL_DATA, NEOPIXEL_TYPE);
|
||||
#endif
|
||||
|
||||
#ifdef UNPHONE
|
||||
#include "unPhone.h"
|
||||
extern unPhone unphone;
|
||||
#endif
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
class AmbientLightingThread : public concurrency::OSThread
|
||||
@@ -27,15 +37,31 @@ class AmbientLightingThread : public concurrency::OSThread
|
||||
disable();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
|
||||
if (!moduleConfig.ambient_lighting.led_state) {
|
||||
LOG_DEBUG("AmbientLightingThread disabling due to moduleConfig.ambient_lighting.led_state OFF\n");
|
||||
disable();
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("AmbientLightingThread initializing\n");
|
||||
#ifdef HAS_NCP5623
|
||||
if (_type == ScanI2C::NCP5623) {
|
||||
rgb.begin();
|
||||
#endif
|
||||
#ifdef RGBLED_RED
|
||||
pinMode(RGBLED_RED, OUTPUT);
|
||||
pinMode(RGBLED_GREEN, OUTPUT);
|
||||
pinMode(RGBLED_BLUE, OUTPUT);
|
||||
#endif
|
||||
#ifdef HAS_NEOPIXEL
|
||||
pixels.begin(); // Initialise the pixel(s)
|
||||
pixels.clear(); // Set all pixel colors to 'off'
|
||||
pixels.setBrightness(moduleConfig.ambient_lighting.current);
|
||||
#endif
|
||||
setLighting();
|
||||
#endif
|
||||
#ifdef HAS_NCP5623
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -43,16 +69,17 @@ class AmbientLightingThread : public concurrency::OSThread
|
||||
protected:
|
||||
int32_t runOnce() override
|
||||
{
|
||||
#if defined(HAS_NCP5623) || defined(RGBLED_RED) || defined(HAS_NEOPIXEL) || defined(UNPHONE)
|
||||
#ifdef HAS_NCP5623
|
||||
if (_type == ScanI2C::NCP5623 && moduleConfig.ambient_lighting.led_state) {
|
||||
#endif
|
||||
setLighting();
|
||||
return 30000; // 30 seconds to reset from any animations that may have been running from Ext. Notification
|
||||
} else {
|
||||
return disable();
|
||||
#ifdef HAS_NCP5623
|
||||
}
|
||||
#else
|
||||
return disable();
|
||||
#endif
|
||||
#endif
|
||||
return disable();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -65,9 +92,36 @@ class AmbientLightingThread : public concurrency::OSThread
|
||||
rgb.setRed(moduleConfig.ambient_lighting.red);
|
||||
rgb.setGreen(moduleConfig.ambient_lighting.green);
|
||||
rgb.setBlue(moduleConfig.ambient_lighting.blue);
|
||||
LOG_DEBUG("Initializing Ambient lighting w/ current=%d, red=%d, green=%d, blue=%d\n",
|
||||
LOG_DEBUG("Initializing NCP5623 Ambient lighting w/ current=%d, red=%d, green=%d, blue=%d\n",
|
||||
moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
|
||||
moduleConfig.ambient_lighting.blue);
|
||||
#endif
|
||||
#ifdef HAS_NEOPIXEL
|
||||
pixels.fill(pixels.Color(moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
|
||||
moduleConfig.ambient_lighting.blue),
|
||||
0, NEOPIXEL_COUNT);
|
||||
pixels.show();
|
||||
LOG_DEBUG("Initializing NeoPixel Ambient lighting w/ brightness(current)=%d, red=%d, green=%d, blue=%d\n",
|
||||
moduleConfig.ambient_lighting.current, moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green,
|
||||
moduleConfig.ambient_lighting.blue);
|
||||
#endif
|
||||
#ifdef RGBLED_CA
|
||||
analogWrite(RGBLED_RED, 255 - moduleConfig.ambient_lighting.red);
|
||||
analogWrite(RGBLED_GREEN, 255 - moduleConfig.ambient_lighting.green);
|
||||
analogWrite(RGBLED_BLUE, 255 - moduleConfig.ambient_lighting.blue);
|
||||
LOG_DEBUG("Initializing Ambient lighting RGB Common Anode w/ red=%d, green=%d, blue=%d\n",
|
||||
moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
|
||||
#elif defined(RGBLED_RED)
|
||||
analogWrite(RGBLED_RED, moduleConfig.ambient_lighting.red);
|
||||
analogWrite(RGBLED_GREEN, moduleConfig.ambient_lighting.green);
|
||||
analogWrite(RGBLED_BLUE, moduleConfig.ambient_lighting.blue);
|
||||
LOG_DEBUG("Initializing Ambient lighting RGB Common Cathode w/ red=%d, green=%d, blue=%d\n",
|
||||
moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
|
||||
#endif
|
||||
#ifdef UNPHONE
|
||||
unphone.rgb(moduleConfig.ambient_lighting.red, moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
|
||||
LOG_DEBUG("Initializing unPhone Ambient lighting w/ red=%d, green=%d, blue=%d\n", moduleConfig.ambient_lighting.red,
|
||||
moduleConfig.ambient_lighting.green, moduleConfig.ambient_lighting.blue);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@@ -23,18 +23,24 @@
|
||||
|
||||
using namespace concurrency;
|
||||
|
||||
ButtonThread *buttonThread; // Declared extern in header
|
||||
volatile ButtonThread::ButtonEventType ButtonThread::btnEvent = ButtonThread::BUTTON_EVENT_NONE;
|
||||
|
||||
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO)
|
||||
OneButton ButtonThread::userButton; // Get reference to static member
|
||||
#endif
|
||||
|
||||
ButtonThread::ButtonThread() : OSThread("Button")
|
||||
{
|
||||
#if defined(ARCH_PORTDUINO) || defined(BUTTON_PIN)
|
||||
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO)
|
||||
|
||||
#if defined(ARCH_PORTDUINO)
|
||||
if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) {
|
||||
userButton = OneButton(settingsMap[user], true, true);
|
||||
this->userButton = OneButton(settingsMap[user], true, true);
|
||||
LOG_DEBUG("Using GPIO%02d for button\n", settingsMap[user]);
|
||||
}
|
||||
#elif defined(BUTTON_PIN)
|
||||
int pin = config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN;
|
||||
int pin = config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN; // Resolved button pin
|
||||
this->userButton = OneButton(pin, true, true);
|
||||
LOG_DEBUG("Using GPIO%02d for button\n", pin);
|
||||
#endif
|
||||
@@ -43,9 +49,11 @@ ButtonThread::ButtonThread() : OSThread("Button")
|
||||
// Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did
|
||||
pinMode(pin, INPUT_PULLUP_SENSE);
|
||||
#endif
|
||||
|
||||
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO)
|
||||
userButton.attachClick(userButtonPressed);
|
||||
userButton.setClickMs(250);
|
||||
userButton.setPressMs(c_longPressTime);
|
||||
userButton.setClickMs(BUTTON_CLICK_MS);
|
||||
userButton.setPressMs(BUTTON_LONGPRESS_MS);
|
||||
userButton.setDebounceMs(1);
|
||||
userButton.attachDoubleClick(userButtonDoublePressed);
|
||||
userButton.attachMultiClick(userButtonMultiPressed, this); // Reference to instance: get click count from non-static OneButton
|
||||
@@ -53,21 +61,8 @@ ButtonThread::ButtonThread() : OSThread("Button")
|
||||
userButton.attachLongPressStart(userButtonPressedLongStart);
|
||||
userButton.attachLongPressStop(userButtonPressedLongStop);
|
||||
#endif
|
||||
#if defined(ARCH_PORTDUINO)
|
||||
if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC)
|
||||
wakeOnIrq(settingsMap[user], FALLING);
|
||||
#else
|
||||
static OneButton *pBtn = &userButton; // only one instance of ButtonThread is created, so static is safe
|
||||
attachInterrupt(
|
||||
pin,
|
||||
[]() {
|
||||
BaseType_t higherWake = 0;
|
||||
mainDelay.interruptFromISR(&higherWake);
|
||||
pBtn->tick();
|
||||
},
|
||||
CHANGE);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef BUTTON_PIN_ALT
|
||||
userButtonAlt = OneButton(BUTTON_PIN_ALT, true, true);
|
||||
#ifdef INPUT_PULLUP_SENSE
|
||||
@@ -75,20 +70,21 @@ ButtonThread::ButtonThread() : OSThread("Button")
|
||||
pinMode(BUTTON_PIN_ALT, INPUT_PULLUP_SENSE);
|
||||
#endif
|
||||
userButtonAlt.attachClick(userButtonPressed);
|
||||
userButtonAlt.setClickMs(250);
|
||||
userButtonAlt.setPressMs(c_longPressTime);
|
||||
userButtonAlt.setClickMs(BUTTON_CLICK_MS);
|
||||
userButtonAlt.setPressMs(BUTTON_LONGPRESS_MS);
|
||||
userButtonAlt.setDebounceMs(1);
|
||||
userButtonAlt.attachDoubleClick(userButtonDoublePressed);
|
||||
userButtonAlt.attachLongPressStart(userButtonPressedLongStart);
|
||||
userButtonAlt.attachLongPressStop(userButtonPressedLongStop);
|
||||
wakeOnIrq(BUTTON_PIN_ALT, FALLING);
|
||||
#endif
|
||||
|
||||
#ifdef BUTTON_PIN_TOUCH
|
||||
userButtonTouch = OneButton(BUTTON_PIN_TOUCH, true, true);
|
||||
userButtonTouch.setPressMs(400);
|
||||
userButtonTouch.setPressMs(BUTTON_TOUCH_MS);
|
||||
userButtonTouch.attachLongPressStart(touchPressedLongStart); // Better handling with longpress than click?
|
||||
wakeOnIrq(BUTTON_PIN_TOUCH, FALLING);
|
||||
#endif
|
||||
|
||||
attachButtonInterrupts();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -140,9 +136,12 @@ int32_t ButtonThread::runOnce()
|
||||
case BUTTON_EVENT_DOUBLE_PRESSED: {
|
||||
LOG_BUTTON("Double press!\n");
|
||||
service.refreshLocalMeshNode();
|
||||
service.sendNetworkPing(NODENUM_BROADCAST, true);
|
||||
auto sentPosition = service.trySendPosition(NODENUM_BROADCAST, true);
|
||||
if (screen) {
|
||||
screen->print("Sent ad-hoc ping\n");
|
||||
if (sentPosition)
|
||||
screen->print("Sent ad-hoc position\n");
|
||||
else
|
||||
screen->print("Sent ad-hoc nodeinfo\n");
|
||||
screen->forceDisplay(true); // Force a new UI frame, then force an EInk update
|
||||
}
|
||||
break;
|
||||
@@ -197,15 +196,13 @@ int32_t ButtonThread::runOnce()
|
||||
#ifdef BUTTON_PIN_TOUCH
|
||||
case BUTTON_EVENT_TOUCH_LONG_PRESSED: {
|
||||
LOG_BUTTON("Touch press!\n");
|
||||
if (config.display.wake_on_tap_or_motion) {
|
||||
if (screen) {
|
||||
// Wake if asleep
|
||||
if (powerFSM.getState() == &stateDARK)
|
||||
powerFSM.trigger(EVENT_PRESS);
|
||||
if (screen) {
|
||||
// Wake if asleep
|
||||
if (powerFSM.getState() == &stateDARK)
|
||||
powerFSM.trigger(EVENT_PRESS);
|
||||
|
||||
// Update display (legacy behaviour)
|
||||
screen->forceDisplay();
|
||||
}
|
||||
// Update display (legacy behaviour)
|
||||
screen->forceDisplay();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -217,9 +214,63 @@ int32_t ButtonThread::runOnce()
|
||||
btnEvent = BUTTON_EVENT_NONE;
|
||||
}
|
||||
|
||||
runASAP = false;
|
||||
return 50;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach (or re-attach) hardware interrupts for buttons
|
||||
* Public method. Used outside class when waking from MCU sleep
|
||||
*/
|
||||
void ButtonThread::attachButtonInterrupts()
|
||||
{
|
||||
#if defined(ARCH_PORTDUINO)
|
||||
if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC)
|
||||
wakeOnIrq(settingsMap[user], FALLING);
|
||||
#elif defined(BUTTON_PIN)
|
||||
// Interrupt for user button, during normal use. Improves responsiveness.
|
||||
attachInterrupt(
|
||||
config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN,
|
||||
[]() {
|
||||
BaseType_t higherWake = 0;
|
||||
mainDelay.interruptFromISR(&higherWake);
|
||||
ButtonThread::userButton.tick();
|
||||
runASAP = true;
|
||||
},
|
||||
CHANGE);
|
||||
#endif
|
||||
|
||||
#ifdef BUTTON_PIN_ALT
|
||||
wakeOnIrq(BUTTON_PIN_ALT, FALLING);
|
||||
#endif
|
||||
|
||||
#ifdef BUTTON_PIN_TOUCH
|
||||
wakeOnIrq(BUTTON_PIN_TOUCH, FALLING);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Detach the "normal" button interrupts.
|
||||
* Public method. Used before attaching a "wake-on-button" interrupt for MCU sleep
|
||||
*/
|
||||
void ButtonThread::detachButtonInterrupts()
|
||||
{
|
||||
#if defined(ARCH_PORTDUINO)
|
||||
if (settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC)
|
||||
detachInterrupt(settingsMap[user]);
|
||||
#elif defined(BUTTON_PIN)
|
||||
detachInterrupt(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN);
|
||||
#endif
|
||||
|
||||
#ifdef BUTTON_PIN_ALT
|
||||
detachInterrupt(BUTTON_PIN_ALT);
|
||||
#endif
|
||||
|
||||
#ifdef BUTTON_PIN_TOUCH
|
||||
detachInterrupt(BUTTON_PIN_TOUCH);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Watch a GPIO and if we get an IRQ, wake the main thread.
|
||||
* Use to add wake on button press
|
||||
@@ -231,6 +282,7 @@ void ButtonThread::wakeOnIrq(int irq, int mode)
|
||||
[] {
|
||||
BaseType_t higherWake = 0;
|
||||
mainDelay.interruptFromISR(&higherWake);
|
||||
runASAP = true;
|
||||
},
|
||||
FALLING);
|
||||
}
|
||||
|
||||
@@ -4,11 +4,22 @@
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#ifndef BUTTON_CLICK_MS
|
||||
#define BUTTON_CLICK_MS 250
|
||||
#endif
|
||||
|
||||
#ifndef BUTTON_LONGPRESS_MS
|
||||
#define BUTTON_LONGPRESS_MS 5000
|
||||
#endif
|
||||
|
||||
#ifndef BUTTON_TOUCH_MS
|
||||
#define BUTTON_TOCH_MS 400
|
||||
#endif
|
||||
|
||||
class ButtonThread : public concurrency::OSThread
|
||||
{
|
||||
public:
|
||||
static const uint32_t c_longPressTime = 5000; // shutdown after 5s
|
||||
static const uint32_t c_holdOffTime = 30000; // hold off 30s after boot
|
||||
static const uint32_t c_holdOffTime = 30000; // hold off 30s after boot
|
||||
|
||||
enum ButtonEventType {
|
||||
BUTTON_EVENT_NONE,
|
||||
@@ -22,11 +33,13 @@ class ButtonThread : public concurrency::OSThread
|
||||
|
||||
ButtonThread();
|
||||
int32_t runOnce() override;
|
||||
void attachButtonInterrupts();
|
||||
void detachButtonInterrupts();
|
||||
void storeClickCount();
|
||||
|
||||
private:
|
||||
#ifdef BUTTON_PIN
|
||||
OneButton userButton;
|
||||
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO)
|
||||
static OneButton userButton; // Static - accessed from an interrupt
|
||||
#endif
|
||||
#ifdef BUTTON_PIN_ALT
|
||||
OneButton userButtonAlt;
|
||||
@@ -34,9 +47,6 @@ class ButtonThread : public concurrency::OSThread
|
||||
#ifdef BUTTON_PIN_TOUCH
|
||||
OneButton userButtonTouch;
|
||||
#endif
|
||||
#if defined(ARCH_PORTDUINO)
|
||||
OneButton userButton;
|
||||
#endif
|
||||
|
||||
// set during IRQ
|
||||
static volatile ButtonEventType btnEvent;
|
||||
@@ -54,3 +64,5 @@ class ButtonThread : public concurrency::OSThread
|
||||
static void userButtonPressedLongStop();
|
||||
static void touchPressedLongStart() { btnEvent = BUTTON_EVENT_TOUCH_LONG_PRESSED; }
|
||||
};
|
||||
|
||||
extern ButtonThread *buttonThread;
|
||||
|
||||
@@ -212,8 +212,23 @@ void fsInit()
|
||||
LOG_ERROR("Filesystem mount Failed.\n");
|
||||
// assert(0); This auto-formats the partition, so no need to fail here.
|
||||
}
|
||||
#ifdef ARCH_ESP32
|
||||
#if defined(ARCH_ESP32)
|
||||
LOG_DEBUG("Filesystem files (%d/%d Bytes):\n", FSCom.usedBytes(), FSCom.totalBytes());
|
||||
#elif defined(ARCH_NRF52)
|
||||
/*
|
||||
* nRF52840 has a certain chance of automatic formatting failure.
|
||||
* Try to create a file after initializing the file system. If the creation fails,
|
||||
* it means that the file system is not working properly. Please format it manually again.
|
||||
* */
|
||||
Adafruit_LittleFS_Namespace::File file(FSCom);
|
||||
const char *filename = "/meshtastic.txt";
|
||||
if (!file.open(filename, FILE_O_WRITE)) {
|
||||
LOG_DEBUG("Format ....");
|
||||
FSCom.format();
|
||||
FSCom.begin();
|
||||
} else {
|
||||
file.close();
|
||||
}
|
||||
#else
|
||||
LOG_DEBUG("Filesystem files:\n");
|
||||
#endif
|
||||
|
||||
@@ -69,7 +69,7 @@ static const uint8_t ext_chrg_detect_value = EXT_CHRG_DETECT_VALUE;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO)
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO)
|
||||
INA260Sensor ina260Sensor;
|
||||
INA219Sensor ina219Sensor;
|
||||
INA3221Sensor ina3221Sensor;
|
||||
@@ -184,7 +184,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
virtual uint16_t getBattVoltage() override
|
||||
{
|
||||
|
||||
#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
|
||||
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||
if (hasINA()) {
|
||||
LOG_DEBUG("Using INA on I2C addr 0x%x for device battery voltage\n", config.power.device_battery_ina_address);
|
||||
return getINAVoltage();
|
||||
@@ -223,7 +223,17 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
raw = raw / BATTERY_SENSE_SAMPLES;
|
||||
scaled = operativeAdcMultiplier * ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * raw;
|
||||
#endif
|
||||
last_read_value += (scaled - last_read_value) * 0.5; // Virtual LPF
|
||||
|
||||
if (!initial_read_done) {
|
||||
// Flush the smoothing filter with an ADC reading, if the reading is plausibly correct
|
||||
if (scaled > last_read_value)
|
||||
last_read_value = scaled;
|
||||
initial_read_done = true;
|
||||
} else {
|
||||
// Already initialized - filter this reading
|
||||
last_read_value += (scaled - last_read_value) * 0.5; // Virtual LPF
|
||||
}
|
||||
|
||||
// LOG_DEBUG("battery gpio %d raw val=%u scaled=%u filtered=%u\n", BATTERY_PIN, raw, (uint32_t)(scaled), (uint32_t)
|
||||
// (last_read_value));
|
||||
}
|
||||
@@ -357,10 +367,12 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
const float noBatVolt = (OCV[NUM_OCV_POINTS - 1] - 500) * NUM_CELLS;
|
||||
// Start value from minimum voltage for the filter to not start from 0
|
||||
// that could trigger some events.
|
||||
// This value is over-written by the first ADC reading, it the voltage seems reasonable.
|
||||
bool initial_read_done = false;
|
||||
float last_read_value = (OCV[NUM_OCV_POINTS - 1] * NUM_CELLS);
|
||||
uint32_t last_read_time_ms = 0;
|
||||
|
||||
#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO)
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO)
|
||||
uint16_t getINAVoltage()
|
||||
{
|
||||
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
|
||||
@@ -500,12 +512,7 @@ void Power::shutdown()
|
||||
{
|
||||
LOG_INFO("Shutting down\n");
|
||||
|
||||
#ifdef HAS_PMU
|
||||
if (pmu_found == true) {
|
||||
PMU->setChargingLedMode(XPOWERS_CHG_LED_OFF);
|
||||
PMU->shutdown();
|
||||
}
|
||||
#elif defined(ARCH_NRF52) || defined(ARCH_ESP32)
|
||||
#if defined(ARCH_NRF52) || defined(ARCH_ESP32)
|
||||
#ifdef PIN_LED1
|
||||
ledOff(PIN_LED1);
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
#include "sleep.h"
|
||||
#include "target_specific.h"
|
||||
|
||||
#ifndef SLEEP_TIME
|
||||
#define SLEEP_TIME 30
|
||||
#endif
|
||||
|
||||
/// Should we behave as if we have AC power now?
|
||||
static bool isPowered()
|
||||
{
|
||||
@@ -81,7 +85,7 @@ static void lsIdle()
|
||||
// If some other service would stall sleep, don't let sleep happen yet
|
||||
if (doPreflightSleep()) {
|
||||
// Briefly come out of sleep long enough to blink the led once every few seconds
|
||||
uint32_t sleepTime = 30;
|
||||
uint32_t sleepTime = SLEEP_TIME;
|
||||
|
||||
setLed(false); // Never leave led on while in light sleep
|
||||
esp_sleep_source_t wakeCause2 = doLightSleep(sleepTime * 1000LL);
|
||||
@@ -102,18 +106,21 @@ static void lsIdle()
|
||||
powerFSM.trigger(EVENT_SERIAL_CONNECTED);
|
||||
break;
|
||||
|
||||
case ESP_SLEEP_WAKEUP_GPIO:
|
||||
// GPIO wakeup is now used for all ESP32 devices during light sleep
|
||||
powerFSM.trigger(EVENT_PRESS);
|
||||
break;
|
||||
|
||||
default:
|
||||
// We woke for some other reason (device interrupt?)
|
||||
LOG_INFO("wakeCause2 %d\n", wakeCause2);
|
||||
// We woke for some other reason (button press, device IRQ interrupt)
|
||||
|
||||
// Let the NB state handle the IRQ (and that state will handle stuff like IRQs etc)
|
||||
// we lie and say "wake timer" because the interrupt will be handled by the regular IRQ code
|
||||
powerFSM.trigger(EVENT_WAKE_TIMER);
|
||||
#ifdef BUTTON_PIN
|
||||
bool pressed = !digitalRead(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN);
|
||||
#else
|
||||
bool pressed = false;
|
||||
#endif
|
||||
if (pressed) { // If we woke because of press, instead generate a PRESS event.
|
||||
powerFSM.trigger(EVENT_PRESS);
|
||||
} else {
|
||||
// Otherwise let the NB state handle the IRQ (and that state will handle stuff like IRQs etc)
|
||||
// we lie and say "wake timer" because the interrupt will be handled by the regular IRQ code
|
||||
powerFSM.trigger(EVENT_WAKE_TIMER);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@@ -178,10 +185,12 @@ static void powerEnter()
|
||||
screen->setOn(true);
|
||||
setBluetoothEnable(true);
|
||||
// within enter() the function getState() returns the state we came from
|
||||
if (strcmp(powerFSM.getState()->name, "BOOT") != 0 && strcmp(powerFSM.getState()->name, "POWER") != 0 &&
|
||||
|
||||
// Mothballed: print change of power-state to device screen
|
||||
/* if (strcmp(powerFSM.getState()->name, "BOOT") != 0 && strcmp(powerFSM.getState()->name, "POWER") != 0 &&
|
||||
strcmp(powerFSM.getState()->name, "DARK") != 0) {
|
||||
screen->print("Powered...\n");
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,8 +207,10 @@ static void powerExit()
|
||||
{
|
||||
screen->setOn(true);
|
||||
setBluetoothEnable(true);
|
||||
if (!isPowered())
|
||||
screen->print("Unpowered...\n");
|
||||
|
||||
// Mothballed: print change of power-state to device screen
|
||||
/*if (!isPowered())
|
||||
screen->print("Unpowered...\n");*/
|
||||
}
|
||||
|
||||
static void onEnter()
|
||||
|
||||
@@ -182,11 +182,11 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...)
|
||||
void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16_t len)
|
||||
{
|
||||
const char alphabet[17] = "0123456789abcdef";
|
||||
log(logLevel, " +------------------------------------------------+ +----------------+\n");
|
||||
log(logLevel, " |.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f | | ASCII |\n");
|
||||
log(logLevel, " +------------------------------------------------+ +----------------+\n");
|
||||
log(logLevel, " |.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f | | ASCII |\n");
|
||||
for (uint16_t i = 0; i < len; i += 16) {
|
||||
if (i % 128 == 0)
|
||||
log(logLevel, " +------------------------------------------------+ +----------------+\n");
|
||||
log(logLevel, " +------------------------------------------------+ +----------------+\n");
|
||||
char s[] = "| | | |\n";
|
||||
uint8_t ix = 1, iy = 52;
|
||||
for (uint8_t j = 0; j < 16; j++) {
|
||||
@@ -208,7 +208,7 @@ void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16
|
||||
log(logLevel, ".");
|
||||
log(logLevel, s);
|
||||
}
|
||||
log(logLevel, " +------------------------------------------------+ +----------------+\n");
|
||||
log(logLevel, " +------------------------------------------------+ +----------------+\n");
|
||||
}
|
||||
|
||||
std::string RedirectablePrint::mt_sprintf(const std::string fmt_str, ...)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "configuration.h"
|
||||
#include "time.h"
|
||||
|
||||
#ifdef RP2040_SLOW_CLOCK
|
||||
#define Port Serial2
|
||||
@@ -50,7 +51,9 @@ SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port), con
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if !ARCH_PORTDUINO
|
||||
emitRebooted();
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t SerialConsole::runOnce()
|
||||
|
||||
@@ -74,6 +74,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define RTC_DATA_ATTR
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Regulatory overrides for producing regional builds
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Define if region should override user saved region
|
||||
// #define LORA_REGIONCODE meshtastic_Config_LoRaConfig_RegionCode_SG_923
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Feature toggles
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -119,8 +126,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define SHTC3_ADDR 0x70
|
||||
#define LPS22HB_ADDR 0x5C
|
||||
#define LPS22HB_ADDR_ALT 0x5D
|
||||
#define SHT31_ADDR 0x44
|
||||
#define SHT31_4x_ADDR 0x44
|
||||
#define PMSA0031_ADDR 0x12
|
||||
#define RCWL9620_ADDR 0x57
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// ACCELEROMETER
|
||||
@@ -128,6 +136,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define MPU6050_ADDR 0x68
|
||||
#define LIS3DH_ADR 0x18
|
||||
#define BMA423_ADDR 0x19
|
||||
#define LSM6DS3_ADDR 0x6A
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// LED
|
||||
@@ -137,9 +146,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// -----------------------------------------------------------------------------
|
||||
// Security
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#define ATECC608B_ADDR 0x35
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// IO Expander
|
||||
// -----------------------------------------------------------------------------
|
||||
#define TCA9555_ADDR 0x26
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// GPS
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -280,4 +293,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#ifdef MESHTASTIC_EXCLUDE_SCREEN
|
||||
#undef HAS_SCREEN
|
||||
#define HAS_SCREEN 0
|
||||
#endif
|
||||
#endif
|
||||
5
src/detect/LoRaRadioType.h
Normal file
5
src/detect/LoRaRadioType.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
enum LoRaRadioType { NO_RADIO, STM32WLx_RADIO, SIM_RADIO, RF95_RADIO, SX1262_RADIO, SX1268_RADIO, LLCC68_RADIO, SX1280_RADIO };
|
||||
|
||||
extern LoRaRadioType radioType;
|
||||
@@ -36,8 +36,8 @@ ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
|
||||
|
||||
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
|
||||
{
|
||||
ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423};
|
||||
return firstOfOrNONE(3, types);
|
||||
ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423, LSM6DS3};
|
||||
return firstOfOrNONE(4, types);
|
||||
}
|
||||
|
||||
ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const
|
||||
|
||||
@@ -29,6 +29,7 @@ class ScanI2C
|
||||
INA3221,
|
||||
MCP9808,
|
||||
SHT31,
|
||||
SHT4X,
|
||||
SHTC3,
|
||||
LPS22HB,
|
||||
QMC6310,
|
||||
@@ -39,9 +40,10 @@ class ScanI2C
|
||||
LIS3DH,
|
||||
BMA423,
|
||||
BQ24295,
|
||||
#ifdef HAS_NCP5623
|
||||
LSM6DS3,
|
||||
TCA9555,
|
||||
RCWL9620,
|
||||
NCP5623,
|
||||
#endif
|
||||
} DeviceType;
|
||||
|
||||
// typedef uint8_t DeviceAddress;
|
||||
|
||||
@@ -271,8 +271,14 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
|
||||
}
|
||||
break;
|
||||
case INA3221_ADDR:
|
||||
LOG_INFO("INA3221 sensor found at address 0x%x\n", (uint8_t)addr.address);
|
||||
type = INA3221;
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
|
||||
LOG_DEBUG("Register MFG_UID: 0x%x\n", registerValue);
|
||||
if (registerValue == 0x5449) {
|
||||
LOG_INFO("INA3221 sensor found at address 0x%x\n", (uint8_t)addr.address);
|
||||
type = INA3221;
|
||||
} else { // Unknown device
|
||||
LOG_INFO("No INA3221 found at address 0x%x\n", (uint8_t)addr.address);
|
||||
}
|
||||
break;
|
||||
case MCP9808_ADDR:
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x07), 2);
|
||||
@@ -286,8 +292,20 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
|
||||
|
||||
break;
|
||||
|
||||
SCAN_SIMPLE_CASE(SHT31_ADDR, SHT31, "SHT31 sensor found\n")
|
||||
case SHT31_4x_ADDR:
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x89), 2);
|
||||
if (registerValue == 0x11a2) {
|
||||
type = SHT4X;
|
||||
LOG_INFO("SHT4X sensor found\n");
|
||||
} else {
|
||||
type = SHT31;
|
||||
LOG_INFO("SHT31 sensor found\n");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
SCAN_SIMPLE_CASE(SHTC3_ADDR, SHTC3, "SHTC3 sensor found\n")
|
||||
SCAN_SIMPLE_CASE(RCWL9620_ADDR, RCWL9620, "RCWL9620 sensor found\n")
|
||||
|
||||
case LPS22HB_ADDR_ALT:
|
||||
SCAN_SIMPLE_CASE(LPS22HB_ADDR, LPS22HB, "LPS22HB sensor found\n")
|
||||
@@ -299,6 +317,12 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
|
||||
if (registerValue == 0xC0) {
|
||||
type = BQ24295;
|
||||
LOG_INFO("BQ24295 PMU found\n");
|
||||
break;
|
||||
}
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 1); // get ID
|
||||
if (registerValue == 0x6A) {
|
||||
type = LSM6DS3;
|
||||
LOG_INFO("LSM6DS3 accelerometer found at address 0x%x\n", (uint8_t)addr.address);
|
||||
} else {
|
||||
type = QMI8658;
|
||||
LOG_INFO("QMI8658 Highrate 6-Axis inertial measurement sensor found\n");
|
||||
@@ -310,6 +334,8 @@ void ScanI2CTwoWire::scanPort(I2CPort port)
|
||||
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(BMA423_ADDR, BMA423, "BMA423 accelerometer found\n");
|
||||
SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3 accelerometer found at address 0x%x\n", (uint8_t)addr.address);
|
||||
SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555 I2C expander found\n");
|
||||
|
||||
default:
|
||||
LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address);
|
||||
@@ -342,4 +368,4 @@ TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address) const
|
||||
size_t ScanI2CTwoWire::countDevices() const
|
||||
{
|
||||
return foundDevices.size();
|
||||
}
|
||||
}
|
||||
|
||||
167
src/gps/GPS.cpp
167
src/gps/GPS.cpp
@@ -7,6 +7,8 @@
|
||||
|
||||
#include "main.h" // pmu_found
|
||||
#include "sleep.h"
|
||||
|
||||
#include "cas.h"
|
||||
#include "ubx.h"
|
||||
|
||||
#ifdef ARCH_PORTDUINO
|
||||
@@ -51,6 +53,28 @@ void GPS::UBXChecksum(uint8_t *message, size_t length)
|
||||
message[length - 1] = CK_B;
|
||||
}
|
||||
|
||||
// Calculate the checksum for a CAS packet
|
||||
void GPS::CASChecksum(uint8_t *message, size_t length)
|
||||
{
|
||||
uint32_t cksum = ((uint32_t)message[5] << 24); // Message ID
|
||||
cksum += ((uint32_t)message[4]) << 16; // Class
|
||||
cksum += message[2]; // Payload Len
|
||||
|
||||
// Iterate over the payload as a series of uint32_t's and
|
||||
// accumulate the cksum
|
||||
uint32_t const *payload = (uint32_t *)(message + 6);
|
||||
for (size_t i = 0; i < (length - 10) / 4; i++) {
|
||||
uint32_t pl = payload[i];
|
||||
cksum += pl;
|
||||
}
|
||||
|
||||
// Place the checksum values in the message
|
||||
message[length - 4] = (cksum & 0xFF);
|
||||
message[length - 3] = (cksum & (0xFF << 8)) >> 8;
|
||||
message[length - 2] = (cksum & (0xFF << 16)) >> 16;
|
||||
message[length - 1] = (cksum & (0xFF << 24)) >> 24;
|
||||
}
|
||||
|
||||
// Function to create a ublox packet for editing in memory
|
||||
uint8_t GPS::makeUBXPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_size, const uint8_t *msg)
|
||||
{
|
||||
@@ -72,6 +96,41 @@ uint8_t GPS::makeUBXPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_siz
|
||||
return (payload_size + 8);
|
||||
}
|
||||
|
||||
// Function to create a CAS packet for editing in memory
|
||||
uint8_t GPS::makeCASPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_size, const uint8_t *msg)
|
||||
{
|
||||
// General CAS structure
|
||||
// | H1 | H2 | payload_len | cls | msg | Payload ... | Checksum |
|
||||
// Size: | 1 | 1 | 2 | 1 | 1 | payload_len | 4 |
|
||||
// Pos: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 ... | 6 + payload_len ... |
|
||||
// |------|------|-------------|------|------|------|--------------|---------------------------|
|
||||
// | 0xBA | 0xCE | 0xXX | 0xXX | 0xXX | 0xXX | 0xXX | 0xXX ... | 0xXX | 0xXX | 0xXX | 0xXX |
|
||||
|
||||
// Construct the CAS packet
|
||||
UBXscratch[0] = 0xBA; // header 1 (0xBA)
|
||||
UBXscratch[1] = 0xCE; // header 2 (0xCE)
|
||||
UBXscratch[2] = payload_size; // length 1
|
||||
UBXscratch[3] = 0; // length 2
|
||||
UBXscratch[4] = class_id; // class
|
||||
UBXscratch[5] = msg_id; // id
|
||||
|
||||
UBXscratch[6 + payload_size] = 0x00; // Checksum
|
||||
UBXscratch[7 + payload_size] = 0x00;
|
||||
UBXscratch[8 + payload_size] = 0x00;
|
||||
UBXscratch[9 + payload_size] = 0x00;
|
||||
|
||||
for (int i = 0; i < payload_size; i++) {
|
||||
UBXscratch[6 + i] = pgm_read_byte(&msg[i]);
|
||||
}
|
||||
CASChecksum(UBXscratch, (payload_size + 10));
|
||||
|
||||
#if defined(GPS_DEBUG) && defined(DEBUG_PORT)
|
||||
LOG_DEBUG("Constructed CAS packet: \n");
|
||||
DEBUG_PORT.hexDump(MESHTASTIC_LOG_LEVEL_DEBUG, UBXscratch, payload_size + 10);
|
||||
#endif
|
||||
return (payload_size + 10);
|
||||
}
|
||||
|
||||
GPS_RESPONSE GPS::getACK(const char *message, uint32_t waitMillis)
|
||||
{
|
||||
uint8_t buffer[768] = {0};
|
||||
@@ -81,6 +140,7 @@ GPS_RESPONSE GPS::getACK(const char *message, uint32_t waitMillis)
|
||||
while (millis() < startTimeout) {
|
||||
if (_serial_gps->available()) {
|
||||
b = _serial_gps->read();
|
||||
|
||||
#ifdef GPS_DEBUG
|
||||
LOG_DEBUG("%02X", (char *)buffer);
|
||||
#endif
|
||||
@@ -104,6 +164,67 @@ GPS_RESPONSE GPS::getACK(const char *message, uint32_t waitMillis)
|
||||
return GNSS_RESPONSE_NONE;
|
||||
}
|
||||
|
||||
GPS_RESPONSE GPS::getACKCas(uint8_t class_id, uint8_t msg_id, uint32_t waitMillis)
|
||||
{
|
||||
uint32_t startTime = millis();
|
||||
uint8_t buffer[CAS_ACK_NACK_MSG_SIZE] = {0};
|
||||
uint8_t bufferPos = 0;
|
||||
|
||||
// CAS-ACK-(N)ACK structure
|
||||
// | H1 | H2 | Payload Len | cls | msg | Payload | Checksum (4) |
|
||||
// | | | | | | Cls | Msg | Reserved | |
|
||||
// |------|------|-------------|------|------|------|------|-------------|---------------------------|
|
||||
// ACK-NACK| 0xBA | 0xCE | 0x04 | 0x00 | 0x05 | 0x00 | 0xXX | 0xXX | 0x00 | 0x00 | 0xXX | 0xXX | 0xXX | 0xXX |
|
||||
// ACK-ACK | 0xBA | 0xCE | 0x04 | 0x00 | 0x05 | 0x01 | 0xXX | 0xXX | 0x00 | 0x00 | 0xXX | 0xXX | 0xXX | 0xXX |
|
||||
|
||||
while (millis() - startTime < waitMillis) {
|
||||
if (_serial_gps->available()) {
|
||||
buffer[bufferPos++] = _serial_gps->read();
|
||||
|
||||
// keep looking at the first two bytes of buffer until
|
||||
// we have found the CAS frame header (0xBA, 0xCE), if not
|
||||
// keep reading bytes until we find a frame header or we run
|
||||
// out of time.
|
||||
if ((bufferPos == 2) && !(buffer[0] == 0xBA && buffer[1] == 0xCE)) {
|
||||
buffer[0] = buffer[1];
|
||||
buffer[1] = 0;
|
||||
bufferPos = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// we have read all the bytes required for the Ack/Nack (14-bytes)
|
||||
// and we must have found a frame to get this far
|
||||
if (bufferPos == sizeof(buffer) - 1) {
|
||||
uint8_t msg_cls = buffer[4]; // message class should be 0x05
|
||||
uint8_t msg_msg_id = buffer[5]; // message id should be 0x00 or 0x01
|
||||
uint8_t payload_cls = buffer[6]; // payload class id
|
||||
uint8_t payload_msg = buffer[7]; // payload message id
|
||||
|
||||
// Check for an ACK-ACK for the specified class and message id
|
||||
if ((msg_cls == 0x05) && (msg_msg_id == 0x01) && payload_cls == class_id && payload_msg == msg_id) {
|
||||
#ifdef GPS_DEBUG
|
||||
LOG_INFO("Got ACK for class %02X message %02X in %d millis.\n", class_id, msg_id, millis() - startTime);
|
||||
#endif
|
||||
return GNSS_RESPONSE_OK;
|
||||
}
|
||||
|
||||
// Check for an ACK-NACK for the specified class and message id
|
||||
if ((msg_cls == 0x05) && (msg_msg_id == 0x00) && payload_cls == class_id && payload_msg == msg_id) {
|
||||
#ifdef GPS_DEBUG
|
||||
LOG_WARN("Got NACK for class %02X message %02X in %d millis.\n", class_id, msg_id, millis() - startTime);
|
||||
#endif
|
||||
return GNSS_RESPONSE_NAK;
|
||||
}
|
||||
|
||||
// This isn't the frame we are looking for, clear the buffer
|
||||
// and try again until we run out of time.
|
||||
memset(buffer, 0x0, sizeof(buffer));
|
||||
bufferPos = 0;
|
||||
}
|
||||
}
|
||||
return GNSS_RESPONSE_NONE;
|
||||
}
|
||||
|
||||
GPS_RESPONSE GPS::getACK(uint8_t class_id, uint8_t msg_id, uint32_t waitMillis)
|
||||
{
|
||||
uint8_t b;
|
||||
@@ -313,6 +434,33 @@ bool GPS::setup()
|
||||
// Switch to Fitness Mode, for running and walking purpose with low speed (<5 m/s)
|
||||
_serial_gps->write("$PMTK886,1*29\r\n");
|
||||
delay(250);
|
||||
} else if (gnssModel == GNSS_MODEL_ATGM336H) {
|
||||
// Set the intial configuration of the device - these _should_ work for most AT6558 devices
|
||||
msglen = makeCASPacket(0x06, 0x07, sizeof(_message_CAS_CFG_NAVX_CONF), _message_CAS_CFG_NAVX_CONF);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACKCas(0x06, 0x07, 250) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("ATGM336H - Could not set Configuration");
|
||||
}
|
||||
|
||||
// Set the update frequence to 1Hz
|
||||
msglen = makeCASPacket(0x06, 0x04, sizeof(_message_CAS_CFG_RATE_1HZ), _message_CAS_CFG_RATE_1HZ);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACKCas(0x06, 0x04, 250) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("ATGM336H - Could not set Update Frequency");
|
||||
}
|
||||
|
||||
// Set the NEMA output messages
|
||||
// Ask for only RMC and GGA
|
||||
uint8_t fields[] = {CAS_NEMA_RMC, CAS_NEMA_GGA};
|
||||
for (unsigned int i = 0; i < sizeof(fields); i++) {
|
||||
// Construct a CAS-CFG-MSG packet
|
||||
uint8_t cas_cfg_msg_packet[] = {0x4e, fields[i], 0x01, 0x00};
|
||||
msglen = makeCASPacket(0x06, 0x01, sizeof(cas_cfg_msg_packet), cas_cfg_msg_packet);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
if (getACKCas(0x06, 0x01, 250) != GNSS_RESPONSE_OK) {
|
||||
LOG_WARN("ATGM336H - Could not enable NMEA MSG: %d\n", fields[i]);
|
||||
}
|
||||
}
|
||||
} else if (gnssModel == GNSS_MODEL_UC6580) {
|
||||
// The Unicore UC6580 can use a lot of sat systems, enable it to
|
||||
// use GPS L1 & L5 + BDS B1I & B2a + GLONASS L1 + GALILEO E1 & E5a + SBAS
|
||||
@@ -948,10 +1096,18 @@ GnssModel_t GPS::probe(int serialSpeed)
|
||||
uint8_t buffer[768] = {0};
|
||||
delay(100);
|
||||
|
||||
// Close all NMEA sentences , Only valid for L76K MTK platform
|
||||
// Close all NMEA sentences, valid for L76K, ATGM336H (and likely other AT6558 devices)
|
||||
_serial_gps->write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n");
|
||||
delay(20);
|
||||
|
||||
// Get version information
|
||||
clearBuffer();
|
||||
_serial_gps->write("$PCAS06,1*1A\r\n");
|
||||
if (getACK("$GPTXT,01,01,02,HW=ATGM336H", 500) == GNSS_RESPONSE_OK) {
|
||||
LOG_INFO("ATGM336H GNSS init succeeded, using ATGM336H Module\n");
|
||||
return GNSS_MODEL_ATGM336H;
|
||||
}
|
||||
|
||||
// Get version information
|
||||
clearBuffer();
|
||||
_serial_gps->write("$PCAS06,0*1B\r\n");
|
||||
@@ -1216,6 +1372,11 @@ bool GPS::factoryReset()
|
||||
LOG_INFO("GNSS Factory Reset via PCAS10,3\n");
|
||||
_serial_gps->write("$PCAS10,3*1F\r\n");
|
||||
delay(100);
|
||||
} else if (gnssModel == GNSS_MODEL_ATGM336H) {
|
||||
LOG_INFO("Factory Reset via CAS-CFG-RST\n");
|
||||
uint8_t msglen = makeCASPacket(0x06, 0x02, sizeof(_message_CAS_CFG_RST_FACTORY), _message_CAS_CFG_RST_FACTORY);
|
||||
_serial_gps->write(UBXscratch, msglen);
|
||||
delay(100);
|
||||
} else {
|
||||
// fire this for good measure, if we have an L76B - won't harm other devices.
|
||||
_serial_gps->write("$PMTK104*37\r\n");
|
||||
@@ -1306,7 +1467,7 @@ bool GPS::lookForLocation()
|
||||
#endif // GPS_EXTRAVERBOSE
|
||||
|
||||
// Is this a new point or are we re-reading the previous one?
|
||||
if (!reader.location.isUpdated())
|
||||
if (!reader.location.isUpdated() && !reader.altitude.isUpdated())
|
||||
return false;
|
||||
|
||||
// check if a complete GPS solution set is available for reading
|
||||
@@ -1423,7 +1584,7 @@ bool GPS::hasFlow()
|
||||
|
||||
bool GPS::whileIdle()
|
||||
{
|
||||
int charsInBuf = 0;
|
||||
unsigned int charsInBuf = 0;
|
||||
bool isValid = false;
|
||||
if (!isAwake) {
|
||||
clearBuffer();
|
||||
|
||||
@@ -22,7 +22,14 @@ struct uBloxGnssModelInfo {
|
||||
char extension[10][30];
|
||||
};
|
||||
|
||||
typedef enum { GNSS_MODEL_MTK, GNSS_MODEL_UBLOX, GNSS_MODEL_UC6580, GNSS_MODEL_UNKNOWN, GNSS_MODEL_MTK_L76B } GnssModel_t;
|
||||
typedef enum {
|
||||
GNSS_MODEL_ATGM336H,
|
||||
GNSS_MODEL_MTK,
|
||||
GNSS_MODEL_UBLOX,
|
||||
GNSS_MODEL_UC6580,
|
||||
GNSS_MODEL_UNKNOWN,
|
||||
GNSS_MODEL_MTK_L76B
|
||||
} GnssModel_t;
|
||||
|
||||
typedef enum {
|
||||
GNSS_RESPONSE_NONE,
|
||||
@@ -133,6 +140,11 @@ class GPS : private concurrency::OSThread
|
||||
static const uint8_t _message_VALSET_DISABLE_SBAS_RAM[];
|
||||
static const uint8_t _message_VALSET_DISABLE_SBAS_BBR[];
|
||||
|
||||
// CASIC commands for ATGM336H
|
||||
static const uint8_t _message_CAS_CFG_RST_FACTORY[];
|
||||
static const uint8_t _message_CAS_CFG_NAVX_CONF[];
|
||||
static const uint8_t _message_CAS_CFG_RATE_1HZ[];
|
||||
|
||||
meshtastic_Position p = meshtastic_Position_init_default;
|
||||
|
||||
GPS() : concurrency::OSThread("GPS") {}
|
||||
@@ -174,6 +186,7 @@ class GPS : private concurrency::OSThread
|
||||
|
||||
// Create a ublox packet for editing in memory
|
||||
uint8_t makeUBXPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_size, const uint8_t *msg);
|
||||
uint8_t makeCASPacket(uint8_t class_id, uint8_t msg_id, uint8_t payload_size, const uint8_t *msg);
|
||||
|
||||
// scratch space for creating ublox packets
|
||||
uint8_t UBXscratch[250] = {0};
|
||||
@@ -184,6 +197,8 @@ class GPS : private concurrency::OSThread
|
||||
GPS_RESPONSE getACK(uint8_t c, uint8_t i, uint32_t waitMillis);
|
||||
GPS_RESPONSE getACK(const char *message, uint32_t waitMillis);
|
||||
|
||||
GPS_RESPONSE getACKCas(uint8_t class_id, uint8_t msg_id, uint32_t waitMillis);
|
||||
|
||||
/**
|
||||
* Switch the GPS into a mode where we are actively looking for a lock, or alternatively switch GPS into a low power mode
|
||||
*
|
||||
@@ -243,6 +258,7 @@ class GPS : private concurrency::OSThread
|
||||
|
||||
// Calculate checksum
|
||||
void UBXChecksum(uint8_t *message, size_t length);
|
||||
void CASChecksum(uint8_t *message, size_t length);
|
||||
|
||||
/** Get how long we should stay looking for each aquisition
|
||||
*/
|
||||
|
||||
@@ -104,13 +104,15 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
|
||||
bool shouldSet;
|
||||
if (q > currentQuality) {
|
||||
shouldSet = true;
|
||||
LOG_DEBUG("Upgrading time to quality %d\n", q);
|
||||
} else if (q == RTCQualityGPS && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) {
|
||||
// Every 12 hrs we will slam in a new GPS time, to correct for local RTC clock drift
|
||||
LOG_DEBUG("Upgrading time to quality %s\n", RtcName(q));
|
||||
} else if (q >= RTCQualityNTP && (now - lastSetMsec) > (12 * 60 * 60 * 1000UL)) {
|
||||
// Every 12 hrs we will slam in a new GPS or Phone GPS / NTP time, to correct for local RTC clock drift
|
||||
shouldSet = true;
|
||||
LOG_DEBUG("Reapplying external time to correct clock drift %ld secs\n", tv->tv_sec);
|
||||
} else
|
||||
} else {
|
||||
shouldSet = false;
|
||||
LOG_DEBUG("Current RTC quality: %s. Ignoring time of RTC quality of %s\n", RtcName(currentQuality), RtcName(q));
|
||||
}
|
||||
|
||||
if (shouldSet) {
|
||||
currentQuality = q;
|
||||
@@ -162,6 +164,24 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
|
||||
}
|
||||
}
|
||||
|
||||
const char *RtcName(RTCQuality quality)
|
||||
{
|
||||
switch (quality) {
|
||||
case RTCQualityNone:
|
||||
return "None";
|
||||
case RTCQualityDevice:
|
||||
return "Device";
|
||||
case RTCQualityFromNet:
|
||||
return "Net";
|
||||
case RTCQualityNTP:
|
||||
return "NTP";
|
||||
case RTCQualityGPS:
|
||||
return "GPS";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the RTC time if the provided time is of higher quality than the current RTC time.
|
||||
*
|
||||
@@ -203,7 +223,7 @@ int32_t getTZOffset()
|
||||
now = time(NULL);
|
||||
gmt = gmtime(&now);
|
||||
gmt->tm_isdst = -1;
|
||||
return (int16_t)difftime(now, mktime(gmt));
|
||||
return (int32_t)difftime(now, mktime(gmt));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,9 @@ RTCQuality getRTCQuality();
|
||||
bool perhapsSetRTC(RTCQuality q, const struct timeval *tv);
|
||||
bool perhapsSetRTC(RTCQuality q, struct tm &t);
|
||||
|
||||
/// Return a string name for the quality
|
||||
const char *RtcName(RTCQuality quality);
|
||||
|
||||
/// Return time since 1970 in secs. While quality is RTCQualityNone we will be returning time based at zero
|
||||
uint32_t getTime(bool local = false);
|
||||
|
||||
|
||||
63
src/gps/cas.h
Normal file
63
src/gps/cas.h
Normal file
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
// CASIC binary message definitions
|
||||
// Reference: https://www.icofchina.com/d/file/xiazai/2020-09-22/20f1b42b3a11ac52089caf3603b43fb5.pdf
|
||||
// ATGM33H-5N: https://www.icofchina.com/pro/mokuai/2016-08-01/4.html
|
||||
// (https://www.icofchina.com/d/file/xiazai/2016-12-05/b5c57074f4b1fcc62ba8c7868548d18a.pdf)
|
||||
|
||||
// NEMA (Class ID - 0x4e) message IDs
|
||||
#define CAS_NEMA_GGA 0x00
|
||||
#define CAS_NEMA_GLL 0x01
|
||||
#define CAS_NEMA_GSA 0x02
|
||||
#define CAS_NEMA_GSV 0x03
|
||||
#define CAS_NEMA_RMC 0x04
|
||||
#define CAS_NEMA_VTG 0x05
|
||||
#define CAS_NEMA_GST 0x07
|
||||
#define CAS_NEMA_ZDA 0x08
|
||||
#define CAS_NEMA_DHV 0x0D
|
||||
|
||||
// Size of a CAS-ACK-(N)ACK message (14 bytes)
|
||||
#define CAS_ACK_NACK_MSG_SIZE 0x0E
|
||||
|
||||
// CFG-RST (0x06, 0x02)
|
||||
// Factory reset
|
||||
const uint8_t GPS::_message_CAS_CFG_RST_FACTORY[] = {
|
||||
0xFF, 0x03, // Fields to clear
|
||||
0x01, // Reset Mode: Controlled Software reset
|
||||
0x03 // Startup Mode: Factory
|
||||
};
|
||||
|
||||
// CFG_RATE (0x06, 0x01)
|
||||
// 1HZ update rate, this should always be the case after
|
||||
// factory reset but update it regardless
|
||||
const uint8_t GPS::_message_CAS_CFG_RATE_1HZ[] = {
|
||||
0xE8, 0x03, // Update Rate: 0x03E8 = 1000ms
|
||||
0x00, 0x00 // Reserved
|
||||
};
|
||||
|
||||
// CFG-NAVX (0x06, 0x07)
|
||||
// Initial ATGM33H-5N configuration, Updates for Dynamic Mode, Fix Mode, and SV system
|
||||
// Qwirk: The ATGM33H-5N-31 should only support GPS+BDS, however it will happily enable
|
||||
// and use GPS+BDS+GLONASS iff the correct CFG_NAVX command is used.
|
||||
const uint8_t GPS::_message_CAS_CFG_NAVX_CONF[] = {
|
||||
0x03, 0x01, 0x00, 0x00, // Update Mask: Dynamic Mode, Fix Mode, Nav Settings
|
||||
0x03, // Dynamic Mode: Automotive
|
||||
0x03, // Fix Mode: Auto 2D/3D
|
||||
0x00, // Min SV
|
||||
0x00, // Max SVs
|
||||
0x00, // Min CNO
|
||||
0x00, // Reserved1
|
||||
0x00, // Init 3D fix
|
||||
0x00, // Min Elevation
|
||||
0x00, // Dr Limit
|
||||
0x07, // Nav System: 2^0 = GPS, 2^1 = BDS 2^2 = GLONASS: 2^3
|
||||
// 3=GPS+BDS, 7=GPS+BDS+GLONASS
|
||||
0x00, 0x00, // Rollover Week
|
||||
0x00, 0x00, 0x00, 0x00, // Fix Altitude
|
||||
0x00, 0x00, 0x00, 0x00, // Fix Height Error
|
||||
0x00, 0x00, 0x00, 0x00, // PDOP Maximum
|
||||
0x00, 0x00, 0x00, 0x00, // TDOP Maximum
|
||||
0x00, 0x00, 0x00, 0x00, // Position Accuracy Max
|
||||
0x00, 0x00, 0x00, 0x00, // Time Accuracy Max
|
||||
0x00, 0x00, 0x00, 0x00 // Static Hold Threshold
|
||||
};
|
||||
@@ -534,6 +534,10 @@ void EInkDynamicDisplay::checkBusyAsyncRefresh()
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Async refresh appears to have stopped, but wasn't caught by onNotify()
|
||||
else
|
||||
pollAsyncRefresh(); // Check (and terminate) the async refresh manually
|
||||
}
|
||||
|
||||
// Hold control while an async refresh runs
|
||||
|
||||
4
src/graphics/NeoPixel.h
Normal file
4
src/graphics/NeoPixel.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#ifdef HAS_NEOPIXEL
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
extern Adafruit_NeoPixel pixels;
|
||||
#endif
|
||||
@@ -94,6 +94,11 @@ std::vector<MeshModule *> moduleFrames;
|
||||
// Stores the last 4 of our hardware ID, to make finding the device for pairing easier
|
||||
static char ourId[5];
|
||||
|
||||
// vector where symbols (string) are displayed in bottom corner of display.
|
||||
std::vector<std::string> functionSymbals;
|
||||
// string displayed in bottom right corner of display. Created from elements in functionSymbals vector
|
||||
std::string functionSymbalString = "";
|
||||
|
||||
#if HAS_GPS
|
||||
// GeoCoord object for the screen
|
||||
GeoCoord geoCoord;
|
||||
@@ -260,6 +265,18 @@ static void drawWelcomeScreen(OLEDDisplay *display, OLEDDisplayUiState *state, i
|
||||
#endif
|
||||
}
|
||||
|
||||
// draw overlay in bottom right corner of screen to show when notifications are muted or modifier key is active
|
||||
static void drawFunctionOverlay(OLEDDisplay *display, OLEDDisplayUiState *state)
|
||||
{
|
||||
// LOG_DEBUG("Drawing function overlay\n");
|
||||
if (functionSymbals.begin() != functionSymbals.end()) {
|
||||
char buf[64];
|
||||
display->setFont(FONT_SMALL);
|
||||
snprintf(buf, sizeof(buf), "%s", functionSymbalString.c_str());
|
||||
display->drawString(SCREEN_WIDTH - display->getStringWidth(buf), SCREEN_HEIGHT - FONT_HEIGHT_SMALL, buf);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_EINK
|
||||
/// Used on eink displays while in deep sleep
|
||||
static void drawDeepSleepScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
@@ -1023,7 +1040,14 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver)
|
||||
#if !ARCH_PORTDUINO
|
||||
dispdev->displayOn();
|
||||
#endif
|
||||
|
||||
#if defined(ST7789_CS) && \
|
||||
!defined(M5STACK) // set display brightness when turning on screens. Just moved function from TFTDisplay to here.
|
||||
static_cast<TFTDisplay *>(dispdev)->setDisplayBrightness(brightness);
|
||||
#endif
|
||||
|
||||
dispdev->displayOn();
|
||||
|
||||
enabled = true;
|
||||
setInterval(0); // Draw ASAP
|
||||
runASAP = true;
|
||||
@@ -1490,6 +1514,11 @@ void Screen::setFrames()
|
||||
ui->setFrames(normalFrames, numframes);
|
||||
ui->enableAllIndicators();
|
||||
|
||||
// Add function overlay here. This can show when notifications muted, modifier key is active etc
|
||||
static OverlayCallback functionOverlay[] = {drawFunctionOverlay};
|
||||
static const int functionOverlayCount = sizeof(functionOverlay) / sizeof(functionOverlay[0]);
|
||||
ui->setOverlays(functionOverlay, functionOverlayCount);
|
||||
|
||||
prevFrame = -1; // Force drawNodeInfo to pick a new node (because our list
|
||||
// just changed)
|
||||
|
||||
@@ -1573,9 +1602,55 @@ void Screen::blink()
|
||||
delay(50);
|
||||
count = count - 1;
|
||||
}
|
||||
// The dispdev->setBrightness does not work for t-deck display, it seems to run the setBrightness function in OLEDDisplay.
|
||||
dispdev->setBrightness(brightness);
|
||||
}
|
||||
|
||||
void Screen::increaseBrightness()
|
||||
{
|
||||
brightness = ((brightness + 62) > 254) ? brightness : (brightness + 62);
|
||||
|
||||
#if defined(ST7789_CS)
|
||||
// run the setDisplayBrightness function. This works on t-decks
|
||||
static_cast<TFTDisplay *>(dispdev)->setDisplayBrightness(brightness);
|
||||
#endif
|
||||
|
||||
/* TO DO: add little popup in center of screen saying what brightness level it is set to*/
|
||||
}
|
||||
|
||||
void Screen::decreaseBrightness()
|
||||
{
|
||||
brightness = (brightness < 70) ? brightness : (brightness - 62);
|
||||
|
||||
#if defined(ST7789_CS)
|
||||
static_cast<TFTDisplay *>(dispdev)->setDisplayBrightness(brightness);
|
||||
#endif
|
||||
|
||||
/* TO DO: add little popup in center of screen saying what brightness level it is set to*/
|
||||
}
|
||||
|
||||
void Screen::setFunctionSymbal(std::string sym)
|
||||
{
|
||||
if (std::find(functionSymbals.begin(), functionSymbals.end(), sym) == functionSymbals.end()) {
|
||||
functionSymbals.push_back(sym);
|
||||
functionSymbalString = "";
|
||||
for (auto symbol : functionSymbals) {
|
||||
functionSymbalString = symbol + " " + functionSymbalString;
|
||||
}
|
||||
setFastFramerate();
|
||||
}
|
||||
}
|
||||
|
||||
void Screen::removeFunctionSymbal(std::string sym)
|
||||
{
|
||||
functionSymbals.erase(std::remove(functionSymbals.begin(), functionSymbals.end(), sym), functionSymbals.end());
|
||||
functionSymbalString = "";
|
||||
for (auto symbol : functionSymbals) {
|
||||
functionSymbalString = symbol + " " + functionSymbalString;
|
||||
}
|
||||
setFastFramerate();
|
||||
}
|
||||
|
||||
std::string Screen::drawTimeDelta(uint32_t days, uint32_t hours, uint32_t minutes, uint32_t seconds)
|
||||
{
|
||||
std::string uptime;
|
||||
@@ -1998,4 +2073,4 @@ int Screen::handleInputEvent(const InputEvent *event)
|
||||
} // namespace graphics
|
||||
#else
|
||||
graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {}
|
||||
#endif // HAS_SCREEN
|
||||
#endif // HAS_SCREEN
|
||||
@@ -166,9 +166,6 @@ class Screen : public concurrency::OSThread
|
||||
void showPrevFrame() { enqueueCmd(ScreenCmd{.cmd = Cmd::SHOW_PREV_FRAME}); }
|
||||
void showNextFrame() { enqueueCmd(ScreenCmd{.cmd = Cmd::SHOW_NEXT_FRAME}); }
|
||||
|
||||
// Implementation to Adjust Brightness
|
||||
uint8_t brightness = BRIGHTNESS_DEFAULT;
|
||||
|
||||
/// Starts showing the Bluetooth PIN screen.
|
||||
//
|
||||
// Switches over to a static frame showing the Bluetooth pairing screen
|
||||
@@ -202,6 +199,13 @@ class Screen : public concurrency::OSThread
|
||||
enqueueCmd(cmd);
|
||||
}
|
||||
|
||||
// functions for display brightness
|
||||
void increaseBrightness();
|
||||
void decreaseBrightness();
|
||||
|
||||
void setFunctionSymbal(std::string sym);
|
||||
void removeFunctionSymbal(std::string sym);
|
||||
|
||||
/// Stops showing the bluetooth PIN screen.
|
||||
void stopBluetoothPinScreen() { enqueueCmd(ScreenCmd{.cmd = Cmd::STOP_BLUETOOTH_PIN_SCREEN}); }
|
||||
|
||||
@@ -395,6 +399,9 @@ class Screen : public concurrency::OSThread
|
||||
// Bluetooth PIN screen)
|
||||
bool showingNormalScreen = false;
|
||||
|
||||
// Implementation to Adjust Brightness
|
||||
uint8_t brightness = BRIGHTNESS_DEFAULT; // H = 254, MH = 192, ML = 130 L = 103
|
||||
|
||||
/// Holds state for debug information
|
||||
DebugInfo debugInfo;
|
||||
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
#define TFT_BACKLIGHT_ON HIGH
|
||||
#endif
|
||||
|
||||
#ifdef GPIO_EXTENDER
|
||||
#include <SparkFunSX1509.h>
|
||||
#include <Wire.h>
|
||||
extern SX1509 gpioExtender;
|
||||
#endif
|
||||
|
||||
#ifndef TFT_MESH
|
||||
#define TFT_MESH COLOR565(0x67, 0xEA, 0x94)
|
||||
#endif
|
||||
@@ -356,6 +362,7 @@ class LGFX : public lgfx::LGFX_Device
|
||||
_panel_instance = new lgfx::Panel_ILI9341;
|
||||
auto buscfg = _bus_instance.config();
|
||||
buscfg.spi_mode = 0;
|
||||
buscfg.spi_host = settingsMap[displayspidev];
|
||||
|
||||
buscfg.pin_dc = settingsMap[displayDC]; // Set SPI DC pin number (-1 = disable)
|
||||
|
||||
@@ -381,6 +388,8 @@ class LGFX : public lgfx::LGFX_Device
|
||||
_touch_instance = new lgfx::Touch_XPT2046;
|
||||
} else if (settingsMap[touchscreenModule] == stmpe610) {
|
||||
_touch_instance = new lgfx::Touch_STMPE610;
|
||||
} else if (settingsMap[touchscreenModule] == ft5x06) {
|
||||
_touch_instance = new lgfx::Touch_FT5x06;
|
||||
}
|
||||
auto touch_cfg = _touch_instance->config();
|
||||
|
||||
@@ -392,6 +401,11 @@ class LGFX : public lgfx::LGFX_Device
|
||||
touch_cfg.pin_int = settingsMap[touchscreenIRQ];
|
||||
touch_cfg.bus_shared = true;
|
||||
touch_cfg.offset_rotation = 1;
|
||||
if (settingsMap[touchscreenI2CAddr] != -1) {
|
||||
touch_cfg.i2c_addr = settingsMap[touchscreenI2CAddr];
|
||||
} else {
|
||||
touch_cfg.spi_host = settingsMap[touchscreenspidev];
|
||||
}
|
||||
|
||||
_touch_instance->config(touch_cfg);
|
||||
_panel_instance->setTouch(_touch_instance);
|
||||
@@ -411,8 +425,7 @@ class LGFX : public lgfx::LGFX_Device
|
||||
lgfx::Panel_HX8357D _panel_instance;
|
||||
lgfx::Bus_SPI _bus_instance;
|
||||
#if defined(USE_XPT2046)
|
||||
lgfx::ITouch *_touch_instance;
|
||||
// lgfx::Touch_XPT2046 _touch_instance;
|
||||
lgfx::Touch_XPT2046 _touch_instance;
|
||||
#endif
|
||||
|
||||
public:
|
||||
@@ -466,8 +479,7 @@ class LGFX : public lgfx::LGFX_Device
|
||||
#if defined(USE_XPT2046)
|
||||
{
|
||||
// Configure settings for touch control.
|
||||
_touch_instance = new lgfx::Touch_XPT2046;
|
||||
auto touch_cfg = _touch_instance->config();
|
||||
auto touch_cfg = _touch_instance.config();
|
||||
|
||||
touch_cfg.pin_cs = TOUCH_CS;
|
||||
touch_cfg.x_min = 0;
|
||||
@@ -478,8 +490,8 @@ class LGFX : public lgfx::LGFX_Device
|
||||
touch_cfg.bus_shared = true;
|
||||
touch_cfg.offset_rotation = 1;
|
||||
|
||||
_touch_instance->config(touch_cfg);
|
||||
//_panel_instance->setTouch(_touch_instance);
|
||||
_touch_instance.config(touch_cfg);
|
||||
_panel_instance.setTouch(&_touch_instance);
|
||||
}
|
||||
#endif
|
||||
setPanel(&_panel_instance);
|
||||
@@ -496,6 +508,11 @@ static LGFX *tft = nullptr;
|
||||
#include "TFTDisplay.h"
|
||||
#include <SPI.h>
|
||||
|
||||
#ifdef UNPHONE
|
||||
#include "unPhone.h"
|
||||
extern unPhone unphone;
|
||||
#endif
|
||||
|
||||
TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY geometry, HW_I2C i2cBus)
|
||||
{
|
||||
LOG_DEBUG("TFTDisplay!\n");
|
||||
@@ -561,8 +578,10 @@ void TFTDisplay::sendCommand(uint8_t com)
|
||||
#elif defined(ST7735_BL_V05)
|
||||
pinMode(ST7735_BL_V05, OUTPUT);
|
||||
digitalWrite(ST7735_BL_V05, TFT_BACKLIGHT_ON);
|
||||
#endif
|
||||
#if defined(TFT_BL) && defined(TFT_BACKLIGHT_ON)
|
||||
#elif !defined(RAK14014) && !defined(M5STACK) && !defined(UNPHONE)
|
||||
tft->wakeup();
|
||||
tft->powerSaveOff();
|
||||
#elif defined(TFT_BL) && defined(TFT_BACKLIGHT_ON)
|
||||
digitalWrite(TFT_BL, TFT_BACKLIGHT_ON);
|
||||
#endif
|
||||
|
||||
@@ -574,14 +593,10 @@ void TFTDisplay::sendCommand(uint8_t com)
|
||||
digitalWrite(VTFT_CTRL, LOW);
|
||||
#endif
|
||||
#ifdef UNPHONE
|
||||
Wire.beginTransmission(0x26);
|
||||
Wire.write(0x02);
|
||||
Wire.write(0x04); // Backlight on
|
||||
Wire.write(0x22); // G&B LEDs off
|
||||
Wire.endTransmission();
|
||||
unphone.backlight(true); // using unPhone library
|
||||
#endif
|
||||
#ifdef RAK14014
|
||||
#elif !defined(M5STACK)
|
||||
#elif !defined(M5STACK) && !defined(ST7789_CS) // T-Deck gets brightness set in Screen.cpp in the handleSetOn function
|
||||
tft->setBrightness(172);
|
||||
#endif
|
||||
break;
|
||||
@@ -596,10 +611,13 @@ void TFTDisplay::sendCommand(uint8_t com)
|
||||
#elif defined(ST7735_BL_V05)
|
||||
pinMode(ST7735_BL_V05, OUTPUT);
|
||||
digitalWrite(ST7735_BL_V05, !TFT_BACKLIGHT_ON);
|
||||
#endif
|
||||
#if defined(TFT_BL) && defined(TFT_BACKLIGHT_ON)
|
||||
#elif !defined(RAK14014) && !defined(M5STACK) && !defined(UNPHONE)
|
||||
tft->sleep();
|
||||
tft->powerSaveOn();
|
||||
#elif defined(TFT_BL) && defined(TFT_BACKLIGHT_ON)
|
||||
digitalWrite(TFT_BL, !TFT_BACKLIGHT_ON);
|
||||
#endif
|
||||
|
||||
#ifdef VTFT_CTRL_V03
|
||||
digitalWrite(VTFT_CTRL_V03, HIGH);
|
||||
#endif
|
||||
@@ -607,11 +625,7 @@ void TFTDisplay::sendCommand(uint8_t com)
|
||||
digitalWrite(VTFT_CTRL, HIGH);
|
||||
#endif
|
||||
#ifdef UNPHONE
|
||||
Wire.beginTransmission(0x26);
|
||||
Wire.write(0x02);
|
||||
Wire.write(0x00); // Backlight off
|
||||
Wire.write(0x22); // G&B LEDs off
|
||||
Wire.endTransmission();
|
||||
unphone.backlight(false); // using unPhone library
|
||||
#endif
|
||||
#ifdef RAK14014
|
||||
#elif !defined(M5STACK)
|
||||
@@ -626,6 +640,12 @@ void TFTDisplay::sendCommand(uint8_t com)
|
||||
// Drop all other commands to device (we just update the buffer)
|
||||
}
|
||||
|
||||
void TFTDisplay::setDisplayBrightness(uint8_t _brightness)
|
||||
{
|
||||
tft->setBrightness(_brightness);
|
||||
LOG_DEBUG("Brightness is set to value: %i \n", _brightness);
|
||||
}
|
||||
|
||||
void TFTDisplay::flipScreenVertically()
|
||||
{
|
||||
#if defined(T_WATCH_S3)
|
||||
@@ -685,11 +705,7 @@ bool TFTDisplay::connect()
|
||||
digitalWrite(ST7735_BL_V05, TFT_BACKLIGHT_ON);
|
||||
#endif
|
||||
#ifdef UNPHONE
|
||||
Wire.beginTransmission(0x26);
|
||||
Wire.write(0x02);
|
||||
Wire.write(0x04); // Backlight on
|
||||
Wire.write(0x22); // G&B LEDs off
|
||||
Wire.endTransmission();
|
||||
unphone.backlight(true); // using unPhone library
|
||||
LOG_INFO("Power to TFT Backlight\n");
|
||||
#endif
|
||||
|
||||
@@ -713,4 +729,4 @@ bool TFTDisplay::connect()
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -30,6 +30,9 @@ class TFTDisplay : public OLEDDisplay
|
||||
static bool hasTouch(void);
|
||||
static bool getTouch(int16_t *x, int16_t *y);
|
||||
|
||||
// Functions for changing display brightness
|
||||
void setDisplayBrightness(uint8_t);
|
||||
|
||||
/**
|
||||
* shim to make the abstraction happy
|
||||
*
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "InputBroker.h"
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "mesh/NodeDB.h"
|
||||
#include "time.h"
|
||||
|
||||
typedef struct _TouchEvent {
|
||||
const char *source;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "configuration.h"
|
||||
#include "modules/ExternalNotificationModule.h"
|
||||
|
||||
#ifdef ARCH_PORTDUINO
|
||||
#if ARCH_PORTDUINO
|
||||
#include "platform/portduino/PortduinoGlue.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "UpDownInterruptBase.h"
|
||||
#include "configuration.h"
|
||||
|
||||
UpDownInterruptBase::UpDownInterruptBase(const char *name)
|
||||
UpDownInterruptBase::UpDownInterruptBase(const char *name) : concurrency::OSThread(name)
|
||||
{
|
||||
this->_originName = name;
|
||||
}
|
||||
@@ -24,31 +24,48 @@ void UpDownInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinPress,
|
||||
attachInterrupt(this->_pinUp, onIntUp, RISING);
|
||||
|
||||
LOG_DEBUG("Up/down/press GPIO initialized (%d, %d, %d)\n", this->_pinUp, this->_pinDown, pinPress);
|
||||
|
||||
this->setInterval(100);
|
||||
}
|
||||
|
||||
int32_t UpDownInterruptBase::runOnce()
|
||||
{
|
||||
InputEvent e;
|
||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||
|
||||
if (this->action == UPDOWN_ACTION_PRESSED) {
|
||||
LOG_DEBUG("GPIO event Press\n");
|
||||
e.inputEvent = this->_eventPressed;
|
||||
} else if (this->action == UPDOWN_ACTION_UP) {
|
||||
LOG_DEBUG("GPIO event Up\n");
|
||||
e.inputEvent = this->_eventUp;
|
||||
} else if (this->action == UPDOWN_ACTION_DOWN) {
|
||||
LOG_DEBUG("GPIO event Down\n");
|
||||
e.inputEvent = this->_eventDown;
|
||||
}
|
||||
|
||||
if (e.inputEvent != meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
|
||||
e.source = this->_originName;
|
||||
e.kbchar = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||
this->notifyObservers(&e);
|
||||
}
|
||||
|
||||
this->action = UPDOWN_ACTION_NONE;
|
||||
|
||||
return 100;
|
||||
}
|
||||
|
||||
void UpDownInterruptBase::intPressHandler()
|
||||
{
|
||||
InputEvent e;
|
||||
e.source = this->_originName;
|
||||
LOG_DEBUG("GPIO event Press\n");
|
||||
e.inputEvent = this->_eventPressed;
|
||||
this->notifyObservers(&e);
|
||||
this->action = UPDOWN_ACTION_PRESSED;
|
||||
}
|
||||
|
||||
void UpDownInterruptBase::intDownHandler()
|
||||
{
|
||||
InputEvent e;
|
||||
e.source = this->_originName;
|
||||
LOG_DEBUG("GPIO event Down\n");
|
||||
e.inputEvent = this->_eventDown;
|
||||
this->notifyObservers(&e);
|
||||
this->action = UPDOWN_ACTION_DOWN;
|
||||
}
|
||||
|
||||
void UpDownInterruptBase::intUpHandler()
|
||||
{
|
||||
InputEvent e;
|
||||
e.source = this->_originName;
|
||||
LOG_DEBUG("GPIO event Up\n");
|
||||
e.inputEvent = this->_eventUp;
|
||||
this->notifyObservers(&e);
|
||||
this->action = UPDOWN_ACTION_UP;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "InputBroker.h"
|
||||
#include "mesh/NodeDB.h"
|
||||
|
||||
class UpDownInterruptBase : public Observable<const InputEvent *>
|
||||
class UpDownInterruptBase : public Observable<const InputEvent *>, public concurrency::OSThread
|
||||
{
|
||||
public:
|
||||
explicit UpDownInterruptBase(const char *name);
|
||||
@@ -13,6 +13,13 @@ class UpDownInterruptBase : public Observable<const InputEvent *>
|
||||
void intDownHandler();
|
||||
void intUpHandler();
|
||||
|
||||
int32_t runOnce() override;
|
||||
|
||||
protected:
|
||||
enum UpDownInterruptBaseActionType { UPDOWN_ACTION_NONE, UPDOWN_ACTION_PRESSED, UPDOWN_ACTION_UP, UPDOWN_ACTION_DOWN };
|
||||
|
||||
volatile UpDownInterruptBaseActionType action = UPDOWN_ACTION_NONE;
|
||||
|
||||
private:
|
||||
uint8_t _pinDown = 0;
|
||||
uint8_t _pinUp = 0;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "kbI2cBase.h"
|
||||
|
||||
#include "configuration.h"
|
||||
#include "detect/ScanI2C.h"
|
||||
|
||||
@@ -138,6 +137,9 @@ int32_t KbI2cBase::runOnce()
|
||||
break;
|
||||
case 0x13: // Code scanner says the SYM key is 0x13
|
||||
is_sym = !is_sym;
|
||||
e.inputEvent = ANYKEY;
|
||||
e.kbchar =
|
||||
is_sym ? 0xf1 : 0xf2; // send 0xf1 to tell CannedMessages to display that the modifier key is active
|
||||
break;
|
||||
case 0x0a: // apparently Enter on Q10 is a line feed instead of carriage return
|
||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
|
||||
@@ -193,6 +195,75 @@ int32_t KbI2cBase::runOnce()
|
||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||
e.source = this->_originName;
|
||||
switch (c) {
|
||||
case 0x71: // This is the button q. If modifier and q pressed, it cancels the input
|
||||
if (is_sym) {
|
||||
is_sym = false;
|
||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL;
|
||||
} else {
|
||||
e.inputEvent = ANYKEY;
|
||||
e.kbchar = c;
|
||||
}
|
||||
break;
|
||||
case 0x74: // letter t. if modifier and t pressed call 'tab'
|
||||
if (is_sym) {
|
||||
is_sym = false;
|
||||
e.inputEvent = ANYKEY;
|
||||
e.kbchar = 0x09; // TAB Scancode
|
||||
} else {
|
||||
e.inputEvent = ANYKEY;
|
||||
e.kbchar = c;
|
||||
}
|
||||
break;
|
||||
case 0x6d: // letter m. Modifier makes it mute notifications
|
||||
if (is_sym) {
|
||||
is_sym = false;
|
||||
e.inputEvent = ANYKEY;
|
||||
e.kbchar = 0xac; // mute notifications
|
||||
} else {
|
||||
e.inputEvent = ANYKEY;
|
||||
e.kbchar = c;
|
||||
}
|
||||
break;
|
||||
case 0x6f: // letter o(+). Modifier makes screen increase in brightness
|
||||
if (is_sym) {
|
||||
is_sym = false;
|
||||
e.inputEvent = ANYKEY;
|
||||
e.kbchar = 0x11; // Increase Brightness code
|
||||
} else {
|
||||
e.inputEvent = ANYKEY;
|
||||
e.kbchar = c;
|
||||
}
|
||||
break;
|
||||
case 0x69: // letter i(-). Modifier makes screen decrease in brightness
|
||||
if (is_sym) {
|
||||
is_sym = false;
|
||||
e.inputEvent = ANYKEY;
|
||||
e.kbchar = 0x12; // Decrease Brightness code
|
||||
} else {
|
||||
e.inputEvent = ANYKEY;
|
||||
e.kbchar = c;
|
||||
}
|
||||
break;
|
||||
case 0x20: // Space. Send network ping like double press does
|
||||
if (is_sym) {
|
||||
is_sym = false;
|
||||
e.inputEvent = ANYKEY;
|
||||
e.kbchar = 0xaf; // (fn + space)
|
||||
} else {
|
||||
e.inputEvent = ANYKEY;
|
||||
e.kbchar = c;
|
||||
}
|
||||
break;
|
||||
case 0x67: // letter g. toggle gps
|
||||
if (is_sym) {
|
||||
is_sym = false;
|
||||
e.inputEvent = ANYKEY;
|
||||
e.kbchar = 0x9e;
|
||||
} else {
|
||||
e.inputEvent = ANYKEY;
|
||||
e.kbchar = c;
|
||||
}
|
||||
break;
|
||||
case 0x1b: // ESC
|
||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL;
|
||||
break;
|
||||
@@ -216,6 +287,12 @@ int32_t KbI2cBase::runOnce()
|
||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
|
||||
e.kbchar = 0xb7;
|
||||
break;
|
||||
case 0xc: // Modifier key: 0xc is alt+c (Other options could be: 0xea = shift+mic button or 0x4 shift+$(speaker))
|
||||
// toggle moddifiers button.
|
||||
is_sym = !is_sym;
|
||||
e.inputEvent = ANYKEY;
|
||||
e.kbchar = is_sym ? 0xf1 : 0xf2; // send 0xf1 to tell CannedMessages to display that the modifier key is active
|
||||
break;
|
||||
case 0x90: // fn+r
|
||||
case 0x91: // fn+t
|
||||
case 0x9b: // fn+s
|
||||
@@ -239,6 +316,7 @@ int32_t KbI2cBase::runOnce()
|
||||
}
|
||||
e.inputEvent = ANYKEY;
|
||||
e.kbchar = c;
|
||||
is_sym = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
82
src/main.cpp
82
src/main.cpp
@@ -69,6 +69,7 @@ NRF52Bluetooth *nrf52Bluetooth;
|
||||
#include "SX1262Interface.h"
|
||||
#include "SX1268Interface.h"
|
||||
#include "SX1280Interface.h"
|
||||
#include "detect/LoRaRadioType.h"
|
||||
|
||||
#ifdef ARCH_STM32WL
|
||||
#include "STM32WLE5JCInterface.h"
|
||||
@@ -142,6 +143,9 @@ ATECCX08A atecc;
|
||||
Adafruit_DRV2605 drv;
|
||||
#endif
|
||||
|
||||
// Global LoRa radio type
|
||||
LoRaRadioType radioType = NO_RADIO;
|
||||
|
||||
bool isVibrating = false;
|
||||
|
||||
bool eink_found = true;
|
||||
@@ -175,6 +179,11 @@ const char *getDeviceName()
|
||||
|
||||
static int32_t ledBlinker()
|
||||
{
|
||||
// Still set up the blinking (heartbeat) interval but skip code path below, so LED will blink if
|
||||
// config.device.led_heartbeat_disabled is changed
|
||||
if (config.device.led_heartbeat_disabled)
|
||||
return 1000;
|
||||
|
||||
static bool ledOn;
|
||||
ledOn ^= 1;
|
||||
|
||||
@@ -188,10 +197,9 @@ uint32_t timeLastPowered = 0;
|
||||
|
||||
static Periodic *ledPeriodic;
|
||||
static OSThread *powerFSMthread;
|
||||
#if HAS_BUTTON || defined(ARCH_PORTDUINO)
|
||||
static OSThread *buttonThread;
|
||||
#endif
|
||||
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||
static OSThread *accelerometerThread;
|
||||
#endif
|
||||
static OSThread *ambientLightingThread;
|
||||
SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0);
|
||||
|
||||
@@ -336,7 +344,7 @@ void setup()
|
||||
Wire.begin(I2C_SDA, I2C_SCL);
|
||||
#elif defined(ARCH_PORTDUINO)
|
||||
if (settingsStrings[i2cdev] != "") {
|
||||
LOG_INFO("Using %s as I2C device.\n", settingsStrings[i2cdev]);
|
||||
LOG_INFO("Using %s as I2C device.\n", settingsStrings[i2cdev].c_str());
|
||||
Wire.begin(settingsStrings[i2cdev].c_str());
|
||||
} else {
|
||||
LOG_INFO("No I2C device configured, skipping.\n");
|
||||
@@ -386,7 +394,7 @@ void setup()
|
||||
// We need to scan here to decide if we have a screen for nodeDB.init() and because power has been applied to
|
||||
// accessories
|
||||
auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire());
|
||||
#ifdef HAS_WIRE
|
||||
#if HAS_WIRE
|
||||
LOG_INFO("Scanning for i2c devices...\n");
|
||||
#endif
|
||||
|
||||
@@ -532,6 +540,8 @@ void setup()
|
||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::QMI8658, meshtastic_TelemetrySensorType_QMI8658)
|
||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::QMC5883L, meshtastic_TelemetrySensorType_QMC5883L)
|
||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::PMSA0031, meshtastic_TelemetrySensorType_PMSA003I)
|
||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::RCWL9620, meshtastic_TelemetrySensorType_RCWL9620)
|
||||
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHT4X, meshtastic_TelemetrySensorType_SHT4X)
|
||||
|
||||
i2cScanner.reset();
|
||||
|
||||
@@ -589,20 +599,6 @@ void setup()
|
||||
if (config.display.oled != meshtastic_Config_DisplayConfig_OledType_OLED_AUTO)
|
||||
screen_model = config.display.oled;
|
||||
|
||||
#ifdef UNPHONE
|
||||
// initialise IO expander with pinmodes
|
||||
Wire.beginTransmission(0x26);
|
||||
Wire.write(0x06);
|
||||
Wire.write(0x7A);
|
||||
Wire.write(0xDD);
|
||||
Wire.endTransmission();
|
||||
Wire.beginTransmission(0x26);
|
||||
Wire.write(0x02);
|
||||
Wire.write(0x04); // Backlight on
|
||||
Wire.write(0x22); // G&B LEDs off
|
||||
Wire.endTransmission();
|
||||
#endif
|
||||
|
||||
#if defined(USE_SH1107)
|
||||
screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1107; // set dimension of 128x128
|
||||
display_geometry = GEOMETRY_128_128;
|
||||
@@ -612,7 +608,7 @@ void setup()
|
||||
screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1107; // keep dimension of 128x64
|
||||
#endif
|
||||
|
||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||
if (acc_info.type != ScanI2C::DeviceType::NONE) {
|
||||
config.display.wake_on_tap_or_motion = true;
|
||||
moduleConfig.external_notification.enabled = true;
|
||||
@@ -620,7 +616,9 @@ void setup()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||
#if defined(HAS_NEOPIXEL) || defined(UNPHONE) || defined(RGBLED_RED)
|
||||
ambientLightingThread = new AmbientLightingThread(ScanI2C::DeviceType::NONE);
|
||||
#elif !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||
if (rgb_found.type != ScanI2C::DeviceType::NONE) {
|
||||
ambientLightingThread = new AmbientLightingThread(rgb_found.type);
|
||||
}
|
||||
@@ -643,14 +641,12 @@ void setup()
|
||||
pinMode(LORA_CS, OUTPUT);
|
||||
digitalWrite(LORA_CS, HIGH);
|
||||
SPI1.begin(false);
|
||||
#else // HW_SPI1_DEVICE
|
||||
#else // HW_SPI1_DEVICE
|
||||
SPI.setSCK(LORA_SCK);
|
||||
SPI.setTX(LORA_MOSI);
|
||||
SPI.setRX(LORA_MISO);
|
||||
SPI.begin(false);
|
||||
#endif // HW_SPI1_DEVICE
|
||||
#elif ARCH_PORTDUINO
|
||||
SPI.begin(settingsStrings[spidev].c_str());
|
||||
#endif // HW_SPI1_DEVICE
|
||||
#elif !defined(ARCH_ESP32) // ARCH_RP2040
|
||||
SPI.begin();
|
||||
#else
|
||||
@@ -701,6 +697,12 @@ void setup()
|
||||
// Now that the mesh service is created, create any modules
|
||||
setupModules();
|
||||
|
||||
#ifdef LED_PIN
|
||||
// Turn LED off after boot, if heartbeat by config
|
||||
if (config.device.led_heartbeat_disabled)
|
||||
digitalWrite(LED_PIN, LOW ^ LED_INVERTED);
|
||||
#endif
|
||||
|
||||
// Do this after service.init (because that clears error_code)
|
||||
#ifdef HAS_PMU
|
||||
if (!pmu_found)
|
||||
@@ -737,7 +739,8 @@ void setup()
|
||||
if (settingsMap[use_sx1262]) {
|
||||
if (!rIf) {
|
||||
LOG_DEBUG("Attempting to activate sx1262 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
||||
LockingArduinoHal *RadioLibHAL =
|
||||
new LockingArduinoHal(SPI, spiSettings, (settingsMap[ch341Quirk] ? settingsMap[busy] : RADIOLIB_NC));
|
||||
rIf = new SX1262Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
||||
settingsMap[busy]);
|
||||
if (!rIf->init()) {
|
||||
@@ -751,7 +754,8 @@ void setup()
|
||||
} else if (settingsMap[use_rf95]) {
|
||||
if (!rIf) {
|
||||
LOG_DEBUG("Attempting to activate rf95 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
||||
LockingArduinoHal *RadioLibHAL =
|
||||
new LockingArduinoHal(SPI, spiSettings, (settingsMap[ch341Quirk] ? settingsMap[busy] : RADIOLIB_NC));
|
||||
rIf = new RF95Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
||||
settingsMap[busy]);
|
||||
if (!rIf->init()) {
|
||||
@@ -778,6 +782,21 @@ void setup()
|
||||
LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio\n");
|
||||
}
|
||||
}
|
||||
} else if (settingsMap[use_sx1268]) {
|
||||
if (!rIf) {
|
||||
LOG_DEBUG("Attempting to activate sx1268 radio on SPI port %s\n", settingsStrings[spidev].c_str());
|
||||
LockingArduinoHal *RadioLibHAL = new LockingArduinoHal(SPI, spiSettings);
|
||||
rIf = new SX1268Interface((LockingArduinoHal *)RadioLibHAL, settingsMap[cs], settingsMap[irq], settingsMap[reset],
|
||||
settingsMap[busy]);
|
||||
if (!rIf->init()) {
|
||||
LOG_ERROR("Failed to find SX1268 radio\n");
|
||||
delete rIf;
|
||||
rIf = NULL;
|
||||
exit(EXIT_FAILURE);
|
||||
} else {
|
||||
LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(HW_SPI1_DEVICE)
|
||||
@@ -796,6 +815,7 @@ void setup()
|
||||
rIf = NULL;
|
||||
} else {
|
||||
LOG_INFO("STM32WL Radio init succeeded, using STM32WL radio\n");
|
||||
radioType = STM32WLx_RADIO;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -809,6 +829,7 @@ void setup()
|
||||
rIf = NULL;
|
||||
} else {
|
||||
LOG_INFO("Using SIMULATED radio!\n");
|
||||
radioType = SIM_RADIO;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -822,6 +843,7 @@ void setup()
|
||||
rIf = NULL;
|
||||
} else {
|
||||
LOG_INFO("RF95 Radio init succeeded, using RF95 radio\n");
|
||||
radioType = RF95_RADIO;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -835,6 +857,7 @@ void setup()
|
||||
rIf = NULL;
|
||||
} else {
|
||||
LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio\n");
|
||||
radioType = SX1262_RADIO;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -848,6 +871,7 @@ void setup()
|
||||
rIf = NULL;
|
||||
} else {
|
||||
LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio\n");
|
||||
radioType = SX1268_RADIO;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -861,6 +885,7 @@ void setup()
|
||||
rIf = NULL;
|
||||
} else {
|
||||
LOG_INFO("LLCC68 Radio init succeeded, using LLCC68 radio\n");
|
||||
radioType = LLCC68_RADIO;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -874,6 +899,7 @@ void setup()
|
||||
rIf = NULL;
|
||||
} else {
|
||||
LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio\n");
|
||||
radioType = SX1280_RADIO;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1009,4 +1035,4 @@ void loop()
|
||||
mainDelay.delay(delayMsec);
|
||||
}
|
||||
// if (didWake) LOG_DEBUG("wake!\n");
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,11 @@ extern NimbleBluetooth *nimbleBluetooth;
|
||||
extern NRF52Bluetooth *nrf52Bluetooth;
|
||||
#endif
|
||||
|
||||
#if ARCH_PORTDUINO
|
||||
extern HardwareSPI *DisplaySPI;
|
||||
extern HardwareSPI *LoraSPI;
|
||||
|
||||
#endif
|
||||
extern ScanI2C::DeviceAddress screen_found;
|
||||
extern ScanI2C::DeviceAddress cardkb_found;
|
||||
extern uint8_t kb_model;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <NodeDB.h>
|
||||
#include <cstdint>
|
||||
#define ONE_DAY 24 * 60 * 60
|
||||
#define ONE_MINUTE_MS 60 * 1000
|
||||
|
||||
#define default_gps_update_interval IF_ROUTER(ONE_DAY, 2 * 60)
|
||||
#define default_broadcast_interval_secs IF_ROUTER(ONE_DAY / 2, 15 * 60)
|
||||
@@ -27,4 +28,4 @@ class Default
|
||||
static uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval);
|
||||
static uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t defaultInterval);
|
||||
static uint32_t getConfiguredOrDefault(uint32_t configured, uint32_t defaultValue);
|
||||
};
|
||||
};
|
||||
@@ -35,11 +35,10 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
|
||||
|
||||
void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Routing *c)
|
||||
{
|
||||
bool isAck =
|
||||
((c && c->error_reason == meshtastic_Routing_Error_NONE)); // consider only ROUTING_APP message without error as ACK
|
||||
if (isAck && p->to != getNodeNum()) {
|
||||
// do not flood direct message that is ACKed
|
||||
LOG_DEBUG("Receiving an ACK not for me, but don't need to rebroadcast this direct message anymore.\n");
|
||||
bool isAckorReply = (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) && (p->decoded.request_id != 0);
|
||||
if (isAckorReply && p->to != getNodeNum() && p->to != NODENUM_BROADCAST) {
|
||||
// do not flood direct message that is ACKed or replied to
|
||||
LOG_DEBUG("Receiving an ACK or reply not for me, but don't need to rebroadcast this direct message anymore.\n");
|
||||
Router::cancelSending(p->to, p->decoded.request_id); // cancel rebroadcast for this DM
|
||||
}
|
||||
if ((p->to != getNodeNum()) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum())) {
|
||||
|
||||
@@ -12,7 +12,7 @@ const meshtastic_MeshPacket *MeshModule::currentRequest;
|
||||
|
||||
/**
|
||||
* If any of the current chain of modules has already sent a reply, it will be here. This is useful to allow
|
||||
* the RoutingPlugin to avoid sending redundant acks
|
||||
* the RoutingModule to avoid sending redundant acks
|
||||
*/
|
||||
meshtastic_MeshPacket *MeshModule::currentReply;
|
||||
|
||||
@@ -40,7 +40,7 @@ meshtastic_MeshPacket *MeshModule::allocAckNak(meshtastic_Routing_Error err, Nod
|
||||
c.error_reason = err;
|
||||
c.which_variant = meshtastic_Routing_error_reason_tag;
|
||||
|
||||
// Now that we have moded sendAckNak up one level into the class hierarchy 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 RoutingModule
|
||||
// So we manually call pb_encode_to_bytes and specify routing port number
|
||||
// auto p = allocDataProtobuf(c);
|
||||
meshtastic_MeshPacket *p = router->allocForSending();
|
||||
@@ -54,7 +54,8 @@ meshtastic_MeshPacket *MeshModule::allocAckNak(meshtastic_Routing_Error err, Nod
|
||||
p->to = to;
|
||||
p->decoded.request_id = idFrom;
|
||||
p->channel = chIndex;
|
||||
LOG_ERROR("Alloc an err=%d,to=0x%x,idFrom=0x%x,id=0x%x\n", err, to, idFrom, p->id);
|
||||
if (err != meshtastic_Routing_Error_NONE)
|
||||
LOG_ERROR("Alloc an err=%d,to=0x%x,idFrom=0x%x,id=0x%x\n", err, to, idFrom, p->id);
|
||||
|
||||
return p;
|
||||
}
|
||||
@@ -68,7 +69,7 @@ meshtastic_MeshPacket *MeshModule::allocErrorResponse(meshtastic_Routing_Error e
|
||||
return r;
|
||||
}
|
||||
|
||||
void MeshModule::callPlugins(meshtastic_MeshPacket &mp, RxSource src)
|
||||
void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src)
|
||||
{
|
||||
// LOG_DEBUG("In call modules\n");
|
||||
bool moduleFound = false;
|
||||
@@ -258,7 +259,7 @@ void MeshModule::observeUIEvents(Observer<const UIFrameEvent *> *observer)
|
||||
}
|
||||
}
|
||||
|
||||
AdminMessageHandleResult MeshModule::handleAdminMessageForAllPlugins(const meshtastic_MeshPacket &mp,
|
||||
AdminMessageHandleResult MeshModule::handleAdminMessageForAllModules(const meshtastic_MeshPacket &mp,
|
||||
meshtastic_AdminMessage *request,
|
||||
meshtastic_AdminMessage *response)
|
||||
{
|
||||
|
||||
@@ -64,11 +64,11 @@ class MeshModule
|
||||
|
||||
/** For use only by MeshService
|
||||
*/
|
||||
static void callPlugins(meshtastic_MeshPacket &mp, RxSource src = RX_SRC_RADIO);
|
||||
static void callModules(meshtastic_MeshPacket &mp, RxSource src = RX_SRC_RADIO);
|
||||
|
||||
static std::vector<MeshModule *> GetMeshModulesWithUIFrames();
|
||||
static void observeUIEvents(Observer<const UIFrameEvent *> *observer);
|
||||
static AdminMessageHandleResult handleAdminMessageForAllPlugins(const meshtastic_MeshPacket &mp,
|
||||
static AdminMessageHandleResult handleAdminMessageForAllModules(const meshtastic_MeshPacket &mp,
|
||||
meshtastic_AdminMessage *request,
|
||||
meshtastic_AdminMessage *response);
|
||||
#if HAS_SCREEN
|
||||
@@ -195,4 +195,4 @@ class MeshModule
|
||||
/** set the destination and packet parameters of packet p intended as a reply to a particular "to" packet
|
||||
* This ensures that if the request packet was sent reliably, the reply is sent that way as well.
|
||||
*/
|
||||
void setReplyTo(meshtastic_MeshPacket *p, const meshtastic_MeshPacket &to);
|
||||
void setReplyTo(meshtastic_MeshPacket *p, const meshtastic_MeshPacket &to);
|
||||
@@ -192,12 +192,7 @@ void MeshService::handleToRadio(meshtastic_MeshPacket &p)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (p.from != 0) { // We don't let phones assign nodenums to their sent messages
|
||||
LOG_WARN("phone tried to pick a nodenum, we don't allow that.\n");
|
||||
p.from = 0;
|
||||
} else {
|
||||
// p.from = nodeDB->getNodeNum();
|
||||
}
|
||||
p.from = 0; // We don't let phones assign nodenums to their sent messages
|
||||
|
||||
if (p.id == 0)
|
||||
p.id = generatePacketId(); // If the phone didn't supply one, then pick one
|
||||
@@ -262,12 +257,12 @@ void MeshService::sendToMesh(meshtastic_MeshPacket *p, RxSource src, bool ccToPh
|
||||
LOG_DEBUG("Can't send status to phone");
|
||||
}
|
||||
|
||||
if (ccToPhone) {
|
||||
if (res == ERRNO_OK && ccToPhone) { // Check if p is not released in case it couldn't be sent
|
||||
sendToPhone(packetPool.allocCopy(*p));
|
||||
}
|
||||
}
|
||||
|
||||
void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
|
||||
bool MeshService::trySendPosition(NodeNum dest, bool wantReplies)
|
||||
{
|
||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
||||
|
||||
@@ -278,6 +273,7 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
|
||||
if (positionModule) {
|
||||
LOG_INFO("Sending position ping to 0x%x, wantReplies=%d, channel=%d\n", dest, wantReplies, node->channel);
|
||||
positionModule->sendOurPosition(dest, wantReplies, node->channel);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
@@ -286,6 +282,7 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
|
||||
nodeInfoModule->sendOurNodeInfo(dest, wantReplies, node->channel);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MeshService::sendToPhone(meshtastic_MeshPacket *p)
|
||||
|
||||
@@ -108,8 +108,9 @@ class MeshService
|
||||
void reloadOwner(bool shouldSave = true);
|
||||
|
||||
/// Called when the user wakes up our GUI, normally sends our latest location to the mesh (if we have it), otherwise at least
|
||||
/// sends our owner
|
||||
void sendNetworkPing(NodeNum dest, bool wantReplies = false);
|
||||
/// sends our nodeinfo
|
||||
/// returns true if we sent a position
|
||||
bool trySendPosition(NodeNum dest, bool wantReplies = false);
|
||||
|
||||
/// Send a packet into the mesh - note p must have been allocated from packetPool. We will return it to that pool after
|
||||
/// sending. This is the ONLY function you should use for sending messages into the mesh, because it also updates the nodedb
|
||||
|
||||
@@ -56,7 +56,7 @@ meshtastic_OEMStore oemStore;
|
||||
bool meshtastic_DeviceState_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field)
|
||||
{
|
||||
if (ostream) {
|
||||
std::vector<meshtastic_NodeInfoLite> *vec = (std::vector<meshtastic_NodeInfoLite> *)field->pData;
|
||||
std::vector<meshtastic_NodeInfoLite> const *vec = (std::vector<meshtastic_NodeInfoLite> *)field->pData;
|
||||
for (auto item : *vec) {
|
||||
if (!pb_encode_tag_for_field(ostream, field))
|
||||
return false;
|
||||
@@ -269,7 +269,7 @@ void NodeDB::installDefaultConfig()
|
||||
config.device.node_info_broadcast_secs = default_node_info_broadcast_secs;
|
||||
config.device.serial_enabled = true;
|
||||
resetRadioConfig();
|
||||
strncpy(config.network.ntp_server, "0.pool.ntp.org", 32);
|
||||
strncpy(config.network.ntp_server, "meshtastic.pool.ntp.org", 32);
|
||||
// FIXME: Default to bluetooth capability of platform as default
|
||||
config.bluetooth.enabled = true;
|
||||
config.bluetooth.fixed_pin = defaultBLEPin;
|
||||
@@ -311,6 +311,12 @@ void NodeDB::initConfigIntervals()
|
||||
config.power.wait_bluetooth_secs = default_wait_bluetooth_secs;
|
||||
|
||||
config.display.screen_on_secs = default_screen_on_secs;
|
||||
|
||||
#if defined(T_WATCH_S3) || defined(T_DECK)
|
||||
config.power.is_power_saving = true;
|
||||
config.display.screen_on_secs = 30;
|
||||
config.power.wait_bluetooth_secs = 30;
|
||||
#endif
|
||||
}
|
||||
|
||||
void NodeDB::installDefaultModuleConfig()
|
||||
@@ -443,7 +449,7 @@ void NodeDB::resetNodes()
|
||||
neighborInfoModule->resetNeighbors();
|
||||
}
|
||||
|
||||
void NodeDB::removeNodeByNum(uint nodeNum)
|
||||
void NodeDB::removeNodeByNum(NodeNum nodeNum)
|
||||
{
|
||||
int newPos = 0, removed = 0;
|
||||
for (int i = 0; i < numMeshNodes; i++) {
|
||||
@@ -517,11 +523,12 @@ void NodeDB::installDefaultDeviceState()
|
||||
*/
|
||||
void NodeDB::pickNewNodeNum()
|
||||
{
|
||||
|
||||
NodeNum nodeNum = myNodeInfo.my_node_num;
|
||||
getMacAddr(ourMacAddr); // Make sure ourMacAddr is set
|
||||
|
||||
// Pick an initial nodenum based on the macaddr
|
||||
NodeNum nodeNum = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5];
|
||||
if (nodeNum == 0) {
|
||||
// Pick an initial nodenum based on the macaddr
|
||||
nodeNum = (ourMacAddr[2] << 24) | (ourMacAddr[3] << 16) | (ourMacAddr[4] << 8) | ourMacAddr[5];
|
||||
}
|
||||
|
||||
meshtastic_NodeInfoLite *found;
|
||||
while ((nodeNum == NODENUM_BROADCAST || nodeNum < NUM_RESERVED) ||
|
||||
@@ -541,12 +548,17 @@ static const char *moduleConfigFileName = "/prefs/module.proto";
|
||||
static const char *channelFileName = "/prefs/channels.proto";
|
||||
static const char *oemConfigFile = "/oem/oem.proto";
|
||||
|
||||
/** Load a protobuf from a file, return true for success */
|
||||
bool NodeDB::loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct)
|
||||
/** Load a protobuf from a file, return LoadFileResult */
|
||||
LoadFileResult NodeDB::loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields,
|
||||
void *dest_struct)
|
||||
{
|
||||
bool okay = false;
|
||||
LoadFileResult state = LoadFileResult::OTHER_FAILURE;
|
||||
#ifdef FSCom
|
||||
// static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM
|
||||
|
||||
if (!FSCom.exists(filename)) {
|
||||
LOG_INFO("File %s not found\n", filename);
|
||||
return LoadFileResult::NOT_FOUND;
|
||||
}
|
||||
|
||||
auto f = FSCom.open(filename, FILE_O_READ);
|
||||
|
||||
@@ -554,30 +566,32 @@ bool NodeDB::loadProto(const char *filename, size_t protoSize, size_t objSize, c
|
||||
LOG_INFO("Loading %s\n", filename);
|
||||
pb_istream_t stream = {&readcb, &f, protoSize};
|
||||
|
||||
// LOG_DEBUG("Preload channel name=%s\n", channelSettings.name);
|
||||
|
||||
memset(dest_struct, 0, objSize);
|
||||
if (!pb_decode(&stream, fields, dest_struct)) {
|
||||
LOG_ERROR("Error: can't decode protobuf %s\n", PB_GET_ERROR(&stream));
|
||||
state = LoadFileResult::DECODE_FAILED;
|
||||
} else {
|
||||
okay = true;
|
||||
LOG_INFO("Loaded %s successfully\n", filename);
|
||||
state = LoadFileResult::SUCCESS;
|
||||
}
|
||||
|
||||
f.close();
|
||||
} else {
|
||||
LOG_INFO("No %s preferences found\n", filename);
|
||||
LOG_ERROR("Could not open / read %s\n", filename);
|
||||
}
|
||||
#else
|
||||
LOG_ERROR("ERROR: Filesystem not implemented\n");
|
||||
state = LoadFileState::NO_FILESYSTEM;
|
||||
#endif
|
||||
return okay;
|
||||
return state;
|
||||
}
|
||||
|
||||
void NodeDB::loadFromDisk()
|
||||
{
|
||||
// static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM
|
||||
if (!loadProto(prefFileName, sizeof(meshtastic_DeviceState) + MAX_NUM_NODES * sizeof(meshtastic_NodeInfo),
|
||||
sizeof(meshtastic_DeviceState), &meshtastic_DeviceState_msg, &devicestate)) {
|
||||
auto state = loadProto(prefFileName, sizeof(meshtastic_DeviceState) + MAX_NUM_NODES * sizeof(meshtastic_NodeInfo),
|
||||
sizeof(meshtastic_DeviceState), &meshtastic_DeviceState_msg, &devicestate);
|
||||
|
||||
if (state != LoadFileResult::SUCCESS) {
|
||||
installDefaultDeviceState(); // Our in RAM copy might now be corrupt
|
||||
} else {
|
||||
if (devicestate.version < DEVICESTATE_MIN_VER) {
|
||||
@@ -592,8 +606,9 @@ void NodeDB::loadFromDisk()
|
||||
}
|
||||
meshNodes->resize(MAX_NUM_NODES);
|
||||
|
||||
if (!loadProto(configFileName, meshtastic_LocalConfig_size, sizeof(meshtastic_LocalConfig), &meshtastic_LocalConfig_msg,
|
||||
&config)) {
|
||||
state = loadProto(configFileName, meshtastic_LocalConfig_size, sizeof(meshtastic_LocalConfig), &meshtastic_LocalConfig_msg,
|
||||
&config);
|
||||
if (state != LoadFileResult::SUCCESS) {
|
||||
installDefaultConfig(); // Our in RAM copy might now be corrupt
|
||||
} else {
|
||||
if (config.version < DEVICESTATE_MIN_VER) {
|
||||
@@ -604,8 +619,9 @@ void NodeDB::loadFromDisk()
|
||||
}
|
||||
}
|
||||
|
||||
if (!loadProto(moduleConfigFileName, meshtastic_LocalModuleConfig_size, sizeof(meshtastic_LocalModuleConfig),
|
||||
&meshtastic_LocalModuleConfig_msg, &moduleConfig)) {
|
||||
state = loadProto(moduleConfigFileName, meshtastic_LocalModuleConfig_size, sizeof(meshtastic_LocalModuleConfig),
|
||||
&meshtastic_LocalModuleConfig_msg, &moduleConfig);
|
||||
if (state != LoadFileResult::SUCCESS) {
|
||||
installDefaultModuleConfig(); // Our in RAM copy might now be corrupt
|
||||
} else {
|
||||
if (moduleConfig.version < DEVICESTATE_MIN_VER) {
|
||||
@@ -616,8 +632,9 @@ void NodeDB::loadFromDisk()
|
||||
}
|
||||
}
|
||||
|
||||
if (!loadProto(channelFileName, meshtastic_ChannelFile_size, sizeof(meshtastic_ChannelFile), &meshtastic_ChannelFile_msg,
|
||||
&channelFile)) {
|
||||
state = loadProto(channelFileName, meshtastic_ChannelFile_size, sizeof(meshtastic_ChannelFile), &meshtastic_ChannelFile_msg,
|
||||
&channelFile);
|
||||
if (state != LoadFileResult::SUCCESS) {
|
||||
installDefaultChannels(); // Our in RAM copy might now be corrupt
|
||||
} else {
|
||||
if (channelFile.version < DEVICESTATE_MIN_VER) {
|
||||
@@ -628,7 +645,8 @@ void NodeDB::loadFromDisk()
|
||||
}
|
||||
}
|
||||
|
||||
if (loadProto(oemConfigFile, meshtastic_OEMStore_size, sizeof(meshtastic_OEMStore), &meshtastic_OEMStore_msg, &oemStore)) {
|
||||
state = loadProto(oemConfigFile, meshtastic_OEMStore_size, sizeof(meshtastic_OEMStore), &meshtastic_OEMStore_msg, &oemStore);
|
||||
if (state == LoadFileResult::SUCCESS) {
|
||||
LOG_INFO("Loaded OEMStore\n");
|
||||
}
|
||||
}
|
||||
@@ -667,9 +685,13 @@ bool NodeDB::saveProto(const char *filename, size_t protoSize, const pb_msgdesc_
|
||||
static uint8_t failedCounter = 0;
|
||||
failedCounter++;
|
||||
if (failedCounter >= 2) {
|
||||
FSCom.format();
|
||||
// After formatting, the device needs to be restarted
|
||||
nodeDB->resetRadioConfig(true);
|
||||
LOG_ERROR("Failed to save file twice. Rebooting...\n");
|
||||
delay(100);
|
||||
NVIC_SystemReset();
|
||||
// We used to blow away the filesystem here, but that's a bit extreme
|
||||
// FSCom.format();
|
||||
// // After formatting, the device needs to be restarted
|
||||
// nodeDB->resetRadioConfig(true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -713,6 +735,7 @@ void NodeDB::saveToDisk(int saveWhat)
|
||||
config.has_power = true;
|
||||
config.has_network = true;
|
||||
config.has_bluetooth = true;
|
||||
|
||||
saveProto(configFileName, meshtastic_LocalConfig_size, &meshtastic_LocalConfig_msg, &config);
|
||||
}
|
||||
|
||||
@@ -724,6 +747,12 @@ void NodeDB::saveToDisk(int saveWhat)
|
||||
moduleConfig.has_serial = true;
|
||||
moduleConfig.has_store_forward = true;
|
||||
moduleConfig.has_telemetry = true;
|
||||
moduleConfig.has_neighbor_info = true;
|
||||
moduleConfig.has_detection_sensor = true;
|
||||
moduleConfig.has_ambient_lighting = true;
|
||||
moduleConfig.has_audio = true;
|
||||
moduleConfig.has_paxcounter = true;
|
||||
|
||||
saveProto(moduleConfigFileName, meshtastic_LocalModuleConfig_size, &meshtastic_LocalModuleConfig_msg, &moduleConfig);
|
||||
}
|
||||
|
||||
@@ -781,6 +810,7 @@ size_t NodeDB::getNumOnlineMeshNodes(bool localOnly)
|
||||
}
|
||||
|
||||
#include "MeshModule.h"
|
||||
#include "Throttle.h"
|
||||
|
||||
/** Update position info for this node based on received position data
|
||||
*/
|
||||
@@ -875,8 +905,10 @@ bool NodeDB::updateUser(uint32_t nodeId, const meshtastic_User &p, uint8_t chann
|
||||
powerFSM.trigger(EVENT_NODEDB_UPDATED);
|
||||
notifyObservers(true); // Force an update whether or not our node counts have changed
|
||||
|
||||
// We just changed something important about the user, store our DB
|
||||
saveToDisk(SEGMENT_DEVICESTATE);
|
||||
// We just changed something about the user, store our DB
|
||||
Throttle::execute(
|
||||
&lastNodeDbSave, ONE_MINUTE_MS, []() { nodeDB->saveToDisk(SEGMENT_DEVICESTATE); },
|
||||
[]() { LOG_DEBUG("Deferring NodeDB saveToDisk for now, since we saved less than a minute ago\n"); });
|
||||
}
|
||||
|
||||
return changed;
|
||||
|
||||
@@ -38,6 +38,19 @@ uint32_t sinceLastSeen(const meshtastic_NodeInfoLite *n);
|
||||
/// Given a packet, return how many seconds in the past (vs now) it was received
|
||||
uint32_t sinceReceived(const meshtastic_MeshPacket *p);
|
||||
|
||||
enum LoadFileResult {
|
||||
// Successfully opened the file
|
||||
SUCCESS = 1,
|
||||
// File does not exist
|
||||
NOT_FOUND = 2,
|
||||
// Device does not have a filesystem
|
||||
NO_FILESYSTEM = 3,
|
||||
// File exists, but could not decode protobufs
|
||||
DECODE_FAILED = 4,
|
||||
// File exists, but open failed for some reason
|
||||
OTHER_FAILURE = 5
|
||||
};
|
||||
|
||||
class NodeDB
|
||||
{
|
||||
// NodeNum provisionalNodeNum; // if we are trying to find a node num this is our current attempt
|
||||
@@ -111,11 +124,12 @@ class NodeDB
|
||||
*/
|
||||
size_t getNumOnlineMeshNodes(bool localOnly = false);
|
||||
|
||||
void initConfigIntervals(), initModuleConfigIntervals(), resetNodes(), removeNodeByNum(uint nodeNum);
|
||||
void initConfigIntervals(), initModuleConfigIntervals(), resetNodes(), removeNodeByNum(NodeNum nodeNum);
|
||||
|
||||
bool factoryReset();
|
||||
|
||||
bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct);
|
||||
LoadFileResult loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields,
|
||||
void *dest_struct);
|
||||
bool saveProto(const char *filename, size_t protoSize, const pb_msgdesc_t *fields, const void *dest_struct);
|
||||
|
||||
void installRoleDefaults(meshtastic_Config_DeviceConfig_Role role);
|
||||
@@ -136,16 +150,18 @@ class NodeDB
|
||||
void setLocalPosition(meshtastic_Position position, bool timeOnly = false)
|
||||
{
|
||||
if (timeOnly) {
|
||||
LOG_DEBUG("Setting local position time only: time=%i\n", position.time);
|
||||
LOG_DEBUG("Setting local position time only: time=%u timestamp=%u\n", position.time, position.timestamp);
|
||||
localPosition.time = position.time;
|
||||
localPosition.timestamp = position.timestamp > 0 ? position.timestamp : position.time;
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Setting local position: latitude=%i, longitude=%i, time=%i\n", position.latitude_i, position.longitude_i,
|
||||
position.time);
|
||||
LOG_DEBUG("Setting local position: latitude=%i, longitude=%i, time=%u, timestamp=%u\n", position.latitude_i,
|
||||
position.longitude_i, position.time, position.timestamp);
|
||||
localPosition = position;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t lastNodeDbSave = 0; // when we last saved our db to flash
|
||||
/// Find a node in our DB, create an empty NodeInfoLite if missing
|
||||
meshtastic_NodeInfoLite *getOrCreateMeshNode(NodeNum n);
|
||||
|
||||
@@ -215,4 +231,4 @@ extern uint32_t error_address;
|
||||
ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + \
|
||||
ModuleConfig_TelemetryConfig_size + ModuleConfig_size)
|
||||
|
||||
// Please do not remove this comment, it makes trunk and compiler happy at the same time.
|
||||
// Please do not remove this comment, it makes trunk and compiler happy at the same time.
|
||||
@@ -430,6 +430,9 @@ bool PhoneAPI::available()
|
||||
auto nextNode = nodeDB->readNextMeshNode(readIndex);
|
||||
if (nextNode) {
|
||||
nodeInfoForPhone = TypeConversions::ConvertToNodeInfo(nextNode);
|
||||
nodeInfoForPhone.hops_away = nodeInfoForPhone.num == nodeDB->getNodeNum() ? 0 : nodeInfoForPhone.hops_away;
|
||||
nodeInfoForPhone.is_favorite =
|
||||
nodeInfoForPhone.is_favorite || nodeInfoForPhone.num == nodeDB->getNodeNum(); // Our node is always a favorite
|
||||
}
|
||||
}
|
||||
return true; // Always say we have something, because we might need to advance our state machine
|
||||
|
||||
@@ -95,12 +95,11 @@ template <class T> class ProtobufModule : protected SinglePortModule
|
||||
*/
|
||||
virtual void alterReceived(meshtastic_MeshPacket &mp) override
|
||||
{
|
||||
auto &p = mp.decoded;
|
||||
|
||||
T scratch;
|
||||
T *decoded = NULL;
|
||||
if (mp.which_payload_variant == meshtastic_MeshPacket_decoded_tag && mp.decoded.portnum == ourPortNum) {
|
||||
memset(&scratch, 0, sizeof(scratch));
|
||||
auto &p = mp.decoded;
|
||||
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch)) {
|
||||
decoded = &scratch;
|
||||
} else {
|
||||
|
||||
@@ -128,12 +128,18 @@ bool RF95Interface::reconfigure()
|
||||
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
err = lora->setSyncWord(syncWord);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
LOG_ERROR("Radiolib error %d when attempting RF95 setSyncWord!\n", err);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
err = lora->setCurrentLimit(currentLimit);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
LOG_ERROR("Radiolib error %d when attempting RF95 setCurrentLimit!\n", err);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
err = lora->setPreambleLength(preambleLength);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
LOG_ERROR("Radiolib error %d when attempting RF95 setPreambleLength!\n", err);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
err = lora->setFrequency(getFreq());
|
||||
@@ -164,6 +170,8 @@ void RF95Interface::addReceiveMetadata(meshtastic_MeshPacket *mp)
|
||||
void RF95Interface::setStandby()
|
||||
{
|
||||
int err = lora->standby();
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
LOG_ERROR("Radiolib error %d when attempting RF95 standby!\n", err);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
isReceiving = false; // If we were receiving, not any more
|
||||
@@ -185,6 +193,8 @@ void RF95Interface::startReceive()
|
||||
setTransmitEnable(false);
|
||||
setStandby();
|
||||
int err = lora->startReceive();
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
LOG_ERROR("Radiolib error %d when attempting RF95 startReceive!\n", err);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
isReceiving = true;
|
||||
@@ -205,6 +215,8 @@ bool RF95Interface::isChannelActive()
|
||||
// LOG_DEBUG("Channel is busy!\n");
|
||||
return true;
|
||||
}
|
||||
if (result != RADIOLIB_CHANNEL_FREE)
|
||||
LOG_ERROR("Radiolib error %d when attempting RF95 isChannelActive!\n", result);
|
||||
assert(result != RADIOLIB_ERR_WRONG_MODEM);
|
||||
|
||||
// LOG_DEBUG("Channel is free!\n");
|
||||
|
||||
@@ -76,9 +76,12 @@ const RegionInfo regions[] = {
|
||||
RDEF(KR, 920.0f, 923.0f, 100, 0, 0, true, false, false),
|
||||
|
||||
/*
|
||||
???
|
||||
Taiwan, 920-925Mhz, limited to 0.5W indoor or coastal, 1.0W outdoor.
|
||||
5.8.1 in the Low-power Radio-frequency Devices Technical Regulations
|
||||
https://www.ncc.gov.tw/english/files/23070/102_5190_230703_1_doc_C.PDF
|
||||
https://gazette.nat.gov.tw/egFront/e_detail.do?metaid=147283
|
||||
*/
|
||||
RDEF(TW, 920.0f, 925.0f, 100, 0, 0, true, false, false),
|
||||
RDEF(TW, 920.0f, 925.0f, 100, 0, 27, true, false, false),
|
||||
|
||||
/*
|
||||
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
|
||||
@@ -151,10 +154,16 @@ static uint8_t bytes[MAX_RHPACKETLEN];
|
||||
void initRegion()
|
||||
{
|
||||
const RegionInfo *r = regions;
|
||||
#ifdef LORA_REGIONCODE
|
||||
for (; r->code != meshtastic_Config_LoRaConfig_RegionCode_UNSET && r->code != LORA_REGIONCODE; r++)
|
||||
;
|
||||
LOG_INFO("Wanted region %d, regulatory override to %s\n", config.lora.region, r->name);
|
||||
#else
|
||||
for (; r->code != meshtastic_Config_LoRaConfig_RegionCode_UNSET && r->code != config.lora.region; r++)
|
||||
;
|
||||
myRegion = r;
|
||||
LOG_INFO("Wanted region %d, using %s\n", config.lora.region, r->name);
|
||||
#endif
|
||||
myRegion = r;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -486,7 +495,7 @@ void RadioInterface::applyModemConfig()
|
||||
// If user has manually specified a channel num, then use that, otherwise generate one by hashing the name
|
||||
const char *channelName = channels.getName(channels.getPrimaryIndex());
|
||||
// channel_num is actually (channel_num - 1), since modulus (%) returns values from 0 to (numChannels - 1)
|
||||
int channel_num = (loraConfig.channel_num ? loraConfig.channel_num - 1 : hash(channelName)) % numChannels;
|
||||
uint32_t channel_num = (loraConfig.channel_num ? loraConfig.channel_num - 1 : hash(channelName)) % numChannels;
|
||||
|
||||
// Check if we use the default frequency slot
|
||||
RadioInterface::uses_default_frequency_slot =
|
||||
@@ -580,4 +589,4 @@ size_t RadioInterface::beginSending(meshtastic_MeshPacket *p)
|
||||
|
||||
sendingPacket = p;
|
||||
return p->encrypted.size + sizeof(PacketHeader);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,31 @@ void LockingArduinoHal::spiEndTransaction()
|
||||
#if ARCH_PORTDUINO
|
||||
void LockingArduinoHal::spiTransfer(uint8_t *out, size_t len, uint8_t *in)
|
||||
{
|
||||
spi->transfer(out, in, len);
|
||||
if (busy == RADIOLIB_NC) {
|
||||
spi->transfer(out, in, len);
|
||||
} else {
|
||||
uint16_t offset = 0;
|
||||
|
||||
while (len) {
|
||||
uint8_t block_size = (len < 20 ? len : 20);
|
||||
spi->transfer((out != NULL ? out + offset : NULL), (in != NULL ? in + offset : NULL), block_size);
|
||||
if (block_size == len)
|
||||
return;
|
||||
|
||||
// ensure GPIO is low
|
||||
|
||||
uint32_t start = millis();
|
||||
while (digitalRead(busy)) {
|
||||
if (millis() - start >= 2000) {
|
||||
LOG_ERROR("GPIO mid-transfer timeout, is it connected?");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
offset += block_size;
|
||||
len -= block_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -319,7 +343,7 @@ void RadioLibInterface::handleReceiveInterrupt()
|
||||
// when this is called, we should be in receive mode - if we are not, just jump out instead of bombing. Possible Race
|
||||
// Condition?
|
||||
if (!isReceiving) {
|
||||
LOG_DEBUG("*** WAS_ASSERT *** handleReceiveInterrupt called when not in receive mode\n");
|
||||
LOG_ERROR("handleReceiveInterrupt called when not in receive mode, which shouldn't happen.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,12 +21,20 @@
|
||||
class LockingArduinoHal : public ArduinoHal
|
||||
{
|
||||
public:
|
||||
LockingArduinoHal(SPIClass &spi, SPISettings spiSettings) : ArduinoHal(spi, spiSettings){};
|
||||
LockingArduinoHal(SPIClass &spi, SPISettings spiSettings, RADIOLIB_PIN_TYPE _busy = RADIOLIB_NC)
|
||||
: ArduinoHal(spi, spiSettings)
|
||||
{
|
||||
#if ARCH_PORTDUINO
|
||||
busy = _busy;
|
||||
#endif
|
||||
};
|
||||
|
||||
void spiBeginTransaction() override;
|
||||
void spiEndTransaction() override;
|
||||
#if ARCH_PORTDUINO
|
||||
RADIOLIB_PIN_TYPE busy;
|
||||
void spiTransfer(uint8_t *out, size_t len, uint8_t *in) override;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -179,4 +187,4 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
|
||||
virtual void addReceiveMetadata(meshtastic_MeshPacket *mp) = 0;
|
||||
|
||||
virtual void setStandby() = 0;
|
||||
};
|
||||
};
|
||||
@@ -8,9 +8,6 @@
|
||||
#include "main.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
#include "modules/RoutingModule.h"
|
||||
extern "C" {
|
||||
#include "mesh/compression/unishox2.h"
|
||||
}
|
||||
#if !MESHTASTIC_EXCLUDE_MQTT
|
||||
#include "mqtt/MQTT.h"
|
||||
#endif
|
||||
@@ -332,6 +329,7 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
|
||||
p->which_payload_variant = meshtastic_MeshPacket_decoded_tag; // change type to decoded
|
||||
p->channel = chIndex; // change to store the index instead of the hash
|
||||
|
||||
/* Not actually ever used.
|
||||
// Decompress if needed. jm
|
||||
if (p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_COMPRESSED_APP) {
|
||||
// Decompress the payload
|
||||
@@ -349,7 +347,7 @@ bool perhapsDecode(meshtastic_MeshPacket *p)
|
||||
|
||||
// Switch the port from PortNum_TEXT_MESSAGE_COMPRESSED_APP to PortNum_TEXT_MESSAGE_APP
|
||||
p->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_APP;
|
||||
}
|
||||
} */
|
||||
|
||||
printPacket("decoded message", p);
|
||||
return true;
|
||||
@@ -371,6 +369,7 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p)
|
||||
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
|
||||
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded);
|
||||
|
||||
/* Not actually used, so save the cycles
|
||||
// Only allow encryption on the text message app.
|
||||
// TODO: Allow modules to opt into compression.
|
||||
if (p->decoded.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP) {
|
||||
@@ -404,7 +403,7 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p)
|
||||
|
||||
p->decoded.portnum = meshtastic_PortNum_TEXT_MESSAGE_COMPRESSED_APP;
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
if (numbytes > MAX_RHPACKETLEN)
|
||||
return meshtastic_Routing_Error_TOO_LARGE;
|
||||
@@ -466,21 +465,22 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
|
||||
cancelSending(p->from, p->id);
|
||||
skipHandle = true;
|
||||
}
|
||||
#if !MESHTASTIC_EXCLUDE_MQTT
|
||||
// Publish received message to MQTT if we're not the original transmitter of the packet
|
||||
if (!skipHandle && moduleConfig.mqtt.enabled && getFrom(p) != nodeDB->getNodeNum() && mqtt)
|
||||
mqtt->onSend(*p_encrypted, *p, p->channel);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
printPacket("packet decoding failed or skipped (no PSK?)", p);
|
||||
}
|
||||
|
||||
packetPool.release(p_encrypted); // Release the encrypted packet
|
||||
|
||||
// call modules here
|
||||
if (!skipHandle)
|
||||
MeshModule::callPlugins(*p, src);
|
||||
if (!skipHandle) {
|
||||
MeshModule::callModules(*p, src);
|
||||
|
||||
#if !MESHTASTIC_EXCLUDE_MQTT
|
||||
// After potentially altering it, publish received message to MQTT if we're not the original transmitter of the packet
|
||||
if (decoded && moduleConfig.mqtt.enabled && getFrom(p) != nodeDB->getNodeNum() && mqtt)
|
||||
mqtt->onSend(*p_encrypted, *p, p->channel);
|
||||
#endif
|
||||
}
|
||||
|
||||
packetPool.release(p_encrypted); // Release the encrypted packet
|
||||
}
|
||||
|
||||
void Router::perhapsHandleReceived(meshtastic_MeshPacket *p)
|
||||
|
||||
@@ -181,12 +181,18 @@ template <typename T> bool SX126xInterface<T>::reconfigure()
|
||||
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
err = lora.setSyncWord(syncWord);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
LOG_ERROR("Radiolib error %d when attempting SX126X setSyncWord!\n", err);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
err = lora.setCurrentLimit(currentLimit);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
LOG_ERROR("Radiolib error %d when attempting SX126X setCurrentLimit!\n", err);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
err = lora.setPreambleLength(preambleLength);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
LOG_ERROR("Radiolib error %d when attempting SX126X setPreambleLength!\n", err);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
err = lora.setFrequency(getFreq());
|
||||
@@ -197,6 +203,8 @@ template <typename T> bool SX126xInterface<T>::reconfigure()
|
||||
power = SX126X_MAX_POWER;
|
||||
|
||||
err = lora.setOutputPower(power);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
LOG_ERROR("Radiolib error %d when attempting SX126X setOutputPower!\n", err);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
startReceive(); // restart receiving
|
||||
@@ -215,10 +223,8 @@ template <typename T> void SX126xInterface<T>::setStandby()
|
||||
|
||||
int err = lora.standby();
|
||||
|
||||
if (err != RADIOLIB_ERR_NONE) {
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
LOG_DEBUG("SX126x standby failed with error %d\n", err);
|
||||
}
|
||||
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
isReceiving = false; // If we were receiving, not any more
|
||||
@@ -260,6 +266,8 @@ template <typename T> void SX126xInterface<T>::startReceive()
|
||||
int err = lora.startReceiveDutyCycleAuto(preambleLength, 8,
|
||||
RADIOLIB_SX126X_IRQ_RX_DEFAULT | RADIOLIB_SX126X_IRQ_PREAMBLE_DETECTED |
|
||||
RADIOLIB_SX126X_IRQ_HEADER_VALID);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
LOG_ERROR("Radiolib error %d when attempting SX126X startReceiveDutyCycleAuto!\n", err);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
isReceiving = true;
|
||||
@@ -279,7 +287,8 @@ template <typename T> bool SX126xInterface<T>::isChannelActive()
|
||||
result = lora.scanChannel();
|
||||
if (result == RADIOLIB_LORA_DETECTED)
|
||||
return true;
|
||||
|
||||
if (result != RADIOLIB_CHANNEL_FREE)
|
||||
LOG_ERROR("Radiolib error %d when attempting SX126X scanChannel!\n", result);
|
||||
assert(result != RADIOLIB_ERR_WRONG_MODEM);
|
||||
|
||||
return false;
|
||||
|
||||
@@ -126,9 +126,13 @@ template <typename T> bool SX128xInterface<T>::reconfigure()
|
||||
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING);
|
||||
|
||||
err = lora.setSyncWord(syncWord);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
LOG_ERROR("Radiolib error %d when attempting SX128X setSyncWord!\n", err);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
err = lora.setPreambleLength(preambleLength);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
LOG_ERROR("Radiolib error %d when attempting SX128X setPreambleLength!\n", err);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
err = lora.setFrequency(getFreq());
|
||||
@@ -139,6 +143,8 @@ template <typename T> bool SX128xInterface<T>::reconfigure()
|
||||
power = SX128X_MAX_POWER;
|
||||
|
||||
err = lora.setOutputPower(power);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
LOG_ERROR("Radiolib error %d when attempting SX128X setOutputPower!\n", err);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
startReceive(); // restart receiving
|
||||
@@ -162,10 +168,8 @@ template <typename T> void SX128xInterface<T>::setStandby()
|
||||
|
||||
int err = lora.standby();
|
||||
|
||||
if (err != RADIOLIB_ERR_NONE) {
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
LOG_ERROR("SX128x standby failed with error %d\n", err);
|
||||
}
|
||||
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
#if ARCH_PORTDUINO
|
||||
if (settingsMap[rxen] != RADIOLIB_NC) {
|
||||
@@ -255,6 +259,8 @@ template <typename T> void SX128xInterface<T>::startReceive()
|
||||
lora.startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF, RADIOLIB_SX128X_IRQ_RX_DEFAULT | RADIOLIB_SX128X_IRQ_PREAMBLE_DETECTED |
|
||||
RADIOLIB_SX128X_IRQ_HEADER_VALID);
|
||||
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
LOG_ERROR("Radiolib error %d when attempting SX128X startReceive!\n", err);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
isReceiving = true;
|
||||
@@ -274,7 +280,8 @@ template <typename T> bool SX128xInterface<T>::isChannelActive()
|
||||
result = lora.scanChannel();
|
||||
if (result == RADIOLIB_LORA_DETECTED)
|
||||
return true;
|
||||
|
||||
if (result != RADIOLIB_CHANNEL_FREE)
|
||||
LOG_ERROR("Radiolib error %d when attempting SX128X scanChannel!\n", result);
|
||||
assert(result != RADIOLIB_ERR_WRONG_MODEM);
|
||||
|
||||
return false;
|
||||
|
||||
27
src/mesh/Throttle.cpp
Normal file
27
src/mesh/Throttle.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "Throttle.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
/// @brief Execute a function throttled to a minimum interval
|
||||
/// @param lastExecutionMs Pointer to the last execution time in milliseconds
|
||||
/// @param minumumIntervalMs Minimum execution interval in milliseconds
|
||||
/// @param throttleFunc Function to execute if the execution is not deferred
|
||||
/// @param onDefer Default to NULL, execute the function if the execution is deferred
|
||||
/// @return true if the function was executed, false if it was deferred
|
||||
bool Throttle::execute(uint32_t *lastExecutionMs, uint32_t minumumIntervalMs, void (*throttleFunc)(void), void (*onDefer)(void))
|
||||
{
|
||||
if (*lastExecutionMs == 0) {
|
||||
*lastExecutionMs = millis();
|
||||
throttleFunc();
|
||||
return true;
|
||||
}
|
||||
uint32_t now = millis();
|
||||
|
||||
if ((now - *lastExecutionMs) >= minumumIntervalMs) {
|
||||
throttleFunc();
|
||||
*lastExecutionMs = now;
|
||||
return true;
|
||||
} else if (onDefer != NULL) {
|
||||
onDefer();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
9
src/mesh/Throttle.h
Normal file
9
src/mesh/Throttle.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
class Throttle
|
||||
{
|
||||
public:
|
||||
static bool execute(uint32_t *lastExecutionMs, uint32_t minumumIntervalMs, void (*func)(void), void (*onDefer)(void) = NULL);
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#include "meshtastic/admin.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#ifndef PB_MESHTASTIC_MESHTASTIC_ADMIN_PB_H_INCLUDED
|
||||
#define PB_MESHTASTIC_MESHTASTIC_ADMIN_PB_H_INCLUDED
|
||||
@@ -340,6 +340,7 @@ extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePinsResponse_msg;
|
||||
#define meshtastic_NodeRemoteHardwarePinsResponse_fields &meshtastic_NodeRemoteHardwarePinsResponse_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define MESHTASTIC_MESHTASTIC_ADMIN_PB_H_MAX_SIZE meshtastic_AdminMessage_size
|
||||
#define meshtastic_AdminMessage_size 500
|
||||
#define meshtastic_HamParameters_size 32
|
||||
#define meshtastic_NodeRemoteHardwarePinsResponse_size 496
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#include "meshtastic/apponly.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#ifndef PB_MESHTASTIC_MESHTASTIC_APPONLY_PB_H_INCLUDED
|
||||
#define PB_MESHTASTIC_MESHTASTIC_APPONLY_PB_H_INCLUDED
|
||||
@@ -54,7 +54,8 @@ extern const pb_msgdesc_t meshtastic_ChannelSet_msg;
|
||||
#define meshtastic_ChannelSet_fields &meshtastic_ChannelSet_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define meshtastic_ChannelSet_size 658
|
||||
#define MESHTASTIC_MESHTASTIC_APPONLY_PB_H_MAX_SIZE meshtastic_ChannelSet_size
|
||||
#define meshtastic_ChannelSet_size 674
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#include "meshtastic/atak.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#ifndef PB_MESHTASTIC_MESHTASTIC_ATAK_PB_H_INCLUDED
|
||||
#define PB_MESHTASTIC_MESHTASTIC_ATAK_PB_H_INCLUDED
|
||||
@@ -260,6 +260,7 @@ extern const pb_msgdesc_t meshtastic_PLI_msg;
|
||||
#define meshtastic_PLI_fields &meshtastic_PLI_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define MESHTASTIC_MESHTASTIC_ATAK_PB_H_MAX_SIZE meshtastic_TAKPacket_size
|
||||
#define meshtastic_Contact_size 242
|
||||
#define meshtastic_GeoChat_size 323
|
||||
#define meshtastic_Group_size 4
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#include "meshtastic/cannedmessages.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#ifndef PB_MESHTASTIC_MESHTASTIC_CANNEDMESSAGES_PB_H_INCLUDED
|
||||
#define PB_MESHTASTIC_MESHTASTIC_CANNEDMESSAGES_PB_H_INCLUDED
|
||||
@@ -40,6 +40,7 @@ extern const pb_msgdesc_t meshtastic_CannedMessageModuleConfig_msg;
|
||||
#define meshtastic_CannedMessageModuleConfig_fields &meshtastic_CannedMessageModuleConfig_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define MESHTASTIC_MESHTASTIC_CANNEDMESSAGES_PB_H_MAX_SIZE meshtastic_CannedMessageModuleConfig_size
|
||||
#define meshtastic_CannedMessageModuleConfig_size 203
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#include "meshtastic/channel.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#ifndef PB_MESHTASTIC_MESHTASTIC_CHANNEL_PB_H_INCLUDED
|
||||
#define PB_MESHTASTIC_MESHTASTIC_CHANNEL_PB_H_INCLUDED
|
||||
@@ -34,6 +34,9 @@ typedef enum _meshtastic_Channel_Role {
|
||||
typedef struct _meshtastic_ModuleSettings {
|
||||
/* Bits of precision for the location sent in position packets. */
|
||||
uint32_t position_precision;
|
||||
/* Controls whether or not the phone / clients should mute the current channel
|
||||
Useful for noisy public channels you don't necessarily want to disable */
|
||||
bool is_client_muted;
|
||||
} meshtastic_ModuleSettings;
|
||||
|
||||
typedef PB_BYTES_ARRAY_T(32) meshtastic_ChannelSettings_psk_t;
|
||||
@@ -126,14 +129,15 @@ extern "C" {
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define meshtastic_ChannelSettings_init_default {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_default}
|
||||
#define meshtastic_ModuleSettings_init_default {0}
|
||||
#define meshtastic_ModuleSettings_init_default {0, 0}
|
||||
#define meshtastic_Channel_init_default {0, false, meshtastic_ChannelSettings_init_default, _meshtastic_Channel_Role_MIN}
|
||||
#define meshtastic_ChannelSettings_init_zero {0, {0, {0}}, "", 0, 0, 0, false, meshtastic_ModuleSettings_init_zero}
|
||||
#define meshtastic_ModuleSettings_init_zero {0}
|
||||
#define meshtastic_ModuleSettings_init_zero {0, 0}
|
||||
#define meshtastic_Channel_init_zero {0, false, meshtastic_ChannelSettings_init_zero, _meshtastic_Channel_Role_MIN}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define meshtastic_ModuleSettings_position_precision_tag 1
|
||||
#define meshtastic_ModuleSettings_is_client_muted_tag 2
|
||||
#define meshtastic_ChannelSettings_channel_num_tag 1
|
||||
#define meshtastic_ChannelSettings_psk_tag 2
|
||||
#define meshtastic_ChannelSettings_name_tag 3
|
||||
@@ -159,7 +163,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, module_settings, 7)
|
||||
#define meshtastic_ChannelSettings_module_settings_MSGTYPE meshtastic_ModuleSettings
|
||||
|
||||
#define meshtastic_ModuleSettings_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, position_precision, 1)
|
||||
X(a, STATIC, SINGULAR, UINT32, position_precision, 1) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_client_muted, 2)
|
||||
#define meshtastic_ModuleSettings_CALLBACK NULL
|
||||
#define meshtastic_ModuleSettings_DEFAULT NULL
|
||||
|
||||
@@ -181,9 +186,10 @@ extern const pb_msgdesc_t meshtastic_Channel_msg;
|
||||
#define meshtastic_Channel_fields &meshtastic_Channel_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define meshtastic_ChannelSettings_size 70
|
||||
#define meshtastic_Channel_size 85
|
||||
#define meshtastic_ModuleSettings_size 6
|
||||
#define MESHTASTIC_MESHTASTIC_CHANNEL_PB_H_MAX_SIZE meshtastic_Channel_size
|
||||
#define meshtastic_ChannelSettings_size 72
|
||||
#define meshtastic_Channel_size 87
|
||||
#define meshtastic_ModuleSettings_size 8
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#include "meshtastic/clientonly.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#ifndef PB_MESHTASTIC_MESHTASTIC_CLIENTONLY_PB_H_INCLUDED
|
||||
#define PB_MESHTASTIC_MESHTASTIC_CLIENTONLY_PB_H_INCLUDED
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#include "meshtastic/config.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#ifndef PB_MESHTASTIC_MESHTASTIC_CONFIG_PB_H_INCLUDED
|
||||
#define PB_MESHTASTIC_MESHTASTIC_CONFIG_PB_H_INCLUDED
|
||||
@@ -283,6 +283,8 @@ typedef struct _meshtastic_Config_DeviceConfig {
|
||||
bool disable_triple_click;
|
||||
/* POSIX Timezone definition string from https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv. */
|
||||
char tzdef[65];
|
||||
/* If true, disable the default blinking LED (LED_PIN) behavior on the device */
|
||||
bool led_heartbeat_disabled;
|
||||
} meshtastic_Config_DeviceConfig;
|
||||
|
||||
/* Position Config */
|
||||
@@ -324,35 +326,30 @@ typedef struct _meshtastic_Config_PositionConfig {
|
||||
/* Power Config\
|
||||
See [Power Config](/docs/settings/config/power) for additional power config details. */
|
||||
typedef struct _meshtastic_Config_PowerConfig {
|
||||
/* If set, we are powered from a low-current source (i.e. solar), so even if it looks like we have power flowing in
|
||||
we should try to minimize power consumption as much as possible.
|
||||
YOU DO NOT NEED TO SET THIS IF YOU'VE set is_router (it is implied in that case).
|
||||
Advanced Option */
|
||||
/* Description: Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio.
|
||||
Don't use this setting if you want to use your device with the phone apps or are using a device without a user button.
|
||||
Technical Details: Works for ESP32 devices and NRF52 devices in the Sensor or Tracker roles */
|
||||
bool is_power_saving;
|
||||
/* If non-zero, the device will fully power off this many seconds after external power is removed. */
|
||||
/* Description: If non-zero, the device will fully power off this many seconds after external power is removed. */
|
||||
uint32_t on_battery_shutdown_after_secs;
|
||||
/* Ratio of voltage divider for battery pin eg. 3.20 (R1=100k, R2=220k)
|
||||
Overrides the ADC_MULTIPLIER defined in variant for battery voltage calculation.
|
||||
Should be set to floating point value between 2 and 4
|
||||
Fixes issues on Heltec v2 */
|
||||
https://meshtastic.org/docs/configuration/radio/power/#adc-multiplier-override
|
||||
Should be set to floating point value between 2 and 6 */
|
||||
float adc_multiplier_override;
|
||||
/* Wait Bluetooth Seconds
|
||||
The number of seconds for to wait before turning off BLE in No Bluetooth states
|
||||
0 for default of 1 minute */
|
||||
/* Description: The number of seconds for to wait before turning off BLE in No Bluetooth states
|
||||
Technical Details: ESP32 Only 0 for default of 1 minute */
|
||||
uint32_t wait_bluetooth_secs;
|
||||
/* Super Deep Sleep Seconds
|
||||
While in Light Sleep if mesh_sds_timeout_secs is exceeded we will lower into super deep sleep
|
||||
for this value (default 1 year) or a button press
|
||||
0 for default of one year */
|
||||
uint32_t sds_secs;
|
||||
/* Light Sleep Seconds
|
||||
In light sleep the CPU is suspended, LoRa radio is on, BLE is off an GPS is on
|
||||
ESP32 Only
|
||||
0 for default of 300 */
|
||||
/* Description: In light sleep the CPU is suspended, LoRa radio is on, BLE is off an GPS is on
|
||||
Technical Details: ESP32 Only 0 for default of 300 */
|
||||
uint32_t ls_secs;
|
||||
/* Minimum Wake Seconds
|
||||
While in light sleep when we receive packets on the LoRa radio we will wake and handle them and stay awake in no BLE mode for this value
|
||||
0 for default of 10 seconds */
|
||||
/* Description: While in light sleep when we receive packets on the LoRa radio we will wake and handle them and stay awake in no BLE mode for this value
|
||||
Technical Details: ESP32 Only 0 for default of 10 seconds */
|
||||
uint32_t min_wake_secs;
|
||||
/* I2C address of INA_2XX to use for reading device battery voltage */
|
||||
uint8_t device_battery_ina_address;
|
||||
@@ -585,7 +582,7 @@ extern "C" {
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}}
|
||||
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, ""}
|
||||
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0}
|
||||
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
||||
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""}
|
||||
@@ -594,7 +591,7 @@ extern "C" {
|
||||
#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0}
|
||||
#define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
|
||||
#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}}
|
||||
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, ""}
|
||||
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0}
|
||||
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
||||
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""}
|
||||
@@ -615,6 +612,7 @@ extern "C" {
|
||||
#define meshtastic_Config_DeviceConfig_is_managed_tag 9
|
||||
#define meshtastic_Config_DeviceConfig_disable_triple_click_tag 10
|
||||
#define meshtastic_Config_DeviceConfig_tzdef_tag 11
|
||||
#define meshtastic_Config_DeviceConfig_led_heartbeat_disabled_tag 12
|
||||
#define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1
|
||||
#define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2
|
||||
#define meshtastic_Config_PositionConfig_fixed_position_tag 3
|
||||
@@ -715,7 +713,8 @@ X(a, STATIC, SINGULAR, UINT32, node_info_broadcast_secs, 7) \
|
||||
X(a, STATIC, SINGULAR, BOOL, double_tap_as_button_press, 8) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_managed, 9) \
|
||||
X(a, STATIC, SINGULAR, BOOL, disable_triple_click, 10) \
|
||||
X(a, STATIC, SINGULAR, STRING, tzdef, 11)
|
||||
X(a, STATIC, SINGULAR, STRING, tzdef, 11) \
|
||||
X(a, STATIC, SINGULAR, BOOL, led_heartbeat_disabled, 12)
|
||||
#define meshtastic_Config_DeviceConfig_CALLBACK NULL
|
||||
#define meshtastic_Config_DeviceConfig_DEFAULT NULL
|
||||
|
||||
@@ -832,8 +831,9 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg;
|
||||
#define meshtastic_Config_BluetoothConfig_fields &meshtastic_Config_BluetoothConfig_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define MESHTASTIC_MESHTASTIC_CONFIG_PB_H_MAX_SIZE meshtastic_Config_size
|
||||
#define meshtastic_Config_BluetoothConfig_size 10
|
||||
#define meshtastic_Config_DeviceConfig_size 98
|
||||
#define meshtastic_Config_DeviceConfig_size 100
|
||||
#define meshtastic_Config_DisplayConfig_size 28
|
||||
#define meshtastic_Config_LoRaConfig_size 80
|
||||
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#include "meshtastic/connection_status.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#ifndef PB_MESHTASTIC_MESHTASTIC_CONNECTION_STATUS_PB_H_INCLUDED
|
||||
#define PB_MESHTASTIC_MESHTASTIC_CONNECTION_STATUS_PB_H_INCLUDED
|
||||
@@ -175,6 +175,7 @@ extern const pb_msgdesc_t meshtastic_SerialConnectionStatus_msg;
|
||||
#define meshtastic_SerialConnectionStatus_fields &meshtastic_SerialConnectionStatus_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define MESHTASTIC_MESHTASTIC_CONNECTION_STATUS_PB_H_MAX_SIZE meshtastic_DeviceConnectionStatus_size
|
||||
#define meshtastic_BluetoothConnectionStatus_size 19
|
||||
#define meshtastic_DeviceConnectionStatus_size 106
|
||||
#define meshtastic_EthernetConnectionStatus_size 13
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#include "meshtastic/deviceonly.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#ifndef PB_MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_INCLUDED
|
||||
#define PB_MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_INCLUDED
|
||||
@@ -174,12 +174,12 @@ extern "C" {
|
||||
/* Initializer values for message structs */
|
||||
#define meshtastic_PositionLite_init_default {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
|
||||
#define meshtastic_NodeInfoLite_init_default {0, false, meshtastic_User_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, 0, 0}
|
||||
#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}, {{NULL}, NULL}}
|
||||
#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}, {0}}
|
||||
#define meshtastic_ChannelFile_init_default {0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0}
|
||||
#define meshtastic_OEMStore_init_default {0, 0, {0, {0}}, _meshtastic_ScreenFonts_MIN, "", {0, {0}}, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default}
|
||||
#define meshtastic_PositionLite_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
|
||||
#define meshtastic_NodeInfoLite_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, 0, 0}
|
||||
#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}, {{NULL}, NULL}}
|
||||
#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}, {0}}
|
||||
#define meshtastic_ChannelFile_init_zero {0, {meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero}, 0}
|
||||
#define meshtastic_OEMStore_init_zero {0, 0, {0, {0}}, _meshtastic_ScreenFonts_MIN, "", {0, {0}}, false, meshtastic_LocalConfig_init_zero, false, meshtastic_LocalModuleConfig_init_zero}
|
||||
|
||||
@@ -305,9 +305,10 @@ extern const pb_msgdesc_t meshtastic_OEMStore_msg;
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
/* meshtastic_DeviceState_size depends on runtime parameters */
|
||||
#define meshtastic_ChannelFile_size 702
|
||||
#define meshtastic_NodeInfoLite_size 160
|
||||
#define meshtastic_OEMStore_size 3344
|
||||
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_OEMStore_size
|
||||
#define meshtastic_ChannelFile_size 718
|
||||
#define meshtastic_NodeInfoLite_size 166
|
||||
#define meshtastic_OEMStore_size 3346
|
||||
#define meshtastic_PositionLite_size 28
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#include "meshtastic/localonly.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#ifndef PB_MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_INCLUDED
|
||||
#define PB_MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_INCLUDED
|
||||
@@ -180,7 +180,8 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
|
||||
#define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define meshtastic_LocalConfig_size 535
|
||||
#define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalModuleConfig_size
|
||||
#define meshtastic_LocalConfig_size 537
|
||||
#define meshtastic_LocalModuleConfig_size 663
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#include "meshtastic/mesh.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#ifndef PB_MESHTASTIC_MESHTASTIC_MESH_PB_H_INCLUDED
|
||||
#define PB_MESHTASTIC_MESHTASTIC_MESH_PB_H_INCLUDED
|
||||
@@ -63,6 +63,8 @@ typedef enum _meshtastic_HardwareModel {
|
||||
meshtastic_HardwareModel_NANO_G2_ULTRA = 18,
|
||||
/* LoRAType device: https://loratype.org/ */
|
||||
meshtastic_HardwareModel_LORA_TYPE = 19,
|
||||
/* wiphone https://www.wiphone.io/ */
|
||||
meshtastic_HardwareModel_WIPHONE = 20,
|
||||
/* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */
|
||||
meshtastic_HardwareModel_STATION_G1 = 25,
|
||||
/* RAK11310 (RP2040 + SX1262) */
|
||||
@@ -146,6 +148,14 @@ typedef enum _meshtastic_HardwareModel {
|
||||
/* Teledatics TD-LORAC NRF52840 based M.2 LoRA module
|
||||
Compatible with the TD-WRLS development board */
|
||||
meshtastic_HardwareModel_TD_LORAC = 60,
|
||||
/* CDEBYTE EoRa-S3 board using their own MM modules, clone of LILYGO T3S3 */
|
||||
meshtastic_HardwareModel_CDEBYTE_EORA_S3 = 61,
|
||||
/* TWC_MESH_V4
|
||||
Adafruit NRF52840 feather express with SX1262, SSD1306 OLED and NEO6M GPS */
|
||||
meshtastic_HardwareModel_TWC_MESH_V4 = 62,
|
||||
/* NRF52_PROMICRO_DIY
|
||||
Promicro NRF52840 with SX1262/LLCC68, SSD1306 OLED and NEO6M GPS */
|
||||
meshtastic_HardwareModel_NRF52_PROMICRO_DIY = 63,
|
||||
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
||||
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.
|
||||
------------------------------------------------------------------------------------------------------------------------------------------ */
|
||||
@@ -1372,6 +1382,7 @@ extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePin_msg;
|
||||
#define meshtastic_NodeRemoteHardwarePin_fields &meshtastic_NodeRemoteHardwarePin_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define MESHTASTIC_MESHTASTIC_MESH_PB_H_MAX_SIZE meshtastic_FromRadio_size
|
||||
#define meshtastic_Compressed_size 243
|
||||
#define meshtastic_Data_size 270
|
||||
#define meshtastic_DeviceMetadata_size 46
|
||||
@@ -1383,7 +1394,7 @@ extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePin_msg;
|
||||
#define meshtastic_MyNodeInfo_size 18
|
||||
#define meshtastic_NeighborInfo_size 258
|
||||
#define meshtastic_Neighbor_size 22
|
||||
#define meshtastic_NodeInfo_size 277
|
||||
#define meshtastic_NodeInfo_size 283
|
||||
#define meshtastic_NodeRemoteHardwarePin_size 29
|
||||
#define meshtastic_Position_size 144
|
||||
#define meshtastic_QueueStatus_size 23
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#include "meshtastic/module_config.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#ifndef PB_MESHTASTIC_MESHTASTIC_MODULE_CONFIG_PB_H_INCLUDED
|
||||
#define PB_MESHTASTIC_MESHTASTIC_MODULE_CONFIG_PB_H_INCLUDED
|
||||
@@ -827,6 +827,7 @@ extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg;
|
||||
#define meshtastic_RemoteHardwarePin_fields &meshtastic_RemoteHardwarePin_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define MESHTASTIC_MESHTASTIC_MODULE_CONFIG_PB_H_MAX_SIZE meshtastic_ModuleConfig_size
|
||||
#define meshtastic_ModuleConfig_AmbientLightingConfig_size 14
|
||||
#define meshtastic_ModuleConfig_AudioConfig_size 19
|
||||
#define meshtastic_ModuleConfig_CannedMessageConfig_size 49
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#include "meshtastic/mqtt.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#ifndef PB_MESHTASTIC_MESHTASTIC_MQTT_PB_H_INCLUDED
|
||||
#define PB_MESHTASTIC_MESHTASTIC_MQTT_PB_H_INCLUDED
|
||||
@@ -120,6 +120,7 @@ extern const pb_msgdesc_t meshtastic_MapReport_msg;
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
/* meshtastic_ServiceEnvelope_size depends on runtime parameters */
|
||||
#define MESHTASTIC_MESHTASTIC_MQTT_PB_H_MAX_SIZE meshtastic_MapReport_size
|
||||
#define meshtastic_MapReport_size 108
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#include "meshtastic/paxcount.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#ifndef PB_MESHTASTIC_MESHTASTIC_PAXCOUNT_PB_H_INCLUDED
|
||||
#define PB_MESHTASTIC_MESHTASTIC_PAXCOUNT_PB_H_INCLUDED
|
||||
@@ -48,6 +48,7 @@ extern const pb_msgdesc_t meshtastic_Paxcount_msg;
|
||||
#define meshtastic_Paxcount_fields &meshtastic_Paxcount_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define MESHTASTIC_MESHTASTIC_PAXCOUNT_PB_H_MAX_SIZE meshtastic_Paxcount_size
|
||||
#define meshtastic_Paxcount_size 18
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#include "meshtastic/portnums.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#ifndef PB_MESHTASTIC_MESHTASTIC_PORTNUMS_PB_H_INCLUDED
|
||||
#define PB_MESHTASTIC_MESHTASTIC_PORTNUMS_PB_H_INCLUDED
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.7 */
|
||||
/* Generated by nanopb-0.4.8 */
|
||||
|
||||
#include "meshtastic/remote_hardware.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user