Compare commits

..

6 Commits

Author SHA1 Message Date
Kevin Hester
9d21e58b0b 1.2.46 2021-10-15 10:10:12 -07:00
Kevin Hester
576acdc117 update protobufs 2021-10-15 10:10:12 -07:00
Kevin Hester
538e22c7cd fix build for my hacked up nrf52 devboard (must use SD140) 2021-10-15 10:10:12 -07:00
Kevin Hester
d81f19c7c3 regen protos 2021-10-12 08:41:36 -07:00
Kevin Hester
252d847779 bl602 notes 2021-10-12 08:41:36 -07:00
Kevin Hester
3da6607a18 todo update 2021-10-12 08:41:36 -07:00
140 changed files with 935 additions and 2411 deletions

View File

@@ -4,12 +4,12 @@ on:
# workflow_dispatch:
# inputs:
# Only want to run if version.properties is bumped in master
# Only want to be run if a new tag starting with v is pushed.
push:
branches:
- master
paths:
- 'version.properties'
- "!*"
tags:
- "v1*"
jobs:
release-build:
@@ -21,15 +21,19 @@ jobs:
with:
submodules: 'recursive'
# get github branch and tag names as ${{ steps.branch_name.outputs.SOURCE_TAG }}
- name: Branch name
id: branch_name
run: |
echo ::set-output name=SOURCE_NAME::${GITHUB_REF#refs/*/}
echo ::set-output name=SOURCE_BRANCH::${GITHUB_REF#refs/heads/}
echo ::set-output name=SOURCE_TAG::${GITHUB_REF#refs/tags/}
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.x
# Will be available in steps.version.outputs.version
- name: Get release version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
id: version
# Note: we don't use caches on release builds because we don't want to accidentally not have a virgin build machine
- name: Upgrade python tools
@@ -56,6 +60,11 @@ jobs:
tar -xf build.tar -C data/static
rm build.tar
# Will be available in steps.version.outputs.version
- name: Get version string
run: echo "::set-output name=version::$(./bin/buildinfo.py long)"
id: version
- name: Build everything
run: bin/build-all.sh
@@ -66,7 +75,8 @@ jobs:
draft: true
prerelease: true
release_name: ${{ steps.version.outputs.version }} alpha
tag_name: v${{ steps.version.outputs.version }}
tag_name: ${{ steps.branch_name.outputs.SOURCE_TAG }}
# was ${{ github.ref }}
body: |
Autogenerated by github action, developer should edit as required before publishing...
env:
@@ -90,4 +100,4 @@ jobs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: release/archive/elfs-${{ steps.version.outputs.version }}.zip
asset_name: debug-elfs-${{ steps.version.outputs.version }}.zip
asset_content_type: application/zip
asset_content_type: application/zip

View File

@@ -1,24 +0,0 @@
name: "Update protobufs"
on: workflow_dispatch
jobs:
update-protobufs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
submodules: true
- name: Update Submodule
run: |
git pull --recurse-submodules
git submodule update --remote --recursive
- name: Commit update
run: |
git config --global user.name 'github-actions'
git config --global user.email 'bot@noreply.github.com'
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
git add proto
git commit -m "Update protobuf submodule" && git push || echo "No changes to commit"

5
.gitignore vendored
View File

@@ -9,7 +9,7 @@ main/credentials.h
!.vscode/extensions.json
*.code-workspace
.idea
.idea/workspace.xml
.DS_Store
Thumbs.db
@@ -23,6 +23,3 @@ flash.uf2
cmake-build*
__pycache__
*.swp
*.swo
*~

View File

@@ -1,50 +0,0 @@
image: python:latest
variables:
# make sure GitLab check out submodules
GIT_SUBMODULE_STRATEGY: recursive
stages:
- buildall
- upload
build:
stage: buildall
before_script:
# we need zip later for packaging
- "apt update;apt -y install zip"
- "pip install -U platformio"
script:
# clean up residues from previous run
- rm -rf release
- bin/build-all.sh
# This is for my local environment, if your runners are tagged differently, modify or remove
tags:
- dockerized
# The files which are to be made available in GitLab
artifacts:
paths:
- release/archive/firmware*.zip
upload:
image: curlimages/curl:latest
stage: upload
script:
- |
PACKAGE_REGISTRY_URL="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${CI_PROJECT_NAME}/master"
cd release/archive
for f in *.zip; do
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file ${f} ${PACKAGE_REGISTRY_URL}/${f}
done
echo 'Package uploaded!'
# This is for my local environment, if your runners are tagged differently, modify or remove
tags:
- dockerized

7
.idea/codeStyles/Project.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<clangFormatSettings>
<option name="ENABLED" value="true" />
</clangFormatSettings>
</code_scheme>
</component>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

2
.idea/meshtastic-esp32.iml generated Normal file
View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />

4
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/meshtastic-esp32.iml" filepath="$PROJECT_DIR$/.idea/meshtastic-esp32.iml" />
</modules>
</component>
</project>

9
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/design" vcs="Git" />
<mapping directory="$PROJECT_DIR$/proto" vcs="Git" />
<mapping directory="$PROJECT_DIR$/sdk-nrfxlib" vcs="Git" />
</component>
</project>

View File

@@ -50,8 +50,7 @@
"cassert": "cpp",
"iterator": "cpp",
"shared_mutex": "cpp",
"iostream": "cpp",
"esp_nimble_hci.h": "c"
"iostream": "cpp"
},
"cSpell.words": [
"Blox",

View File

@@ -2,10 +2,4 @@
[![Open in Visual Studio Code](https://open.vscode.dev/badges/open-in-vscode.svg)](https://open.vscode.dev/meshtastic/Meshtastic-device)
## This repository contains the device firmware used in the [Meshtastic](https://meshtastic.org) project.
Update Instructions
[For ESP32 devices click here](https://meshtastic.org/docs/getting-started/flashing-esp32)
[For nRF52 devices click here](https://meshtastic.org/docs/getting-started/flashing-nrf52)
For developer information and specific building instructions, please see the [developer doccumentation](https://meshtastic.org/docs/developers)

View File

@@ -1,15 +1,15 @@
#!/usr/bin/env bash
#!/bin/bash
set -e
VERSION=`bin/buildinfo.py long`
SHORT_VERSION=`bin/buildinfo.py short`
BOARDS_ESP32="tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v1 heltec-v2.0 heltec-v2.1 tbeam0.7 meshtastic-diy-v1"
BOARDS_ESP32="tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec-v2.0 heltec-v2.1 tbeam0.7"
#BOARDS_ESP32=tbeam
# FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine
BOARDS_NRF52="rak4631_5005 rak4631_19003 t-echo"
BOARDS_NRF52="rak4631 t-echo"
#BOARDS_NRF52=""
OUTDIR=release/latest

38
bin/build-nightly.sh Executable file
View File

@@ -0,0 +1,38 @@
#!/bin/bash
source ~/.bashrc
# Meshtastic Nightly Build Script.
# McHamster (jm@casler.org)
#
# This is the script that is used for the nightly build server.
#
# It's probably not useful for most people, but you may want to run your own
# nightly builds.
#
# The last line of ~/.bashrc contains an inclusion of platformio in the path.
# Without this, the build script won't run from the crontab:
#
# export PATH="$HOME/.platformio/penv/bin:$PATH"
#
# The crontab contains:
# 0 2 * * * cd ~/meshtastic/github/meshtastic && source "~/.bashrc"; ./build-nightly.sh > ~/cronout.txt 2> ~/cronout.txt
cd Meshtastic-device
git pull
bin/build-all.sh
date_stamp=$(date +'%Y-%m-%d')
cd ..
# TODO: Archive the same binaries used by the build-all script.
#zip -r meshtastic_device_nightly_${date_stamp} Meshtastic-device/release/latest/bins
cp Meshtastic-device/release/archive/`ls -t ./Meshtastic-device/release/archive/| head -1` meshtastic_device_nightly_${date_stamp}.zip
# Copy the file to the webserver
scp meshtastic_device_nightly_${date_stamp}.zip jm@10.11.12.20:/volume1/web/meshtastic/nightly_builds/
# Delete the local copy
rm meshtastic_device_nightly_${date_stamp}.zip

View File

@@ -46,10 +46,10 @@ shift "$((OPTIND-1))"
if [ -f "${FILENAME}" ]; then
echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
$PYTHON -m esptool erase_flash
$PYTHON -m esptool write_flash 0x1000 system-info.bin
$PYTHON -m esptool write_flash 0x00390000 spiffs-*.bin
$PYTHON -m esptool write_flash 0x10000 ${FILENAME}
$PYTHON -m esptool --baud 921600 erase_flash
$PYTHON -m esptool --baud 921600 write_flash 0x1000 system-info.bin
$PYTHON -m esptool --baud 921600 write_flash 0x00390000 spiffs-*.bin
$PYTHON -m esptool --baud 921600 write_flash 0x10000 ${FILENAME}
else
echo "Invalid file: ${FILENAME}"
show_help

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
arm-none-eabi-readelf -s -e .pio/build/nrf52dk/firmware.elf | head -80
nm -CSr --size-sort .pio/build/nrf52dk/firmware.elf | grep '^200'

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env bash
set -e

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/python2
# This is a layout for 4MB of flash
# Name, Type, SubType, Offset, Size, Flags
@@ -38,4 +38,4 @@ app0, app, ota_0, , 0x{app:x},
app1, app, ota_1, , 0x{app:x},
spiffs, data, spiffs, , 0x{spi:x} """.format(**locals())
print(table)
print(table)

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
# You probably don't want to use this script, it programs a custom bootloader build onto a nrf52 board
set -e

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
# You probably don't want to use this script, it programs a custom bootloader build onto a nrf52 board
set -e

View File

@@ -1,4 +1,3 @@
#!/usr/bin/env bash
mosquitto_sub -h mqtt.meshtastic.org -v -t \$SYS/\# -t msh/+/stat/\# -t msh/+/json/\#
# mosquitto_sub -h test.mosquitto.org -v -t mesh/\# -F "%j"

View File

@@ -1,3 +1 @@
#!/usr/bin/env bash
mosquitto_pub -h mqtt.meshtastic.org -u meshdev -P large4cats -t msh/1/stat/FakeNode -m online -d

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
set -e
pio run --environment native
gdbserver --once localhost:2345 .pio/build/native/program "$@"

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
set -e
pio run --environment native
.pio/build/native/program "$@"

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env bash
# JLinkRTTViewer
JLinkRTTClient
JLinkRTTClient

View File

@@ -1,3 +1,3 @@
#!/usr/bin/env bash
JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52832_XXAA

View File

@@ -1,3 +1,3 @@
#!/usr/bin/env bash
JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52833_XXAA

View File

@@ -1,3 +1,3 @@
#!/usr/bin/env bash
JLinkGDBServerCLExe -if SWD -select USB -port 2331 -device NRF52840_XXAA -SuppressInfoUpdateFW -DisableAutoUpdateFW -rtos GDBServer/RTOSPlugin_FreeRTOS

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
esptool.py --baud 921600 write_flash 0x10000 release/archive/old/firmware-tbeam-EU865-1.0.0.bin
echo "Erasing the otadata partition, which will turn off flash flippy-flop and force the first image to be used"
esptool.py --baud 921600 erase_region 0xe000 0x2000

View File

@@ -1,3 +1 @@
#!/usr/bin/env bash
esptool.py --baud 921600 write_flash 0x10000 release/archive/old/firmware-tbeam-1.1.50.bin

View File

@@ -1,4 +1,3 @@
#!/usr/bin/env bash
set -e

View File

@@ -1,4 +1,3 @@
#!/usr/bin/env bash
set -e

View File

@@ -1,4 +1,3 @@
#!/usr/bin/env bash
set -e

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
set -e
echo "This script is only for developers who are publishing new builds on github. Most users don't need it"
@@ -8,10 +6,6 @@ VERSION=`bin/buildinfo.py long`
# Must have a V prefix to trigger github
git tag "v${VERSION}"
# Commented out per https://github.com/meshtastic/Meshtastic-device/issues/947
#git push root "v${VERSION}" # push the tag
git push origin "v${VERSION}" # push the tag
git push root "v${VERSION}" # push the tag
echo "Tag ${VERSION} pushed to github, github actions should now be building the draft release. If it seems good, click to publish it"

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
# You probably don't need this - it is a basic test of the serial flash on the TTGO eink board
nrfjprog --qspiini nrf52/ttgo_eink_qpsi.ini --qspieraseall

View File

@@ -1,3 +1 @@
#!/usr/bin/env bash
esptool.py --baud 921600 read_flash 0x1000 0xf000 system-info.img

View File

@@ -1 +0,0 @@
cd proto && ..\nanopb-0.4.4\generator-bin\protoc.exe --nanopb_out=-v:..\src\mesh\generated -I=..\proto *.proto

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/bin/bash
set -e
@@ -12,4 +12,4 @@ cd proto
#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
#bin/regen-docs.sh

View File

@@ -1,3 +1 @@
#!/usr/bin/env bash
pio run --upload-port /dev/ttyUSB0 -t upload -t monitor

View File

@@ -1,3 +1 @@
#!/usr/bin/env bash
pio run --upload-port /dev/ttyUSB1 -t upload -t monitor

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
set -e
echo uploading to usb1

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
set -e
TARG=tbeam

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env bash
# /home/kevinh/.platformio/packages/tool-openocd-esp32/bin/openocd -s /home/kevinh/.platformio/packages/tool-openocd-esp32 -c gdb_port pipe; tcl_port disabled; telnet_port disabled -s /home/kevinh/.platformio/packages/tool-openocd-esp32/share/openocd/scripts -f interface/jlink.cfg -f board/esp-wroom-32.cfg
/home/kevinh/.platformio/packages/tool-openocd-esp32/bin/openocd -s /home/kevinh/.platformio/packages/tool-openocd-esp32 -s /home/kevinh/.platformio/packages/tool-openocd-esp32/share/openocd/scripts -f interface/jlink.cfg -f ./lora32-openocd.cfg

View File

@@ -1,3 +1 @@
#!/usr/bin/env bash
pio device monitor -b 921600

View File

@@ -1,3 +1 @@
#!/usr/bin/env bash
pio device monitor -p /dev/ttyUSB1 -b 921600

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
set -e
echo "Starting simulator"

View File

@@ -1,2 +0,0 @@
@echo off
if [%1]==[] (echo "Please specify a platformio NRF target (i.e. rak4631) as the first argument.") else (python3 .\bin\uf2conv.py .\.pio\build\%1\firmware.hex -c -o .\.pio\build\%1\firmware.uf2 -f 0xADA52840)

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
set -e
echo "building for t-echo"

View File

@@ -1,5 +1,3 @@
#!/usr/bin/env bash
set -e
echo "Converting to uf2 for NRF52 Adafruit bootloader"

View File

@@ -1,3 +1 @@
#!/usr/bin/env bash
pio run --upload-port /dev/ttyUSB1 -t upload

View File

@@ -1,4 +1,2 @@
#!/usr/bin/env bash
echo using amap tool to display memory map
amap .pio/build/output.map

BIN
deprecated/icon-18dp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 B

1
deprecated/icon-24px.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 5c-3.87 0-7 3.13-7 7h2c0-2.76 2.24-5 5-5s5 2.24 5 5h2c0-3.87-3.13-7-7-7zm1 9.29c.88-.39 1.5-1.26 1.5-2.29 0-1.38-1.12-2.5-2.5-2.5S9.5 10.62 9.5 12c0 1.02.62 1.9 1.5 2.29v3.3L7.59 21 9 22.41l3-3 3 3L16.41 21 13 17.59v-3.3zM12 1C5.93 1 1 5.93 1 12h2c0-4.97 4.03-9 9-9s9 4.03 9 9h2c0-6.07-4.93-11-11-11z"/></svg>

After

Width:  |  Height:  |  Size: 442 B

BIN
deprecated/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -325,7 +325,7 @@ Items after the first final candidate release.
- add "store and forward" support for messages, or move to the DB sync model. This would allow messages to be eventually delivered even if nodes are out of contact at the moment.
- use variable length Strings in protobufs (instead of current fixed buffers). This would save lots of RAM
- use BLEDevice::setPower to lower our BLE transmit power - extra range doesn't help us, it costs amps and it increases snoopability
- make a Ham build: just a new frequency list, a bool to say 'never do encryption' and use the callsign as that node's unique id. -from Girts
- make a HAM build: just a new frequency list, a bool to say 'never do encryption' and use hte callsign as that node's unique id. -from Girts
- don't forward redundant pings or ping responses to the phone, it just wastes phone battery
- don't send location packets if we haven't moved significantly
- scrub default radio config settings for bandwidth/range/speed

View File

@@ -0,0 +1,7 @@
* install python
* install git (including git-bash)
* install platformio
* install vscode
* install https://sourceforge.net/projects/mingw-w64/ (for windows gcc/g++) - you'll need to add the bin directory to your PATH

View File

@@ -9,11 +9,9 @@
; https://docs.platformio.org/page/projectconf.html
[platformio]
default_envs = tbeam
;default_envs = tbeam
;default_envs = tbeam0.7
;default_envs = heltec-v2.0
;default_envs = heltec-v1
;default_envs = tlora-v1
;default_envs = tlora-v1
;default_envs = tlora_v1_3
;default_envs = tlora-v2
@@ -23,7 +21,7 @@ default_envs = tbeam
;default_envs = native # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here
;default_envs = rak4631
;default_envs = rak4630
;default_envs = meshtastic-diy-v1
default_envs = meshtastic-diy-v1
[common]
; common is not currently used
@@ -71,7 +69,7 @@ debug_tool = jlink
lib_deps =
https://github.com/meshtastic/esp8266-oled-ssd1306.git#35d796226b853b0c0ff818b2f1aa3d35e7296a96 ; ESP8266_SSD1306
https://github.com/meshtastic/OneButton.git#3bcba9492d01e2a8a86f46700ab16f96dd2cf1f5 ; OneButton library for non-blocking button debounce
https://github.com/geeksville/OneButton.git ; OneButton library for non-blocking button debounce
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
https://github.com/meshtastic/arduino-fsm.git
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad
@@ -104,36 +102,23 @@ src_filter =
${arduino_base.src_filter} -<nrf52/>
upload_speed = 921600
debug_init_break = tbreak setup
# Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging.
# See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h
# This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h
build_flags =
${arduino_base.build_flags} -Wall -Wextra -Isrc/esp32 -Isrc/esp32-mfix-esp32-psram-cache-issue -lnimble -std=c++11
-DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL
-DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
-DAXP_DEBUG_PORT=Serial
lib_deps =
${arduino_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git
adafruit/DHT sensor library@^1.4.1
adafruit/Adafruit Unified Sensor@^1.1.4
paulstoffregen/OneWire@^2.3.5
robtillaart/DS18B20@^0.1.11
h2zero/NimBLE-Arduino@1.3.4
tobozo/ESP32-targz@^1.1.4
arduino-libraries/NTPClient#531eff39d9fbc831f3d03f706a161739203fbe2a
# Hmm - this doesn't work yet
# board_build.ldscript = linker/esp32.extram.bss.ld
lib_ignore =
segger_rtt
ESP32 BLE Arduino
lib_ignore = segger_rtt
platform_packages =
framework-arduinoespressif32@https://github.com/meshtastic/arduino-esp32.git#4cde0f5d412d2695184f32e8a47e9bea57b45276
; leave this commented out to avoid breaking Windows
;upload_port = /dev/ttyUSB0
upload_port = /dev/ttyUSB0
;monitor_port = /dev/ttyUSB0
;upload_port = /dev/cu.SLAB_USBtoUART
@@ -167,13 +152,6 @@ board = ttgo-t-beam
build_flags =
${esp32_base.build_flags} -D TBEAM_V07
[env:heltec-v1]
;build_type = debug ; to make it possible to step through our jtag debugger
extends = esp32_base
board = heltec_wifi_lora_32
build_flags =
${esp32_base.build_flags} -D HELTEC_V1
[env:heltec-v2.0]
;build_type = debug ; to make it possible to step through our jtag debugger
extends = esp32_base
@@ -345,21 +323,12 @@ monitor_speed = 115200
# board_build.ldscript = linker/nrf52840_s140_sim832.ld
; The very slick RAK wireless RAK 4631 / 4630 board
[env:rak4631_5005]
[env:rak4631]
extends = nrf52840_base
board = wiscore_rak4631
# add our variants files to the include and src paths
# define build flags for the TFT_eSPI library
build_flags = ${nrf52840_base.build_flags} -Ivariants/WisCore_RAK4631_Board -D RAK_BASE_5005
src_filter = ${nrf52_base.src_filter} +<../variants/WisCore_RAK4631_Board>
debug_tool = jlink
[env:rak4631_19003]
extends = nrf52840_base
board = wiscore_rak4631
# add our variants files to the include and src paths
# define build flags for the TFT_eSPI library
build_flags = ${nrf52840_base.build_flags} -Ivariants/WisCore_RAK4631_Board -D RAK_BASE_19003
build_flags = ${nrf52840_base.build_flags} -Ivariants/WisCore_RAK4631_Board
src_filter = ${nrf52_base.src_filter} +<../variants/WisCore_RAK4631_Board>
debug_tool = jlink
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)

2
proto

Submodule proto updated: 18fc4cdb52...e24fa8c6ed

1
src/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
main.ino.cpp

View File

@@ -19,39 +19,28 @@ class GPSStatus : public Status
bool hasLock = false; // default to false, until we complete our first read
bool isConnected = false; // Do we have a GPS we are talking to
Position p = Position_init_default;
int32_t latitude = 0, longitude = 0; // as an int mult by 1e-7 to get value as double
int32_t altitude = 0;
uint32_t dop = 0; // Diminution of position; PDOP where possible (UBlox), HDOP otherwise (TinyGPS) in 10^2 units (needs
// scaling before use)
uint32_t heading = 0;
uint32_t numSatellites = 0;
public:
GPSStatus() { statusType = STATUS_TYPE_GPS; }
// proposed for deprecation
GPSStatus(bool hasLock, bool isConnected, int32_t latitude, int32_t longitude, int32_t altitude, uint32_t dop,
uint32_t heading, uint32_t numSatellites)
: Status()
{
this->hasLock = hasLock;
this->isConnected = isConnected;
this->p.latitude_i = latitude;
this->p.longitude_i = longitude;
this->p.altitude = altitude;
this->p.PDOP = dop;
this->p.ground_track = heading;
this->p.sats_in_view = numSatellites;
this->latitude = latitude;
this->longitude = longitude;
this->altitude = altitude;
this->dop = dop;
this->heading = heading;
this->numSatellites = numSatellites;
}
// preferred method
GPSStatus(bool hasLock, bool isConnected, Position pos)
: Status()
{
this->hasLock = hasLock;
this->isConnected = isConnected;
// all-in-one struct copy
this->p = pos;
}
GPSStatus(const GPSStatus &);
GPSStatus &operator=(const GPSStatus &);
@@ -67,7 +56,7 @@ class GPSStatus : public Status
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
return node->position.latitude_i;
} else {
return p.latitude_i;
return latitude;
}
}
@@ -77,7 +66,7 @@ class GPSStatus : public Status
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
return node->position.longitude_i;
} else {
return p.longitude_i;
return longitude;
}
}
@@ -87,59 +76,44 @@ class GPSStatus : public Status
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
return node->position.altitude;
} else {
return p.altitude;
return altitude;
}
}
uint32_t getDOP() const { return p.PDOP; }
uint32_t getHeading() const { return p.ground_track; }
uint32_t getDOP() const { return dop; }
uint32_t getNumSatellites() const { return p.sats_in_view; }
uint32_t getHeading() const { return heading; }
uint32_t getNumSatellites() const { return numSatellites; }
bool matches(const GPSStatus *newStatus) const
{
#if GPS_EXTRAVERBOSE
DEBUG_MSG("GPSStatus.match() new pos@%x to old pos@%x\n",
newStatus->p.pos_timestamp, p.pos_timestamp);
#endif
return (newStatus->hasLock != hasLock ||
newStatus->isConnected != isConnected ||
newStatus->p.latitude_i != p.latitude_i ||
newStatus->p.longitude_i != p.longitude_i ||
newStatus->p.altitude != p.altitude ||
newStatus->p.altitude_hae != p.altitude_hae ||
newStatus->p.PDOP != p.PDOP ||
newStatus->p.ground_track != p.ground_track ||
newStatus->p.sats_in_view != p.sats_in_view);
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected || newStatus->latitude != latitude ||
newStatus->longitude != longitude || newStatus->altitude != altitude || newStatus->dop != dop ||
newStatus->heading != heading || newStatus->numSatellites != numSatellites);
}
int updateStatus(const GPSStatus *newStatus)
{
// Only update the status if values have actually changed
bool isDirty = matches(newStatus);
if (isDirty && p.pos_timestamp &&
(newStatus->p.pos_timestamp == p.pos_timestamp)) {
// We can NEVER be in two locations at the same time! (also PR #886)
DEBUG_MSG("BUG!! positional timestamp unchanged from prev solution\n");
bool isDirty;
{
isDirty = matches(newStatus);
initialized = true;
hasLock = newStatus->hasLock;
isConnected = newStatus->isConnected;
latitude = newStatus->latitude;
longitude = newStatus->longitude;
altitude = newStatus->altitude;
dop = newStatus->dop;
heading = newStatus->heading;
numSatellites = newStatus->numSatellites;
}
initialized = true;
hasLock = newStatus->hasLock;
isConnected = newStatus->isConnected;
p = newStatus->p;
if (isDirty) {
if (hasLock) {
// In debug logs, identify position by @timestamp:stage (stage 3 = notify)
DEBUG_MSG("New GPS pos@%x:3 lat=%f, lon=%f, alt=%d, pdop=%.2f, track=%.2f, sats=%d\n",
p.pos_timestamp,
p.latitude_i * 1e-7, p.longitude_i * 1e-7,
p.altitude, p.PDOP * 1e-2, p.ground_track * 1e-5,
p.sats_in_view);
} else
if (hasLock)
DEBUG_MSG("New GPS pos lat=%f, lon=%f, alt=%d, pdop=%f, heading=%f, sats=%d\n", latitude * 1e-7, longitude * 1e-7,
altitude, dop * 1e-2, heading * 1e-5, numSatellites);
else
DEBUG_MSG("No GPS lock\n");
onNewStatus.notifyObservers(this);
}

View File

@@ -1,8 +1,8 @@
#include "configuration.h"
#include "PowerFSM.h"
#include "GPS.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "configuration.h"
#include "graphics/Screen.h"
#include "main.h"
#include "sleep.h"
@@ -11,11 +11,6 @@
/// Should we behave as if we have AC power now?
static bool isPowered()
{
// Completely circumvents the battery / power sensing logic and assumes constant power source
if (radioConfig.preferences.is_always_powered) {
return true;
}
bool isRouter = radioConfig.preferences.is_router;
// If we are not a router and we already have AC power go to POWER state after init, otherwise go to ON
@@ -37,14 +32,6 @@ static void sdsEnter()
doDeepSleep(getPref_sds_secs() * 1000LL);
}
extern Power *power;
static void shutdownEnter()
{
DEBUG_MSG("Enter state: SHUTDOWN\n");
power->shutdown();
}
#include "error.h"
static uint32_t secsSlept;
@@ -221,12 +208,10 @@ static void screenPress()
screen->onPress();
}
static void bootEnter()
{
static void bootEnter() {
DEBUG_MSG("Enter state: BOOT\n");
}
State stateSHUTDOWN(shutdownEnter, NULL, NULL, "SHUTDOWN");
State stateSDS(sdsEnter, NULL, NULL, "SDS");
State stateLS(lsEnter, lsIdle, lsExit, "LS");
State stateNB(nbEnter, NULL, NULL, "NB");
@@ -249,10 +234,8 @@ void PowerFSM_setup()
// if we are a router node, we go to NB (no need for bluetooth) otherwise we go to DARK (so we can send message to phone)
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_WAKE_TIMER, NULL, "Wake timer");
// We need this transition, because we might not transition if we were waiting to enter light-sleep, because when we wake from
// light sleep we _always_ transition to NB or dark and
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_PACKET_FOR_PHONE, NULL,
"Received packet, exiting light sleep");
// We need this transition, because we might not transition if we were waiting to enter light-sleep, because when we wake from light sleep we _always_ transition to NB or dark and
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, exiting light sleep");
powerFSM.add_transition(&stateNB, &stateNB, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, resetting win wake");
// Handle press events - note: we ignore button presses when in API mode
@@ -272,14 +255,6 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateON, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
powerFSM.add_transition(&stateSERIAL, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
// Handle being told to power off
powerFSM.add_transition(&stateBOOT, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
powerFSM.add_transition(&stateLS, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
powerFSM.add_transition(&stateNB, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
powerFSM.add_transition(&stateDARK, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
powerFSM.add_transition(&stateON, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
powerFSM.add_transition(&stateSERIAL, &stateSHUTDOWN, EVENT_SHUTDOWN, NULL, "Shutdown");
powerFSM.add_transition(&stateDARK, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
powerFSM.add_transition(&stateON, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
@@ -337,23 +312,15 @@ void PowerFSM_setup()
#ifndef NRF52_SERIES
// We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
// See: https://github.com/meshtastic/Meshtastic-device/issues/1071
if (isRouter || radioConfig.preferences.is_power_saving) {
// I don't think this transition is correct, turning off for now - @geeksville
// powerFSM.add_timed_transition(&stateDARK, &stateNB, getPref_phone_timeout_secs() * 1000, NULL, "Phone timeout");
powerFSM.add_timed_transition(&stateNB, &stateLS, getPref_min_wake_secs() * 1000, NULL, "Min wake timeout");
powerFSM.add_timed_transition(&stateDARK, &stateLS, getPref_wait_bluetooth_secs() * 1000, NULL, "Bluetooth timeout");
meshSds = getPref_mesh_sds_timeout_secs();
} else {
meshSds = UINT32_MAX;
}
// I don't think this transition is correct, turning off for now - @geeksville
// powerFSM.add_timed_transition(&stateDARK, &stateNB, getPref_phone_timeout_secs() * 1000, NULL, "Phone timeout");
powerFSM.add_timed_transition(&stateNB, &stateLS, getPref_min_wake_secs() * 1000, NULL, "Min wake timeout");
powerFSM.add_timed_transition(&stateDARK, &stateLS, getPref_wait_bluetooth_secs() * 1000, NULL, "Bluetooth timeout");
meshSds = getPref_mesh_sds_timeout_secs();
#else
lowPowerState = &stateDARK;
meshSds = UINT32_MAX; // Workaround for now: Don't go into deep sleep on the RAK4631
meshSds = UINT32_MAX; //Workaround for now: Don't go into deep sleep on the RAK4631
#endif
if (meshSds != UINT32_MAX)

View File

@@ -19,7 +19,6 @@
#define EVENT_POWER_CONNECTED 13
#define EVENT_POWER_DISCONNECTED 14
#define EVENT_FIRMWARE_UPDATE 15 // We just received a new firmware update packet from the phone
#define EVENT_SHUTDOWN 16 //force a full shutdown now (not just sleep)
extern Fsm powerFSM;
extern State statePOWER, stateSERIAL;

View File

@@ -1,135 +1,107 @@
#include "airtime.h"
#include "NodeDB.h"
#include "configuration.h"
#include "airtime.h"
#define periodsToLog 48
AirTime *airTime;
// Don't read out of this directly. Use the helper functions.
uint32_t secondsPerPeriod = 3600;
uint32_t lastMillis = 0;
uint32_t secSinceBoot = 0;
// AirTime at;
// Don't read out of this directly. Use the helper functions.
struct airtimeStruct {
uint32_t periodTX[periodsToLog]; // AirTime transmitted
uint32_t periodRX[periodsToLog]; // AirTime received and repeated (Only valid mesh packets)
uint32_t periodRX_ALL[periodsToLog]; // AirTime received regardless of valid mesh packet. Could include noise.
uint8_t lastPeriodIndex;
} airtimes;
void AirTime::logAirtime(reportTypes reportType, uint32_t airtime_ms)
{
// TODO: Is the airtimes array still necessary? It's now in myNodeInfo anyway
if (reportType == TX_LOG) {
DEBUG_MSG("AirTime - Packet transmitted : %ums\n", airtime_ms);
this->airtimes.periodTX[0] = this->airtimes.periodTX[0] + airtime_ms;
myNodeInfo.air_period_tx[0] = myNodeInfo.air_period_tx[0] + airtime_ms;
airtimes.periodTX[0] = airtimes.periodTX[0] + airtime_ms;
} else if (reportType == RX_LOG) {
DEBUG_MSG("AirTime - Packet received : %ums\n", airtime_ms);
this->airtimes.periodRX[0] = this->airtimes.periodRX[0] + airtime_ms;
myNodeInfo.air_period_rx[0] = myNodeInfo.air_period_rx[0] + airtime_ms;
airtimes.periodRX[0] = airtimes.periodRX[0] + airtime_ms;
} else if (reportType == RX_ALL_LOG) {
DEBUG_MSG("AirTime - Packet received (noise?) : %ums\n", airtime_ms);
this->airtimes.periodRX_ALL[0] = this->airtimes.periodRX_ALL[0] + airtime_ms;
airtimes.periodRX_ALL[0] = airtimes.periodRX_ALL[0] + airtime_ms;
} else {
DEBUG_MSG("AirTime - Unknown report time. This should never happen!!\n");
}
uint8_t channelUtilPeriod = (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS;
this->channelUtilization[channelUtilPeriod] = channelUtilization[channelUtilPeriod] + airtime_ms;
}
uint8_t AirTime::currentPeriodIndex()
uint8_t currentPeriodIndex()
{
return ((getSecondsSinceBoot() / SECONDS_PER_PERIOD) % PERIODS_TO_LOG);
return ((getSecondsSinceBoot() / secondsPerPeriod) % periodsToLog);
}
void AirTime::airtimeRotatePeriod()
void airtimeRotatePeriod()
{
if (this->airtimes.lastPeriodIndex != currentPeriodIndex()) {
if (airtimes.lastPeriodIndex != currentPeriodIndex()) {
DEBUG_MSG("Rotating airtimes to a new period = %u\n", currentPeriodIndex());
for (int i = PERIODS_TO_LOG - 2; i >= 0; --i) {
this->airtimes.periodTX[i + 1] = this->airtimes.periodTX[i];
this->airtimes.periodRX[i + 1] = this->airtimes.periodRX[i];
this->airtimes.periodRX_ALL[i + 1] = this->airtimes.periodRX_ALL[i];
myNodeInfo.air_period_tx[i + 1] = myNodeInfo.air_period_tx[i];
myNodeInfo.air_period_rx[i + 1] = myNodeInfo.air_period_rx[i];
for (int i = periodsToLog - 2; i >= 0; --i) {
airtimes.periodTX[i + 1] = airtimes.periodTX[i];
airtimes.periodRX[i + 1] = airtimes.periodRX[i];
airtimes.periodRX_ALL[i + 1] = airtimes.periodRX_ALL[i];
}
this->airtimes.periodTX[0] = 0;
this->airtimes.periodRX[0] = 0;
this->airtimes.periodRX_ALL[0] = 0;
airtimes.periodTX[0] = 0;
airtimes.periodRX[0] = 0;
airtimes.periodRX_ALL[0] = 0;
myNodeInfo.air_period_tx[0] = 0;
myNodeInfo.air_period_rx[0] = 0;
this->airtimes.lastPeriodIndex = currentPeriodIndex();
airtimes.lastPeriodIndex = currentPeriodIndex();
}
}
uint32_t *AirTime::airtimeReport(reportTypes reportType)
uint32_t *airtimeReport(reportTypes reportType)
{
if (reportType == TX_LOG) {
return this->airtimes.periodTX;
return airtimes.periodTX;
} else if (reportType == RX_LOG) {
return this->airtimes.periodRX;
return airtimes.periodRX;
} else if (reportType == RX_ALL_LOG) {
return this->airtimes.periodRX_ALL;
return airtimes.periodRX_ALL;
}
return 0;
}
uint8_t AirTime::getPeriodsToLog()
uint8_t getPeriodsToLog()
{
return PERIODS_TO_LOG;
return periodsToLog;
}
uint32_t AirTime::getSecondsPerPeriod()
uint32_t getSecondsPerPeriod()
{
return SECONDS_PER_PERIOD;
return secondsPerPeriod;
}
uint32_t AirTime::getSecondsSinceBoot()
uint32_t getSecondsSinceBoot()
{
return this->secSinceBoot;
}
float AirTime::channelUtilizationPercent()
{
uint32_t sum = 0;
for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) {
sum += this->channelUtilization[i];
// DEBUG_MSG("ChanUtilArray %u %u\n", i, this->channelUtilization[i]);
}
return (float(sum) / float(CHANNEL_UTILIZATION_PERIODS * 10 * 1000)) * 100;
return secSinceBoot;
}
AirTime::AirTime() : concurrency::OSThread("AirTime") {}
int32_t AirTime::runOnce()
{
//DEBUG_MSG("AirTime::runOnce()\n");
airtimeRotatePeriod();
secSinceBoot++;
uint8_t utilPeriod = (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS;
if (firstTime) {
airtimeRotatePeriod();
for (uint32_t i = 0; i < CHANNEL_UTILIZATION_PERIODS; i++) {
this->channelUtilization[i] = 0;
}
firstTime = false;
lastUtilPeriod = utilPeriod;
} else {
// Reset the channelUtilization window when we roll over
if (lastUtilPeriod != utilPeriod) {
lastUtilPeriod = utilPeriod;
this->channelUtilization[utilPeriod] = 0;
}
// Update channel_utilization every second.
myNodeInfo.channel_utilization = airTime->channelUtilizationPercent();
}
/*
This actually doesn't need to be run once per second but we currently use it for the
secSinceBoot counter.
If we have a better counter of how long the device has been online (and not millis())
then we can change this to something less frequent. Maybe once ever 5 seconds?
*/
return (1000 * 1);
}

View File

@@ -23,18 +23,21 @@
RX_ALL_LOG - RX_LOG = Other lora radios on our frequency channel.
*/
#define CHANNEL_UTILIZATION_PERIODS 6
#define SECONDS_PER_PERIOD 3600
#define PERIODS_TO_LOG 24
enum reportTypes { TX_LOG, RX_LOG, RX_ALL_LOG };
void logAirtime(reportTypes reportType, uint32_t airtime_ms);
void airtimeRotatePeriod();
uint8_t currentPeriodIndex();
uint8_t getPeriodsToLog();
uint32_t getSecondsSinceBoot();
uint32_t *airtimeReport(reportTypes reportType);
uint32_t getSecondsPerPeriod();
class AirTime : private concurrency::OSThread
{
@@ -42,27 +45,6 @@ class AirTime : private concurrency::OSThread
AirTime();
void logAirtime(reportTypes reportType, uint32_t airtime_ms);
float channelUtilizationPercent();
uint32_t channelUtilization[CHANNEL_UTILIZATION_PERIODS];
uint8_t currentPeriodIndex();
void airtimeRotatePeriod();
uint8_t getPeriodsToLog();
uint32_t getSecondsPerPeriod();
uint32_t getSecondsSinceBoot();
uint32_t *airtimeReport(reportTypes reportType);
private:
bool firstTime = true;
uint8_t lastUtilPeriod = 0;
uint32_t secSinceBoot = 0;
struct airtimeStruct {
uint32_t periodTX[PERIODS_TO_LOG]; // AirTime transmitted
uint32_t periodRX[PERIODS_TO_LOG]; // AirTime received and repeated (Only valid mesh packets)
uint32_t periodRX_ALL[PERIODS_TO_LOG]; // AirTime received regardless of valid mesh packet. Could include noise.
uint8_t lastPeriodIndex;
} airtimes;
protected:
virtual int32_t runOnce() override;

View File

@@ -84,10 +84,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define BUTTON_PIN_ALT PIN_BUTTON2
#endif
#ifdef PIN_BUTTON_TOUCH
#define BUTTON_PIN_TOUCH PIN_BUTTON_TOUCH
#endif
// FIXME, use variant.h defs for all of this!!! (even on the ESP32 targets)
#elif defined(CubeCell_BoardPlus)
@@ -175,8 +171,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define I2C_SCL 22
#define BUTTON_PIN 38 // The middle button GPIO on the T-Beam
//#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented anywhere.
#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Plugin.
#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed
#define LED_INVERTED 1
#define LED_PIN 4 // Newer tbeams (1.1) have an extra led on GPIO4
@@ -218,7 +213,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define BUTTON_PIN 39
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Plugin.
#define USE_RF95
#define LORA_DIO0 26 // a No connect on the SX1262 module
@@ -247,8 +241,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
//#define GPS_TX_PIN 12 // not connected
#define BUTTON_PIN 39 // The middle button GPIO on the T-Beam
#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Plugin (#975).
#define LED_PIN 2 // add status LED (compatible with core-pcb and DIY targets)
#define LORA_DIO0 26 // a No connect on the SX1262/SX1268 module
#define LORA_RESET 23 // RST for SX1276, and for SX1262/SX1268
@@ -264,7 +256,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// supported modules list
#define USE_SX1262
#define USE_SX1268
#define USE_LLCC68
// common pinouts for SX126X modules
#define SX126X_CS 18 // NSS for SX126X
@@ -324,45 +315,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define HW_VENDOR HardwareModel_HELTEC_V2_1
#define BATTERY_PIN 37 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Plugin.
#endif
#elif defined(ARDUINO_HELTEC_WIFI_LORA_32)
// the default ESP32 Pin of 15 is the Oled SCL, set to 36 and 37 and works fine.
// Tested on Neo6m module.
#undef GPS_RX_PIN
#undef GPS_TX_PIN
#define GPS_RX_PIN 36
#define GPS_TX_PIN 37
#ifndef USE_JTAG // gpio15 is TDO for JTAG, so no I2C on this board while doing jtag
#define I2C_SDA 4 // I2C pins for this board
#define I2C_SCL 15
#endif
#define RESET_OLED 16 // If defined, this pin will be used to reset the display controller
#define LED_PIN 25 // If defined we will blink this LED
#define BUTTON_PIN 0 // If defined, this will be used for user button presses
#define USE_RF95
#define LORA_DIO0 26 // a No connect on the SX1262 module
#ifndef USE_JTAG
#define LORA_RESET 14
#endif
#define LORA_DIO1 33 // Not really used
#define LORA_DIO2 32 // Not really used
// ratio of voltage divider = 3.20 (R1=100k, R2=220k)
#define ADC_MULTIPLIER 3.2
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_HELTEC_V1
#define BATTERY_PIN 13 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#elif defined(TLORA_V1)
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR HardwareModel_TLORA_V1
@@ -380,7 +335,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define LED_PIN 2 // If defined we will blink this LED
#define BUTTON_PIN 0 // If defined, this will be used for user button presses
#define BUTTON_NEED_PULLUP
#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Plugin.
#define USE_RF95
#define LORA_DIO0 26 // a No connect on the SX1262 module

View File

@@ -43,8 +43,8 @@ void esp32Setup()
nvs_stats_t nvs_stats;
auto res = nvs_get_stats(NULL, &nvs_stats);
assert(res == ESP_OK);
DEBUG_MSG("NVS: UsedEntries %d, FreeEntries %d, AllEntries %d, NameSpaces %d\n", nvs_stats.used_entries, nvs_stats.free_entries,
nvs_stats.total_entries, nvs_stats.namespace_count);
DEBUG_MSG("NVS: UsedEntries %d, FreeEntries %d, AllEntries %d\n", nvs_stats.used_entries, nvs_stats.free_entries,
nvs_stats.total_entries);
DEBUG_MSG("Setup Preferences in Flash Storage\n");

View File

@@ -202,13 +202,11 @@ void GPS::publishUpdate()
if (shouldPublish) {
shouldPublish = false;
// In debug logs, identify position by @timestamp:stage (stage 2 = publish)
DEBUG_MSG("publishing pos@%x:2, hasVal=%d, GPSlock=%d\n",
p.pos_timestamp, hasValidLocation, hasLock());
DEBUG_MSG("publishing GPS lock=%d\n", hasLock());
// Notify any status instances that are observing us
const meshtastic::GPSStatus status =
meshtastic::GPSStatus(hasValidLocation, isConnected(), p);
meshtastic::GPSStatus(hasLock(), isConnected(), latitude, longitude, altitude, dop, heading, numSatellites);
newStatus.notifyObservers(&status);
}
}
@@ -246,7 +244,6 @@ int32_t GPS::runOnce()
bool gotLoc = lookForLocation();
if (gotLoc && !hasValidLocation) { // declare that we have location ASAP
DEBUG_MSG("hasValidLocation RISING EDGE\n");
hasValidLocation = true;
shouldPublish = true;
}
@@ -263,10 +260,6 @@ int32_t GPS::runOnce()
if (tooLong) {
// we didn't get a location during this ack window, therefore declare loss of lock
if (hasValidLocation) {
DEBUG_MSG("hasValidLocation FALLING EDGE (last read: %d)\n", gotLoc);
}
p = Position_init_default;
hasValidLocation = false;
}

View File

@@ -17,10 +17,6 @@ class GPS : private concurrency::OSThread
private:
uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastWhileActiveMsec = 0;
/**
* hasValidLocation - indicates that the position variables contain a complete
* GPS location, valid and fresh (< gps_update_interval + gps_attempt_time)
*/
bool hasValidLocation = false; // default to false, until we complete our first read
bool isAwake = false; // true if we want a location right now
@@ -43,7 +39,14 @@ class GPS : private concurrency::OSThread
/** If !0 we will attempt to connect to the GPS over I2C */
static uint8_t i2cAddress;
Position p = Position_init_default;
int32_t latitude = 0, longitude = 0; // as an int mult by 1e-7 to get value as double
int32_t altitude = 0;
uint32_t dop = 0; // Diminution of position; PDOP where possible (UBlox), HDOP otherwise (TinyGPS) in 10^2 units (needs
// scaling before use)
uint32_t heading = 0; // Heading of motion, in degrees * 10^-5
int32_t geoidal_height = 0; // geoidal separation, in meters!
time_t pos_timestamp = 0; // positional timestamp from GPS solution
GPS() : concurrency::OSThread("GPS") {}

View File

@@ -14,7 +14,7 @@
// Helper functions
// Raises a number to an exponent, handling negative exponents.
static inline double pow_neg(double base, double exponent) {
static double pow_neg(double base, double exponent) {
if (exponent == 0) {
return 1;
} else if (exponent > 0) {

View File

@@ -95,17 +95,6 @@ bool NMEAGPS::lookForLocation()
if (! hasLock())
return false;
#ifdef GPS_EXTRAVERBOSE
DEBUG_MSG("AGE: LOC=%d FIX=%d DATE=%d TIME=%d\n",
reader.location.age(),
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
gsafixtype.age(),
#else
0,
#endif
reader.date.age(), reader.time.age());
#endif // GPS_EXTRAVERBOSE
// check if a complete GPS solution set is available for reading
// tinyGPSDatum::age() also includes isValid() test
// FIXME
@@ -116,7 +105,7 @@ bool NMEAGPS::lookForLocation()
(reader.time.age() < GPS_SOL_EXPIRY_MS) &&
(reader.date.age() < GPS_SOL_EXPIRY_MS)))
{
DEBUG_MSG("SOME data is TOO OLD\n");
// DEBUG_MSG("SOME data is TOO OLD\n");
return false;
}
@@ -124,7 +113,7 @@ bool NMEAGPS::lookForLocation()
if (! reader.location.isUpdated())
return false;
// We know the solution is fresh and valid, so just read the data
// Start reading the data
auto loc = reader.location.value();
// Some GPSes (Air530) seem to send a zero longitude when the current fix is bogus
@@ -134,34 +123,27 @@ bool NMEAGPS::lookForLocation()
return false;
}
p.location_source = Position_LocSource_LOCSRC_GPS_INTERNAL;
// Dilution of precision (an accuracy metric) is reported in 10^2 units, so we need to scale down when we use it
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
p.HDOP = reader.hdop.value();
p.PDOP = TinyGPSPlus::parseDecimal(gsapdop.value());
DEBUG_MSG("PDOP=%d, HDOP=%d\n", dop, reader.hdop.value());
dop = TinyGPSPlus::parseDecimal(gsapdop.value());
#else
// FIXME! naive PDOP emulation (assumes VDOP==HDOP)
// correct formula is PDOP = SQRT(HDOP^2 + VDOP^2)
p.HDOP = reader.hdop.value();
p.PDOP = 1.41 * reader.hdop.value();
dop = 1.41 * reader.hdop.value();
#endif
// Discard incomplete or erroneous readings
if (reader.hdop.value() == 0)
if (dop == 0)
return false;
p.latitude_i = toDegInt(loc.lat);
p.longitude_i = toDegInt(loc.lng);
latitude = toDegInt(loc.lat);
longitude = toDegInt(loc.lng);
p.alt_geoid_sep = reader.geoidHeight.meters();
p.altitude_hae = reader.altitude.meters() + p.alt_geoid_sep;
p.altitude = reader.altitude.meters();
p.fix_quality = fixQual;
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
p.fix_type = fixType;
geoidal_height = reader.geoidHeight.meters();
#ifdef GPS_ALTITUDE_HAE
altitude = reader.altitude.meters() + geoidal_height;
#else
altitude = reader.altitude.meters();
#endif
// positional timestamp
@@ -173,16 +155,16 @@ bool NMEAGPS::lookForLocation()
t.tm_mon = reader.date.month() - 1;
t.tm_year = reader.date.year() - 1900;
t.tm_isdst = false;
p.pos_timestamp = mktime(&t);
pos_timestamp = mktime(&t);
// Nice to have, if available
if (reader.satellites.isUpdated()) {
p.sats_in_view = reader.satellites.value();
setNumSatellites(reader.satellites.value());
}
if (reader.course.isUpdated() && reader.course.isValid()) {
if (reader.course.value() < 36000) { // sanity check
p.ground_track = reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5
heading = reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5
} else {
DEBUG_MSG("BOGUS course.value() REJECTED: %d\n",
reader.course.value());

View File

@@ -11,11 +11,8 @@ enum RTCQuality {
/// Some other node gave us a time we can use
RTCQualityFromNet = 1,
/// Our time is based on NTP
RTCQualityNTP= 2,
/// Our time is based on our own GPS
RTCQualityGPS = 3
RTCQualityGPS = 2
};
RTCQuality getRTCQuality();

View File

@@ -10,8 +10,6 @@
#define PDOP_INVALID 9999
// #define UBX_MODE_NMEA
extern RadioConfig radioConfig;
UBloxGPS::UBloxGPS() {}
@@ -50,22 +48,12 @@ bool UBloxGPS::setupGPS()
delay(500);
if (isConnected()) {
#ifdef UBX_MODE_NMEA
DEBUG_MSG("Connected to UBLOX GPS, downgrading to NMEA mode\n");
DEBUG_MSG("- GPS errors below are related and safe to ignore\n");
#else
DEBUG_MSG("Connected to UBLOX GPS successfully\n");
#endif
if (!setUBXMode())
RECORD_CRITICALERROR(CriticalErrorCode_UBloxInitFailed); // Don't halt the boot if saving the config fails, but do report the bug
#ifdef UBX_MODE_NMEA
return false;
#else
return true;
#endif
} else {
return false;
}
@@ -73,17 +61,6 @@ bool UBloxGPS::setupGPS()
bool UBloxGPS::setUBXMode()
{
#ifdef UBX_MODE_NMEA
if (_serial_gps) {
ublox.setUART1Output(COM_TYPE_NMEA, 1000);
}
if (i2cAddress) {
ublox.setI2COutput(COM_TYPE_NMEA, 1000);
}
return false; // pretend initialization failed to force NMEA mode
#endif
if (_serial_gps) {
if (!ublox.setUART1Output(COM_TYPE_UBX, 1000)) // Use native API
return false;
@@ -142,6 +119,7 @@ bool UBloxGPS::factoryReset()
void UBloxGPS::whileActive()
{
ublox.flushPVT(); // reset ALL freshness flags first
ublox.getT(maxWait()); // ask for new time data - hopefully ready when we come back
// Ask for a new position fix - hopefully it will have results ready by next time
@@ -192,29 +170,25 @@ bool UBloxGPS::lookForLocation()
{
bool foundLocation = false;
// check if a complete GPS solution set is available for reading
// (some of these, like lat/lon are redundant and can be removed)
if ( ! (ublox.moduleQueried.fixType &&
ublox.moduleQueried.latitude &&
ublox.moduleQueried.longitude &&
ublox.moduleQueried.altitude &&
ublox.moduleQueried.pDOP &&
ublox.moduleQueried.SIV &&
ublox.moduleQueried.gpsDay))
{
// Not ready? No problem! We'll try again later.
return false;
// catch fixType changes here, instead of whileActive()
if (ublox.moduleQueried.fixType) {
fixType = ublox.getFixType();
}
fixType = ublox.getFixType();
#ifdef UBLOX_EXTRAVERBOSE
DEBUG_MSG("FixType=%d\n", fixType);
#endif
// check if GPS has an acceptable lock
if (! hasLock()) {
ublox.flushPVT(); // reset ALL freshness flags
return false;
}
// check if a complete GPS solution set is available for reading
// (some of these, like lat/lon are redundant and can be removed)
if ( ! (ublox.moduleQueried.latitude &&
ublox.moduleQueried.longitude &&
ublox.moduleQueried.altitude &&
ublox.moduleQueried.pDOP &&
ublox.moduleQueried.gpsiTOW))
{
// Not ready? No problem! We'll try again later.
return false;
}
@@ -225,10 +199,6 @@ bool UBloxGPS::lookForLocation()
int32_t tmp_lon = ublox.getLongitude(0);
int32_t tmp_alt_msl = ublox.getAltitudeMSL(0);
int32_t tmp_alt_hae = ublox.getAltitude(0);
int32_t max_dop = PDOP_INVALID;
if (radioConfig.preferences.gps_max_dop)
max_dop = radioConfig.preferences.gps_max_dop * 100; // scaling
// Note: heading is only currently implmented in the ublox for the 8m chipset - therefore
// don't read it here - it will generate an ignored getPVT command on the 6ms
// heading = ublox.getHeading(0);
@@ -245,55 +215,41 @@ bool UBloxGPS::lookForLocation()
time_t tmp_ts = mktime(&t);
// FIXME - can opportunistically attempt to set RTC from GPS timestamp?
// SIV number is nice-to-have if it's available
if (ublox.moduleQueried.SIV) {
uint16_t gSIV = ublox.getSIV(0);
setNumSatellites(gSIV);
}
// bogus lat lon is reported as 0 or 0 (can be bogus just for one)
// Also: apparently when the GPS is initially reporting lock it can output a bogus latitude > 90 deg!
// FIXME - NULL ISLAND is a real location on Earth!
foundLocation = (tmp_lat != 0) && (tmp_lon != 0) &&
(tmp_lat <= 900000000) && (tmp_lat >= -900000000) &&
(tmp_dop < max_dop);
(tmp_dop < PDOP_INVALID);
// only if entire dataset is valid, update globals from temp vars
if (foundLocation) {
p.location_source = Position_LocSource_LOCSRC_GPS_INTERNAL;
p.longitude_i = tmp_lon;
p.latitude_i = tmp_lat;
if (fixType > 2) {
// if fix is 2d, ignore altitude data
p.altitude = tmp_alt_msl / 1000;
p.altitude_hae = tmp_alt_hae / 1000;
p.alt_geoid_sep = (tmp_alt_hae - tmp_alt_msl) / 1000;
} else {
#ifdef GPS_EXTRAVERBOSE
DEBUG_MSG("no altitude data (fixType=%d)\n", fixType);
longitude = tmp_lon;
latitude = tmp_lat;
#ifdef GPS_ALTITUDE_HAE
altitude = tmp_alt_hae / 1000;
#else
altitude = tmp_alt_msl / 1000;
#endif
// clean up old values in case it's a 3d-2d fix transition
p.altitude = p.altitude_hae = p.alt_geoid_sep = 0;
}
p.pos_timestamp = tmp_ts;
p.PDOP = tmp_dop;
p.fix_type = fixType;
p.sats_in_view = ublox.getSIV(0);
// In debug logs, identify position by @timestamp:stage (stage 1 = birth)
DEBUG_MSG("lookForLocation() new pos@%x:1\n", tmp_ts);
geoidal_height = (tmp_alt_hae - tmp_alt_msl) / 1000;
pos_timestamp = tmp_ts;
dop = tmp_dop;
} else {
// INVALID solution - should never happen
DEBUG_MSG("Invalid location lat/lon/hae/dop %d/%d/%d/%d - discarded\n",
tmp_lat, tmp_lon, tmp_alt_hae, tmp_dop);
DEBUG_MSG("Invalid location discarded\n");
}
ublox.flushPVT(); // reset ALL freshness flags at the end
return foundLocation;
}
bool UBloxGPS::hasLock()
{
if (radioConfig.preferences.gps_accept_2d)
return (fixType >= 2 && fixType <= 4);
else
return (fixType >= 3 && fixType <= 4);
return (fixType >= 3 && fixType <= 4);
}
bool UBloxGPS::whileIdle()

View File

@@ -27,19 +27,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "NodeDB.h"
#include "Screen.h"
#include "fonts.h"
#include "gps/GeoCoord.h"
#include "gps/RTC.h"
#include "graphics/images.h"
#include "main.h"
#include "mesh-pb-constants.h"
#include "mesh/Channels.h"
#include "plugins/TextMessagePlugin.h"
#include "sleep.h"
#include "target_specific.h"
#include "utils.h"
#include "gps/GeoCoord.h"
#ifndef NO_ESP32
#include "esp_task_wdt.h"
#include "mesh/http/WiFiAPClient.h"
#endif
@@ -149,26 +147,6 @@ static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int1
drawIconScreen(region, display, state, x, y);
}
// Used on boot when a certificate is being created
static void drawSSLScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_SMALL);
display->drawString(64 + x, y, "Creating SSL certificate");
#ifndef NO_ESP32
yield();
esp_task_wdt_reset();
#endif
display->setFont(FONT_SMALL);
if ((millis() / 1000) % 2) {
display->drawString(64 + x, FONT_HEIGHT_SMALL + y + 2, "Please wait . . .");
} else {
display->drawString(64 + x, FONT_HEIGHT_SMALL + y + 2, "Please wait . . ");
}
}
#ifdef HAS_EINK
/// Used on eink displays while in deep sleep
static void drawSleepScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
@@ -226,11 +204,7 @@ static void drawFrameFirmware(OLEDDisplay *display, OLEDDisplayUiState *state, i
display->drawString(64 + x, y, "Updating");
display->setFont(FONT_SMALL);
if ((millis() / 1000) % 2) {
display->drawString(64 + x, FONT_HEIGHT_SMALL + y + 2, "Please wait . . .");
} else {
display->drawString(64 + x, FONT_HEIGHT_SMALL + y + 2, "Please wait . . ");
}
display->drawString(64 + x, FONT_HEIGHT_SMALL + y + 2, "Please wait...");
// display->setFont(FONT_LARGE);
// display->drawString(64 + x, 26 + y, btPIN);
@@ -252,13 +226,6 @@ static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *sta
display->drawString(0 + x, FONT_HEIGHT_MEDIUM + y, "For help, please post on\nmeshtastic.discourse.group");
}
// Ignore messages orginating from phone (from the current node 0x0) unless range test or store and forward plugin are enabled
static bool shouldDrawMessage(const MeshPacket *packet)
{
return packet->from != 0 && !radioConfig.preferences.range_test_plugin_enabled &&
!radioConfig.preferences.store_forward_plugin_enabled;
}
/// Draw the last text message we received
static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
@@ -435,7 +402,6 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const
displayLine = "No GPS Lock";
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
} else {
if (gpsFormat != GpsCoordinateFormat_GpsFormatDMS) {
char coordinateLine[22];
geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude()));
@@ -445,36 +411,25 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const
sprintf(coordinateLine, "%2i%1c %06i %07i", geoCoord.getUTMZone(), geoCoord.getUTMBand(),
geoCoord.getUTMEasting(), geoCoord.getUTMNorthing());
} else if (gpsFormat == GpsCoordinateFormat_GpsFormatMGRS) { // Military Grid Reference System
sprintf(coordinateLine, "%2i%1c %1c%1c %05i %05i", geoCoord.getMGRSZone(), geoCoord.getMGRSBand(),
geoCoord.getMGRSEast100k(), geoCoord.getMGRSNorth100k(), geoCoord.getMGRSEasting(),
geoCoord.getMGRSNorthing());
sprintf(coordinateLine, "%2i%1c %1c%1c %05i %05i", geoCoord.getMGRSZone(), geoCoord.getMGRSBand(), geoCoord.getMGRSEast100k(),
geoCoord.getMGRSNorth100k(), geoCoord.getMGRSEasting(), geoCoord.getMGRSNorthing());
} else if (gpsFormat == GpsCoordinateFormat_GpsFormatOLC) { // Open Location Code
geoCoord.getOLCCode(coordinateLine);
} else if (gpsFormat == GpsCoordinateFormat_GpsFormatOSGR) { // Ordnance Survey Grid Reference
} else if (gpsFormat == GpsCoordinateFormat_GpsFormatOSGR) { // Ordnance Survey Grid Reference
if (geoCoord.getOSGRE100k() == 'I' || geoCoord.getOSGRN100k() == 'I') // OSGR is only valid around the UK region
sprintf(coordinateLine, "%s", "Out of Boundary");
else
sprintf(coordinateLine, "%1c%1c %05i %05i", geoCoord.getOSGRE100k(), geoCoord.getOSGRN100k(),
sprintf(coordinateLine, "%1c%1c %05i %05i", geoCoord.getOSGRE100k(),geoCoord.getOSGRN100k(),
geoCoord.getOSGREasting(), geoCoord.getOSGRNorthing());
}
// If fixed position, display text "Fixed GPS" alternating with the coordinates.
if (radioConfig.preferences.fixed_position) {
if ((millis() / 10000) % 2) {
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(coordinateLine))) / 2, y, coordinateLine);
} else {
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth("Fixed GPS"))) / 2, y, "Fixed GPS");
}
} else {
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(coordinateLine))) / 2, y, coordinateLine);
}
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(coordinateLine))) / 2, y, coordinateLine);
} else {
char latLine[22];
char lonLine[22];
sprintf(latLine, "%2i° %2i' %2.4f\" %1c", geoCoord.getDMSLatDeg(), geoCoord.getDMSLatMin(), geoCoord.getDMSLatSec(),
geoCoord.getDMSLatCP());
sprintf(lonLine, "%3i° %2i' %2.4f\" %1c", geoCoord.getDMSLonDeg(), geoCoord.getDMSLonMin(), geoCoord.getDMSLonSec(),
sprintf(lonLine, "%3i° %2i' %2.4f\" %1c", geoCoord.getDMSLonDeg(), geoCoord.getDMSLonMin(), geoCoord.getDMSLonSec(),
geoCoord.getDMSLonCP());
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(latLine))) / 2, y - FONT_HEIGHT_SMALL * 1, latLine);
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(lonLine))) / 2, y, lonLine);
@@ -619,6 +574,11 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
n = nodeDB.getNodeByIndex(nodeIndex);
}
displayedNodeNum = n->num;
// We just changed to a new node screen, ask that node for updated state if it's older than 2 minutes
if (sinceLastSeen(n) > 120) {
service.sendNetworkPing(displayedNodeNum, true);
}
}
NodeInfo *node = nodeDB.getNodeByIndex(nodeIndex);
@@ -661,8 +621,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
// display direction toward node
hasNodeHeading = true;
Position &p = node->position;
float d =
GeoCoord::latLongToMeter(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
float d = GeoCoord::latLongToMeter(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
if (d < 2000)
snprintf(distStr, sizeof(distStr), "%.0f m", d);
else
@@ -670,8 +629,7 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
// FIXME, also keep the guess at the operators heading and add/substract
// it. currently we don't do this and instead draw north up only.
float bearingToOther =
GeoCoord::bearing(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
float bearingToOther = GeoCoord::bearing(DegD(p.latitude_i), DegD(p.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
headingRadian = bearingToOther - myHeading;
drawNodeHeading(display, compassX, compassY, headingRadian);
}
@@ -712,7 +670,6 @@ void _screen_header()
Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue(32), dispdev(address, sda, scl), ui(&dispdev)
{
address_found = address;
cmdQueue.setReader(this);
}
@@ -830,8 +787,6 @@ void Screen::forceDisplay()
#endif
}
static uint32_t lastScreenTransition;
int32_t Screen::runOnce()
{
// If we don't have a screen, don't ever spend any CPU for us.
@@ -900,11 +855,6 @@ int32_t Screen::runOnce()
// oldFrameState = ui.getUiState()->frameState;
DEBUG_MSG("Setting idle framerate\n");
targetFramerate = IDLE_FRAMERATE;
#ifndef NO_ESP32
setCPUFast(false); // Turn up the CPU to improve screen animations
#endif
ui.setTargetFPS(targetFramerate);
forceDisplay();
}
@@ -913,11 +863,6 @@ int32_t Screen::runOnce()
// standard screen switching is stopped.
if (showingNormalScreen) {
// standard screen loop handling here
if (radioConfig.preferences.auto_screen_carousel_secs > 0 &&
(millis() - lastScreenTransition) > (radioConfig.preferences.auto_screen_carousel_secs * 1000)) {
DEBUG_MSG("LastScreenTransition exceeded %ums transitioning to next frame\n", (millis() - lastScreenTransition));
handleOnPress();
}
}
// DEBUG_MSG("want fps %d, fixed=%d\n", targetFramerate,
@@ -946,18 +891,6 @@ void Screen::drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiStat
screen->debugInfo.drawFrameWiFi(display, state, x, y);
}
/* show a message that the SSL cert is being built
* it is expected that this will be used during the boot phase */
void Screen::setSSLFrames()
{
if (address_found) {
// DEBUG_MSG("showing SSL frames\n");
static FrameCallback sslFrames[] = {drawSSLScreen};
ui.setFrames(sslFrames, 1);
ui.update();
}
}
// restore our regular frame list
void Screen::setFrames()
{
@@ -992,10 +925,9 @@ void Screen::setFrames()
if (myNodeInfo.error_code)
normalFrames[numframes++] = drawCriticalFaultFrame;
// If we have a text message - show it next, unless it's a phone message and we aren't using any special plugins
if (devicestate.has_rx_text_message && shouldDrawMessage(&devicestate.rx_text_message)) {
// If we have a text message - show it next
if (devicestate.has_rx_text_message)
normalFrames[numframes++] = drawTextMessageFrame;
}
// then all the nodes
// We only show a few nodes in our scrolling list - because meshes with many nodes would have too many screens
@@ -1090,8 +1022,7 @@ void Screen::handleOnPress()
// If we are in a transition, the press must have bounced, drop it.
if (ui.getUiState()->frameState == FIXED) {
ui.nextFrame();
DEBUG_MSG("Setting LastScreenTransition\n");
lastScreenTransition = millis();
setFastFramerate();
}
}
@@ -1106,11 +1037,6 @@ void Screen::setFastFramerate()
// We are about to start a transition so speed up fps
targetFramerate = SCREEN_TRANSITION_FRAMERATE;
#ifndef NO_ESP32
setCPUFast(true); // Turn up the CPU to improve screen animations
#endif
ui.setTargetFPS(targetFramerate);
setInterval(0); // redraw ASAP
runASAP = true;
@@ -1202,7 +1128,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
if (radioConfig.preferences.wifi_ap_mode || isSoftAPForced()) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.softAPIP().toString().c_str()));
// Number of connections to the AP. Default max for the esp32 is 4
// Number of connections to the AP. Default mmax for the esp32 is 4
display->drawString(x + SCREEN_WIDTH - display->getStringWidth("(" + String(WiFi.softAPgetStationNum()) + "/4)"),
y + FONT_HEIGHT_SMALL * 1, "(" + String(WiFi.softAPgetStationNum()) + "/4)");
} else {
@@ -1336,24 +1262,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
display->drawString(x, y, String("USB"));
}
auto mode = "";
if (channels.getPrimary().modem_config == 0) {
mode = "ShrtSlow";
} else if (channels.getPrimary().modem_config == 1) {
mode = "ShrtFast";
} else if (channels.getPrimary().modem_config == 2) {
mode = "LngFast";
} else if (channels.getPrimary().modem_config == 3) {
mode = "LngSlow";
} else if (channels.getPrimary().modem_config == 4) {
mode = "MedSlow";
} else if (channels.getPrimary().modem_config == 5) {
mode = "MedFast";
} else {
mode = "Custom";
}
auto mode = "Mode " + String(channels.getPrimary().modem_config);
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode), y, mode);
// Line 2
@@ -1398,11 +1307,11 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, uptime);
// Display Channel Utilization
char chUtil[13];
sprintf(chUtil, "ChUtil %2.0f%%", airTime->channelUtilizationPercent());
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil),
y + FONT_HEIGHT_SMALL * 1, chUtil);
#ifndef NO_ESP32
// Show CPU Frequency.
display->drawString(x + SCREEN_WIDTH - display->getStringWidth("CPU " + String(getCpuFrequencyMhz()) + "MHz"),
y + FONT_HEIGHT_SMALL * 1, "CPU " + String(getCpuFrequencyMhz()) + "MHz");
#endif
// Line 3
if (radioConfig.preferences.gps_format != GpsCoordinateFormat_GpsFormatDMS) // if DMS then don't draw altitude
@@ -1448,7 +1357,7 @@ int Screen::handleStatusUpdate(const meshtastic::Status *arg)
return 0;
}
int Screen::handleTextMessage(const MeshPacket *packet)
int Screen::handleTextMessage(const MeshPacket *arg)
{
if (showingNormalScreen) {
setFrames(); // Regen the list of screens (will show new text message)

View File

@@ -97,8 +97,6 @@ class Screen : public concurrency::OSThread
Screen(const Screen &) = delete;
Screen &operator=(const Screen &) = delete;
uint8_t address_found;
/// Initializes the UI, turns on the display, starts showing boot screen.
//
// Not thread safe - must be called before any other methods are called.
@@ -222,9 +220,6 @@ class Screen : public concurrency::OSThread
/// Used to force (super slow) eink displays to draw critical frames
void forceDisplay();
/// Draws our SSL cert screen during boot (called from WebServer)
void setSSLFrames();
protected:
/// Updates the UI.
//

View File

@@ -40,7 +40,6 @@
#include "RF95Interface.h"
#include "SX1262Interface.h"
#include "SX1268Interface.h"
#include "LLCC68Interface.h"
#ifdef NRF52_SERIES
#include "variant.h"
@@ -134,8 +133,6 @@ static int32_t ledBlinker()
return powerStatus->getIsCharging() ? 1000 : (ledOn ? 1 : 1000);
}
uint32_t timeLastPowered = 0;
/// Wrapper to convert our powerFSM stuff into a 'thread'
class PowerFSMThread : public OSThread
{
@@ -153,13 +150,6 @@ class PowerFSMThread : public OSThread
auto state = powerFSM.getState();
canSleep = (state != &statePOWER) && (state != &stateSERIAL);
if (powerStatus->getHasUSB()) {
timeLastPowered = millis();
} else if (radioConfig.preferences.on_battery_shutdown_after_secs > 0 &&
millis() > timeLastPowered + (1000 * radioConfig.preferences.on_battery_shutdown_after_secs)) { //shutdown after 30 minutes unpowered
powerFSM.trigger(EVENT_SHUTDOWN);
}
return 10;
}
};
@@ -187,9 +177,6 @@ class ButtonThread : public OSThread
#endif
#ifdef BUTTON_PIN_ALT
OneButton userButtonAlt;
#endif
#ifdef BUTTON_PIN_TOUCH
OneButton userButtonTouch;
#endif
static bool shutdown_on_long_stop;
@@ -208,7 +195,6 @@ class ButtonThread : public OSThread
userButton.attachClick(userButtonPressed);
userButton.attachDuringLongPress(userButtonPressedLong);
userButton.attachDoubleClick(userButtonDoublePressed);
userButton.attachMultiClick(userButtonMultiPressed);
userButton.attachLongPressStart(userButtonPressedLongStart);
userButton.attachLongPressStop(userButtonPressedLongStop);
wakeOnIrq(BUTTON_PIN, FALLING);
@@ -226,21 +212,6 @@ class ButtonThread : public OSThread
userButtonAlt.attachLongPressStop(userButtonPressedLongStop);
wakeOnIrq(BUTTON_PIN_ALT, FALLING);
#endif
#ifdef BUTTON_PIN_TOUCH
userButtonTouch = OneButton(BUTTON_PIN_TOUCH, true, true);
#ifdef INPUT_PULLUP_SENSE
// Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did
pinMode(BUTTON_PIN_TOUCH, INPUT_PULLUP_SENSE);
#endif
userButtonTouch.attachClick(touchPressed);
userButtonTouch.attachDuringLongPress(touchPressedLong);
userButtonTouch.attachDoubleClick(touchDoublePressed);
userButtonTouch.attachLongPressStart(touchPressedLongStart);
userButtonTouch.attachLongPressStop(touchPressedLongStop);
wakeOnIrq(BUTTON_PIN_TOUCH, FALLING);
#endif
}
protected:
@@ -256,10 +227,6 @@ class ButtonThread : public OSThread
#ifdef BUTTON_PIN_ALT
userButtonAlt.tick();
canSleep &= userButtonAlt.isIdle();
#endif
#ifdef BUTTON_PIN_TOUCH
userButtonTouch.tick();
canSleep &= userButtonTouch.isIdle();
#endif
// if (!canSleep) DEBUG_MSG("Supressing sleep!\n");
// else DEBUG_MSG("sleep ok\n");
@@ -268,33 +235,6 @@ class ButtonThread : public OSThread
}
private:
static void touchPressed()
{
screen->forceDisplay();
DEBUG_MSG("touch press!\n");
}
static void touchDoublePressed()
{
DEBUG_MSG("touch double press!\n");
}
static void touchPressedLong()
{
DEBUG_MSG("touch press long!\n");
}
static void touchDoublePressedLong()
{
DEBUG_MSG("touch double pressed!\n");
}
static void touchPressedLongStart()
{
DEBUG_MSG("touch long press start!\n");
}
static void touchPressedLongStop()
{
DEBUG_MSG("touch long press stop!\n");
}
static void userButtonPressed()
{
// DEBUG_MSG("press!\n");
@@ -332,19 +272,9 @@ class ButtonThread : public OSThread
{
#ifndef NO_ESP32
disablePin();
#elif defined(HAS_EINK)
digitalWrite(PIN_EINK_EN,digitalRead(PIN_EINK_EN) == LOW);
#endif
}
static void userButtonMultiPressed()
{
#ifndef NO_ESP32
clearNVS();
#endif
}
static void userButtonPressedLongStart()
{
DEBUG_MSG("Long press start!\n");
@@ -397,8 +327,6 @@ void setup()
}
#endif
DEBUG_MSG("\n\n//\\ E S H T /\\ S T / C\n\n");
initDeepSleep();
#ifdef VEXT_ENABLE
@@ -611,19 +539,6 @@ void setup()
}
#endif
#if defined(USE_LLCC68)
if (!rIf) {
rIf = new LLCC68Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI);
if (!rIf->init()) {
DEBUG_MSG("Warning: Failed to find LLCC68 radio\n");
delete rIf;
rIf = NULL;
} else {
DEBUG_MSG("LLCC68 Radio init succeeded, using LLCC68 radio\n");
}
}
#endif
#ifdef USE_SIM_RADIO
if (!rIf) {
rIf = new SimRadio;
@@ -661,14 +576,6 @@ void setup()
else
router->addInterface(rIf);
// Calculate and save the bit rate to myNodeInfo
// TODO: This needs to be added what ever method changes the channel from the phone.
myNodeInfo.bitrate = (float(Constants_DATA_PAYLOAD_LEN) /
(float(rIf->getPacketTime(Constants_DATA_PAYLOAD_LEN)))
) * 1000;
DEBUG_MSG("myNodeInfo.bitrate = %f bytes / sec\n", myNodeInfo.bitrate);
// This must be _after_ service.init because we need our preferences loaded from flash to have proper timeout values
PowerFSM_setup(); // we will transition to ON in a couple of seconds, FIXME, only do this for cold boots, not waking from SDS
powerFSMthread = new PowerFSMThread();

View File

@@ -217,23 +217,17 @@ const char *Channels::getName(size_t chIndex)
else
switch (channelSettings.modem_config) {
case ChannelSettings_ModemConfig_Bw125Cr45Sf128:
channelName = "ShortSlow";
channelName = "Medium";
break;
case ChannelSettings_ModemConfig_Bw500Cr45Sf128:
channelName = "ShortFast";
break;
case ChannelSettings_ModemConfig_Bw31_25Cr48Sf512:
channelName = "LongFast";
channelName = "LongAlt";
break;
case ChannelSettings_ModemConfig_Bw125Cr48Sf4096:
channelName = "LongSlow";
break;
case ChannelSettings_ModemConfig_Bw250Cr46Sf2048:
channelName = "MediumSlow";
break;
case ChannelSettings_ModemConfig_Bw250Cr47Sf1024:
channelName = "MediumFast";
break;
default:
channelName = "Invalid";
break;

View File

@@ -17,7 +17,7 @@ ErrorCode FloodingRouter::send(MeshPacket *p)
return Router::send(p);
}
bool FloodingRouter::shouldFilterReceived(MeshPacket *p)
bool FloodingRouter::shouldFilterReceived(const MeshPacket *p)
{
if (wasSeenRecently(p)) { // Note: this will also add a recent packet record
printPacket("Ignoring incoming msg, because we've already seen it", p);

View File

@@ -50,7 +50,7 @@ class FloodingRouter : public Router, protected PacketHistory
* Called immedately on receiption, before any further processing.
* @return true to abandon the packet
*/
virtual bool shouldFilterReceived(MeshPacket *p);
virtual bool shouldFilterReceived(const MeshPacket *p);
/**
* Look for broadcasts we need to rebroadcast

View File

@@ -3,5 +3,4 @@
// We need this declaration for proper linking in derived classes
template class SX126xInterface<SX1262>;
template class SX126xInterface<SX1268>;
template class SX126xInterface<LLCC68>;
template class SX126xInterface<SX1268>;

View File

@@ -1,9 +0,0 @@
#include "configuration.h"
#include "LLCC68Interface.h"
#include "error.h"
LLCC68Interface::LLCC68Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
SPIClass &spi)
: SX126xInterface(cs, irq, rst, busy, spi)
{
}

View File

@@ -1,17 +0,0 @@
#pragma once
#include "SX126xInterface.h"
/**
* Our adapter for LLCC68 radios
* https://www.semtech.com/products/wireless-rf/lora-core/llcc68
* ⚠️⚠️⚠️
* Be aware that LLCC68 does not support Spreading Factor 12 (SF12) and will not work on the default "Long Slow" channel.
* You must change the channel if you get `Critical Error #3` with this module.
* ⚠️⚠️⚠️
*/
class LLCC68Interface : public SX126xInterface<LLCC68>
{
public:
LLCC68Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
};

View File

@@ -96,7 +96,7 @@ void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src)
assert(!pi.myReply); // If it is !null it means we have a bug, because it should have been sent the previous time
if (wantsPacket) {
DEBUG_MSG("Plugin '%s' wantsPacket=%d\n", pi.name, wantsPacket);
DEBUG_MSG("Plugin %s wantsPacket=%d\n", pi.name, wantsPacket);
pluginFound = true;
@@ -109,10 +109,7 @@ void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src)
/// Also: if a packet comes in on the local PC interface, we don't check for bound channels, because it is TRUSTED and it needs to
/// to be able to fetch the initial admin packets without yet knowing any channels.
bool rxChannelOk = !pi.boundChannel || (mp.from == 0) ||
!ch ||
strlen(ch->settings.name) > 0 ||
strcmp(ch->settings.name, pi.boundChannel);
bool rxChannelOk = !pi.boundChannel || (mp.from == 0) || (ch && (strcmp(ch->settings.name, pi.boundChannel) == 0));
if (!rxChannelOk) {
// no one should have already replied!
@@ -137,9 +134,9 @@ void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src)
// any other node.
if (mp.decoded.want_response && toUs && (getFrom(&mp) != ourNodeNum || mp.to == ourNodeNum) && !currentReply) {
pi.sendResponse(mp);
DEBUG_MSG("Plugin '%s' sent a response\n", pi.name);
DEBUG_MSG("Plugin %s sent a response\n", pi.name);
} else {
DEBUG_MSG("Plugin '%s' considered\n", pi.name);
DEBUG_MSG("Plugin %s considered\n", pi.name);
}
// If the requester didn't ask for a response we might need to discard unused replies to prevent memory leaks
@@ -150,7 +147,7 @@ void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src)
}
if (handled == ProcessMessage::STOP) {
DEBUG_MSG("Plugin '%s' handled and skipped other processing\n", pi.name);
DEBUG_MSG("Plugin %s handled and skipped other processing\n", pi.name);
break;
}
}

View File

@@ -112,11 +112,7 @@ bool MeshService::reloadConfig()
/// The owner User record just got updated, update our node DB and broadcast the info into the mesh
void MeshService::reloadOwner()
{
// DEBUG_MSG("reloadOwner()\n");
// update our local data directly
nodeDB.updateUser(nodeDB.getNodeNum(), owner);
assert(nodeInfoPlugin);
// update everyone else
if (nodeInfoPlugin)
nodeInfoPlugin->sendOurNodeInfo();
nodeDB.saveToDisk();
@@ -144,7 +140,7 @@ void MeshService::handleToRadio(MeshPacket &p)
// Send the packet into the mesh
sendToMesh(packetPool.allocCopy(p), RX_SRC_USER);
sendToMesh(packetPool.allocCopy(p));
bool loopback = false; // if true send any packet the phone sends back itself (for testing)
if (loopback) {
@@ -161,12 +157,12 @@ bool MeshService::cancelSending(PacketId id)
return router->cancelSending(nodeDB.getNodeNum(), id);
}
void MeshService::sendToMesh(MeshPacket *p, RxSource src)
void MeshService::sendToMesh(MeshPacket *p)
{
nodeDB.updateFrom(*p); // update our local DB for this packet (because phone might have sent position packets etc...)
// Note: We might return !OK if our fifo was full, at that point the only option we have is to drop it
router->sendLocal(p, src);
router->sendLocal(p);
}
void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
@@ -213,39 +209,34 @@ NodeInfo *MeshService::refreshMyNodeInfo()
return node;
}
int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
int MeshService::onGPSChanged(const meshtastic::GPSStatus *unused)
{
// Update our local node info with our position (even if we don't decide to update anyone else)
NodeInfo *node = refreshMyNodeInfo();
Position pos = Position_init_default;
Position pos = node->position;
if (newStatus->getHasLock()) {
// load data from GPS object, will add timestamp + battery further down
pos = gps->p;
if (gps->hasLock()) {
if (gps->altitude != 0)
pos.altitude = gps->altitude;
pos.latitude_i = gps->latitude;
pos.longitude_i = gps->longitude;
} else {
// The GPS has lost lock, if we are fixed position we should just keep using
// the old position
#if GPS_EXTRAVERBOSE
DEBUG_MSG("onGPSchanged() - lost validLocation\n");
#endif
if (radioConfig.preferences.fixed_position) {
DEBUG_MSG("WARNING: Using fixed position\n");
pos = node->position;
} else {
// throw away old position
pos.latitude_i = 0;
pos.longitude_i = 0;
pos.altitude = 0;
}
}
// Finally add a fresh timestamp and battery level reading
// I KNOW this is redundant with refreshMyNodeInfo() above, but these are
// inexpensive nonblocking calls and can be refactored in due course
pos.time = getValidTime(RTCQualityGPS);
pos.battery_level = powerStatus->getBatteryChargePercent();
// In debug logs, identify position by @timestamp:stage (stage 4 = nodeDB)
DEBUG_MSG("onGPSChanged() pos@%x:4, time=%u, lat=%d, bat=%d\n",
pos.pos_timestamp, pos.time, pos.latitude_i, pos.battery_level);
DEBUG_MSG("got gps notify time=%u, lat=%d, bat=%d\n", pos.time, pos.latitude_i, pos.battery_level);
// Update our current position in the local DB
nodeDB.updatePosition(nodeDB.getNodeNum(), pos, RX_SRC_LOCAL);
nodeDB.updatePosition(nodeDB.getNodeNum(), pos);
return 0;
}

View File

@@ -75,7 +75,7 @@ class MeshService
/// 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
/// cache
void sendToMesh(MeshPacket *p, RxSource src = RX_SRC_LOCAL);
void sendToMesh(MeshPacket *p);
/** Attempt to cancel a previously sent packet from this _local_ node. Returns true if a packet was found we could cancel */
bool cancelSending(PacketId id);

View File

@@ -20,8 +20,7 @@ typedef uint32_t PacketId; // A packet sequence number
*/
enum RxSource {
RX_SRC_LOCAL, // message was generated locally
RX_SRC_RADIO, // message was received from radio mesh
RX_SRC_USER // message was received from end-user device
RX_SRC_RADIO // message was received from radio mesh
};
/**

View File

@@ -23,7 +23,6 @@
#include "mesh/http/WiFiAPClient.h"
#include "plugins/esp32/StoreForwardPlugin.h"
#include <Preferences.h>
#include <nvs_flash.h>
#endif
NodeDB nodeDB;
@@ -87,10 +86,6 @@ bool NodeDB::resetRadioConfig()
if (radioConfig.preferences.factory_reset) {
DEBUG_MSG("Performing factory reset!\n");
installDefaultDeviceState();
#ifndef NO_ESP32
// This will erase what's in NVS including ssl keys, persistant variables and ble pairing
nvs_flash_erase();
#endif
didFactoryReset = true;
}
@@ -130,11 +125,6 @@ void NodeDB::installDefaultRadioConfig()
memset(&radioConfig, 0, sizeof(radioConfig));
radioConfig.has_preferences = true;
resetRadioConfig();
// for backward compat, default position flags are BAT+ALT+MSL (0x23 = 35)
radioConfig.preferences.position_flags = (PositionFlags_POS_BATTERY |
PositionFlags_POS_ALTITUDE | PositionFlags_POS_ALT_MSL);
}
void NodeDB::installDefaultChannels()
@@ -250,10 +240,6 @@ void NodeDB::init()
preferences.end();
DEBUG_MSG("Number of Device Reboots: %d\n", myNodeInfo.reboot_count);
/* The ESP32 has a wifi radio. This will need to be modified at some point so
* the test isn't so simplistic.
*/
myNodeInfo.has_wifi = true;
#endif
resetRadioConfig(); // If bogus settings got saved, then fix them
@@ -438,7 +424,7 @@ uint32_t sinceLastSeen(const NodeInfo *n)
return delta;
}
#define NUM_ONLINE_SECS (60 & 60 * 2) // 2 hrs to consider someone offline
#define NUM_ONLINE_SECS (60 * 2) // 2 hrs to consider someone offline
size_t NodeDB::getNumOnlineNodes()
{
@@ -456,42 +442,25 @@ size_t NodeDB::getNumOnlineNodes()
/** Update position info for this node based on received position data
*/
void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src)
void NodeDB::updatePosition(uint32_t nodeId, const Position &p)
{
NodeInfo *info = getOrCreateNode(nodeId);
if (src == RX_SRC_LOCAL) {
// Local packet, fully authoritative
DEBUG_MSG("updatePosition LOCAL pos@%x:5, time=%u, latI=%d, lonI=%d\n",
p.pos_timestamp, p.time, p.latitude_i, p.longitude_i);
info->position = p;
DEBUG_MSG("DB update position node=0x%x time=%u, latI=%d, lonI=%d\n", nodeId, p.time, p.latitude_i, p.longitude_i);
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.pos_timestamp &&
!p.location_source) {
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
// (stop-gap fix for issue #900)
DEBUG_MSG("updatePosition SPECIAL time setting time=%u\n", p.time);
// Be careful to only update fields that have been set by the sender
// A lot of position reports don't have time populated. In that case, be careful to not blow away the time we
// recorded based on the packet rxTime
if (p.time)
info->position.time = p.time;
} else {
// Be careful to only update fields that have been set by the REMOTE sender
// A lot of position reports don't have time populated. In that case, be careful to not blow away the time we
// recorded based on the packet rxTime
//
// FIXME perhaps handle RX_SRC_USER separately?
DEBUG_MSG("updatePosition REMOTE node=0x%x time=%u, latI=%d, lonI=%d\n",
nodeId, p.time, p.latitude_i, p.longitude_i);
// First, back up fields that we want to protect from overwrite
uint32_t tmp_time = info->position.time;
// Next, update atomically
info->position = p;
// Last, restore any fields that may have been overwritten
if (! info->position.time)
info->position.time = tmp_time;
if (p.battery_level)
info->position.battery_level = p.battery_level;
if (p.latitude_i || p.longitude_i) {
info->position.latitude_i = p.latitude_i;
info->position.longitude_i = p.longitude_i;
}
if (p.altitude)
info->position.altitude = p.altitude;
info->has_position = true;
updateGUIforNode = info;
notifyObservers(true); // Force an update whether or not our node counts have changed

View File

@@ -59,7 +59,7 @@ class NodeDB
/** Update position info for this node based on received position data
*/
void updatePosition(uint32_t nodeId, const Position &p, RxSource src = RX_SRC_RADIO);
void updatePosition(uint32_t nodeId, const Position &p);
/** Update user info for this node based on received user data
*/

View File

@@ -297,16 +297,6 @@ void RadioInterface::applyModemConfig()
cr = 8;
sf = 12;
break;
case ChannelSettings_ModemConfig_Bw250Cr46Sf2048:
bw = 250;
cr = 6;
sf = 11;
break;
case ChannelSettings_ModemConfig_Bw250Cr47Sf1024:
bw = 250;
cr = 7;
sf = 10;
break;
default:
assert(0); // Unknown enum
}
@@ -317,8 +307,6 @@ void RadioInterface::applyModemConfig()
if (bw == 31) // This parameter is not an integer
bw = 31.25;
if (bw == 62) // Fix for 62.5Khz bandwidth
bw = 62.5;
}
power = channelSettings.tx_power;

View File

@@ -93,8 +93,7 @@ bool RadioLibInterface::canSendImmediately()
/// bluetooth comms code. If the txmit queue is empty it might return an error
ErrorCode RadioLibInterface::send(MeshPacket *p)
{
if (disabled || radioConfig.preferences.is_lora_tx_disabled) {
DEBUG_MSG("send - lora_tx_disabled\n");
if (disabled) {
packetPool.release(p);
return ERRNO_DISABLED;
}
@@ -102,6 +101,7 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
// Sometimes when testing it is useful to be able to never turn on the xmitter
#ifndef LORA_DISABLE_SENDING
printPacket("enqueuing for send", p);
uint32_t xmitMsec = getPacketTime(p);
DEBUG_MSG("txGood=%d,rxGood=%d,rxBad=%d\n", txGood, rxGood, rxBad);
ErrorCode res = txQueue.enqueue(p) ? ERRNO_OK : ERRNO_UNKNOWN;
@@ -111,6 +111,10 @@ ErrorCode RadioLibInterface::send(MeshPacket *p)
return res;
}
// Count the packet toward our TX airtime utilization.
// We only count it if it can be added to the TX queue.
airTime->logAirtime(TX_LOG, xmitMsec);
// We want all sending/receiving to be done by our daemon thread, We use a delay here because this packet might have been sent
// in response to a packet we just received. So we want to make sure the other side has had a chance to reconfigure its radio
startTransmitTimer(true);
@@ -184,10 +188,6 @@ void RadioLibInterface::onNotify(uint32_t notification)
MeshPacket *txp = txQueue.dequeue();
assert(txp);
startSend(txp);
// Packet has been sent, count it toward our TX airtime utilization.
uint32_t xmitMsec = getPacketTime(txp);
airTime->logAirtime(TX_LOG, xmitMsec);
}
} else {
// DEBUG_MSG("done with txqueue\n");
@@ -301,7 +301,7 @@ void RadioLibInterface::handleReceiveInterrupt()
void RadioLibInterface::startSend(MeshPacket *txp)
{
printPacket("Starting low level send", txp);
if (disabled || radioConfig.preferences.is_lora_tx_disabled) {
if (disabled) {
DEBUG_MSG("startSend is dropping tx packet because we are disabled\n");
packetPool.release(txp);
} else {

View File

@@ -8,7 +8,6 @@
#define RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED
#endif
#define RADIOLIB_EXCLUDE_HTTP
#include <RadioLib.h>
// ESP32 has special rules about ISR code
@@ -88,8 +87,8 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
* for a long time.
*/
const uint8_t syncWord = 0x2b;
float currentLimit = 100; // 100mA OCP - Should be acceptable for RFM95/SX127x chipset.
float currentLimit = 100; // FIXME
LockingModule module; // The HW interface to the radio

View File

@@ -16,13 +16,8 @@ ErrorCode ReliableRouter::send(MeshPacket *p)
// If someone asks for acks on broadcast, we need the hop limit to be at least one, so that first node that receives our
// message will rebroadcast. But asking for hop_limit 0 in that context means the client app has no preference on hop counts
// and we want this message to get through the whole mesh, so use the default.
if (p->to == NODENUM_BROADCAST && p->hop_limit == 0) {
if (radioConfig.preferences.hop_limit && radioConfig.preferences.hop_limit <= HOP_MAX) {
p->hop_limit = (radioConfig.preferences.hop_limit >= HOP_MAX) ? HOP_MAX : radioConfig.preferences.hop_limit;
} else {
p->hop_limit = HOP_RELIABLE;
}
}
if (p->to == NODENUM_BROADCAST && p->hop_limit == 0)
p->hop_limit = HOP_RELIABLE;
auto copy = packetPool.allocCopy(*p);
startRetransmission(copy);
@@ -31,7 +26,7 @@ ErrorCode ReliableRouter::send(MeshPacket *p)
return FloodingRouter::send(p);
}
bool ReliableRouter::shouldFilterReceived(MeshPacket *p)
bool ReliableRouter::shouldFilterReceived(const MeshPacket *p)
{
// Note: do not use getFrom() here, because we want to ignore messages sent from phone
if (p->to == NODENUM_BROADCAST && p->from == getNodeNum()) {
@@ -59,17 +54,6 @@ bool ReliableRouter::shouldFilterReceived(MeshPacket *p)
}
}
/* send acks for repeated packets that want acks and are destined for us
* this way if an ACK is dropped and a packet is resent we'll ACK the resent packet
* make sure wasSeenRecently _doesn't_ update
* finding the channel requires decoding the packet. */
if (p->want_ack && (p->to == getNodeNum()) && wasSeenRecently(p, false)) {
if (perhapsDecode(p)) {
sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel);
DEBUG_MSG("acking a repeated want_ack packet\n");
}
}
return FloodingRouter::shouldFilterReceived(p);
}

View File

@@ -102,7 +102,7 @@ class ReliableRouter : public FloodingRouter
/**
* We hook this method so we can see packets before FloodingRouter says they should be discarded
*/
virtual bool shouldFilterReceived(MeshPacket *p);
virtual bool shouldFilterReceived(const MeshPacket *p);
/**
* Add p to the list of packets to retransmit occasionally. We will free it once we stop retransmitting.

View File

@@ -115,11 +115,7 @@ MeshPacket *Router::allocForSending()
p->which_payloadVariant = MeshPacket_decoded_tag; // Assume payload is decoded at start.
p->from = nodeDB.getNodeNum();
p->to = NODENUM_BROADCAST;
if (radioConfig.preferences.hop_limit && radioConfig.preferences.hop_limit <= HOP_MAX) {
p->hop_limit = (radioConfig.preferences.hop_limit >= HOP_MAX) ? HOP_MAX : radioConfig.preferences.hop_limit;
} else {
p->hop_limit = HOP_RELIABLE;
}
p->hop_limit = HOP_RELIABLE;
p->id = generatePacketId();
p->rx_time =
getValidTime(RTCQualityFromNet); // Just in case we process the packet locally - make sure it has a valid timestamp
@@ -149,7 +145,7 @@ void Router::setReceivedMessage()
runASAP = true;
}
ErrorCode Router::sendLocal(MeshPacket *p, RxSource src)
ErrorCode Router::sendLocal(MeshPacket *p)
{
// No need to deliver externally if the destination is the local node
if (p->to == nodeDB.getNodeNum()) {
@@ -165,7 +161,7 @@ ErrorCode Router::sendLocal(MeshPacket *p, RxSource src)
// If we are sending a broadcast, we also treat it as if we just received it ourself
// this allows local apps (and PCs) to see broadcasts sourced locally
if (p->to == NODENUM_BROADCAST) {
handleReceived(p, src);
handleReceived(p, RX_SRC_LOCAL);
}
return send(p);
@@ -338,11 +334,9 @@ void Router::handleReceived(MeshPacket *p, RxSource src)
if (decoded) {
// parsing was successful, queue for our recipient
if (src == RX_SRC_LOCAL)
printPacket("handleReceived(LOCAL)", p);
else if (src == RX_SRC_USER)
printPacket("handleReceived(USER)", p);
printPacket("handleReceived(local)", p);
else
printPacket("handleReceived(REMOTE)", p);
printPacket("handleReceived(remote)", p);
} else {
printPacket("packet decoding failed (no PSK?)", p);
}

View File

@@ -45,7 +45,7 @@ class Router : protected concurrency::OSThread
*
* NOTE: This method will free the provided packet (even if we return an error code)
*/
ErrorCode sendLocal(MeshPacket *p, RxSource src = RX_SRC_RADIO);
ErrorCode sendLocal(MeshPacket *p);
/** Attempt to cancel a previously sent packet. Returns true if a packet was found we could cancel */
bool cancelSending(NodeNum from, PacketId id);
@@ -90,7 +90,7 @@ class Router : protected concurrency::OSThread
* Called immedately on receiption, before any further processing.
* @return true to abandon the packet
*/
virtual bool shouldFilterReceived(MeshPacket *p) { return false; }
virtual bool shouldFilterReceived(const MeshPacket *p) { return false; }
/**
* Every (non duplicate) packet this node receives will be passed through this method. This allows subclasses to

View File

@@ -29,8 +29,6 @@ class SX126xInterface : public RadioLibInterface
protected:
float currentLimit = 140; // Higher OCP limit for SX126x PA
/**
* Specific module instance
*/

View File

@@ -4,9 +4,9 @@
#ifndef PB_ADMIN_PB_H_INCLUDED
#define PB_ADMIN_PB_H_INCLUDED
#include <pb.h>
#include "channel.pb.h"
#include "mesh.pb.h"
#include "radioconfig.pb.h"
#include "channel.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
@@ -23,8 +23,6 @@ typedef struct _AdminMessage {
RadioConfig get_radio_response;
uint32_t get_channel_request;
Channel get_channel_response;
bool get_owner_request;
User get_owner_response;
bool confirm_set_channel;
bool confirm_set_radio;
bool exit_simulator;
@@ -49,8 +47,6 @@ extern "C" {
#define AdminMessage_get_radio_response_tag 5
#define AdminMessage_get_channel_request_tag 6
#define AdminMessage_get_channel_response_tag 7
#define AdminMessage_get_owner_request_tag 8
#define AdminMessage_get_owner_response_tag 9
#define AdminMessage_confirm_set_channel_tag 32
#define AdminMessage_confirm_set_radio_tag 33
#define AdminMessage_exit_simulator_tag 34
@@ -65,8 +61,6 @@ X(a, STATIC, ONEOF, BOOL, (variant,get_radio_request,get_radio_request)
X(a, STATIC, ONEOF, MESSAGE, (variant,get_radio_response,get_radio_response), 5) \
X(a, STATIC, ONEOF, UINT32, (variant,get_channel_request,get_channel_request), 6) \
X(a, STATIC, ONEOF, MESSAGE, (variant,get_channel_response,get_channel_response), 7) \
X(a, STATIC, ONEOF, BOOL, (variant,get_owner_request,get_owner_request), 8) \
X(a, STATIC, ONEOF, MESSAGE, (variant,get_owner_response,get_owner_response), 9) \
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_channel,confirm_set_channel), 32) \
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_radio,confirm_set_radio), 33) \
X(a, STATIC, ONEOF, BOOL, (variant,exit_simulator,exit_simulator), 34) \
@@ -78,7 +72,6 @@ X(a, STATIC, ONEOF, INT32, (variant,reboot_seconds,reboot_seconds), 35)
#define AdminMessage_variant_set_channel_MSGTYPE Channel
#define AdminMessage_variant_get_radio_response_MSGTYPE RadioConfig
#define AdminMessage_variant_get_channel_response_MSGTYPE Channel
#define AdminMessage_variant_get_owner_response_MSGTYPE User
extern const pb_msgdesc_t AdminMessage_msg;
@@ -86,7 +79,7 @@ extern const pb_msgdesc_t AdminMessage_msg;
#define AdminMessage_fields &AdminMessage_msg
/* Maximum encoded size of messages (where known) */
#define AdminMessage_size 535
#define AdminMessage_size 407
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -14,9 +14,7 @@ typedef enum _ChannelSettings_ModemConfig {
ChannelSettings_ModemConfig_Bw125Cr45Sf128 = 0,
ChannelSettings_ModemConfig_Bw500Cr45Sf128 = 1,
ChannelSettings_ModemConfig_Bw31_25Cr48Sf512 = 2,
ChannelSettings_ModemConfig_Bw125Cr48Sf4096 = 3,
ChannelSettings_ModemConfig_Bw250Cr46Sf2048 = 4,
ChannelSettings_ModemConfig_Bw250Cr47Sf1024 = 5
ChannelSettings_ModemConfig_Bw125Cr48Sf4096 = 3
} ChannelSettings_ModemConfig;
typedef enum _Channel_Role {
@@ -51,8 +49,8 @@ typedef struct _Channel {
/* Helper constants for enums */
#define _ChannelSettings_ModemConfig_MIN ChannelSettings_ModemConfig_Bw125Cr45Sf128
#define _ChannelSettings_ModemConfig_MAX ChannelSettings_ModemConfig_Bw250Cr47Sf1024
#define _ChannelSettings_ModemConfig_ARRAYSIZE ((ChannelSettings_ModemConfig)(ChannelSettings_ModemConfig_Bw250Cr47Sf1024+1))
#define _ChannelSettings_ModemConfig_MAX ChannelSettings_ModemConfig_Bw125Cr48Sf4096
#define _ChannelSettings_ModemConfig_ARRAYSIZE ((ChannelSettings_ModemConfig)(ChannelSettings_ModemConfig_Bw125Cr48Sf4096+1))
#define _Channel_Role_MIN Channel_Role_DISABLED
#define _Channel_Role_MAX Channel_Role_SECONDARY

View File

@@ -4,8 +4,8 @@
#ifndef PB_DEVICEONLY_PB_H_INCLUDED
#define PB_DEVICEONLY_PB_H_INCLUDED
#include <pb.h>
#include "channel.pb.h"
#include "mesh.pb.h"
#include "channel.pb.h"
#include "radioconfig.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
@@ -125,7 +125,7 @@ extern const pb_msgdesc_t ChannelFile_msg;
/* Maximum encoded size of messages (where known) */
#define LegacyRadioConfig_size 4
#define LegacyRadioConfig_LegacyPreferences_size 2
#define DeviceState_size 9967
#define DeviceState_size 10054
#define ChannelFile_size 832
#ifdef __cplusplus

View File

@@ -27,7 +27,7 @@ PB_BIND(MeshPacket, MeshPacket, 2)
PB_BIND(NodeInfo, NodeInfo, AUTO)
PB_BIND(MyNodeInfo, MyNodeInfo, 2)
PB_BIND(MyNodeInfo, MyNodeInfo, AUTO)
PB_BIND(LogRecord, LogRecord, AUTO)
@@ -51,5 +51,3 @@ PB_BIND(ToRadio_PeerInfo, ToRadio_PeerInfo, AUTO)

View File

@@ -23,7 +23,6 @@ typedef enum _HardwareModel {
HardwareModel_TLORA_V1_1p3 = 8,
HardwareModel_RAK4631 = 9,
HardwareModel_HELTEC_V2_1 = 10,
HardwareModel_HELTEC_V1 = 11,
HardwareModel_LORA_RELAY_V1 = 32,
HardwareModel_NRF52840DK = 33,
HardwareModel_PPR = 34,
@@ -34,24 +33,6 @@ typedef enum _HardwareModel {
HardwareModel_DIY_V1 = 39
} HardwareModel;
typedef enum _Team {
Team_CLEAR = 0,
Team_CYAN = 1,
Team_WHITE = 2,
Team_YELLOW = 3,
Team_ORANGE = 4,
Team_MAGENTA = 5,
Team_RED = 6,
Team_MAROON = 7,
Team_PURPLE = 8,
Team_DARK_BLUE = 9,
Team_BLUE = 10,
Team_TEAL = 11,
Team_GREEN = 12,
Team_DARK_GREEN = 13,
Team_BROWN = 14
} Team;
typedef enum _Constants {
Constants_Unused = 0,
Constants_DATA_PAYLOAD_LEN = 237
@@ -111,12 +92,6 @@ typedef enum _MeshPacket_Priority {
MeshPacket_Priority_MAX = 127
} MeshPacket_Priority;
typedef enum _MeshPacket_Delayed {
MeshPacket_Delayed_NO_DELAY = 0,
MeshPacket_Delayed_DELAYED_BROADCAST = 1,
MeshPacket_Delayed_DELAYED_DIRECT = 2
} MeshPacket_Delayed;
typedef enum _LogRecord_Level {
LogRecord_Level_UNSET = 0,
LogRecord_Level_CRITICAL = 50,
@@ -156,16 +131,9 @@ typedef struct _MyNodeInfo {
uint32_t error_address;
uint32_t error_count;
uint32_t reboot_count;
float bitrate;
uint32_t message_timeout_msec;
uint32_t min_app_version;
uint32_t max_channels;
pb_size_t air_period_tx_count;
uint32_t air_period_tx[24];
pb_size_t air_period_rx_count;
uint32_t air_period_rx[24];
bool has_wifi;
float channel_utilization;
} MyNodeInfo;
typedef struct _Position {
@@ -190,6 +158,11 @@ typedef struct _Position {
uint32_t fix_type;
uint32_t sats_in_view;
uint32_t sensor_id;
uint32_t heading;
int32_t roll;
int32_t pitch;
uint32_t air_speed;
uint32_t ground_distance_cm;
uint32_t pos_next_update;
uint32_t pos_seq_number;
} Position;
@@ -211,10 +184,6 @@ typedef struct _User {
pb_byte_t macaddr[6];
HardwareModel hw_model;
bool is_licensed;
Team team;
uint32_t tx_power_dbm;
uint32_t ant_gain_dbi;
uint32_t ant_azimuth;
} User;
typedef PB_BYTES_ARRAY_T(256) MeshPacket_encrypted_t;
@@ -234,9 +203,6 @@ typedef struct _MeshPacket {
bool want_ack;
MeshPacket_Priority priority;
int32_t rx_rssi;
MeshPacket_Delayed delayed;
uint32_t reply_id;
bool is_tapback;
} MeshPacket;
typedef struct _NodeInfo {
@@ -287,10 +253,6 @@ typedef struct _ToRadio {
#define _HardwareModel_MAX HardwareModel_DIY_V1
#define _HardwareModel_ARRAYSIZE ((HardwareModel)(HardwareModel_DIY_V1+1))
#define _Team_MIN Team_CLEAR
#define _Team_MAX Team_BROWN
#define _Team_ARRAYSIZE ((Team)(Team_BROWN+1))
#define _Constants_MIN Constants_Unused
#define _Constants_MAX Constants_DATA_PAYLOAD_LEN
#define _Constants_ARRAYSIZE ((Constants)(Constants_DATA_PAYLOAD_LEN+1))
@@ -315,10 +277,6 @@ typedef struct _ToRadio {
#define _MeshPacket_Priority_MAX MeshPacket_Priority_MAX
#define _MeshPacket_Priority_ARRAYSIZE ((MeshPacket_Priority)(MeshPacket_Priority_MAX+1))
#define _MeshPacket_Delayed_MIN MeshPacket_Delayed_NO_DELAY
#define _MeshPacket_Delayed_MAX MeshPacket_Delayed_DELAYED_DIRECT
#define _MeshPacket_Delayed_ARRAYSIZE ((MeshPacket_Delayed)(MeshPacket_Delayed_DELAYED_DIRECT+1))
#define _LogRecord_Level_MIN LogRecord_Level_UNSET
#define _LogRecord_Level_MAX LogRecord_Level_CRITICAL
#define _LogRecord_Level_ARRAYSIZE ((LogRecord_Level)(LogRecord_Level_CRITICAL+1))
@@ -329,26 +287,26 @@ extern "C" {
#endif
/* Initializer values for message structs */
#define Position_init_default {0, 0, 0, 0, 0, _Position_LocSource_MIN, _Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define User_init_default {"", "", "", {0}, _HardwareModel_MIN, 0, _Team_MIN, 0, 0, 0}
#define Position_init_default {0, 0, 0, 0, 0, _Position_LocSource_MIN, _Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define User_init_default {"", "", "", {0}, _HardwareModel_MIN, 0}
#define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}}
#define Routing_init_default {0, {RouteDiscovery_init_default}}
#define Data_init_default {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0}
#define MeshPacket_init_default {0, 0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN, 0, 0}
#define MeshPacket_init_default {0, 0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0}
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0}
#define MyNodeInfo_init_default {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}
#define MyNodeInfo_init_default {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0}
#define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN}
#define FromRadio_init_default {0, 0, {MyNodeInfo_init_default}}
#define ToRadio_init_default {0, {MeshPacket_init_default}}
#define ToRadio_PeerInfo_init_default {0, 0}
#define Position_init_zero {0, 0, 0, 0, 0, _Position_LocSource_MIN, _Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define User_init_zero {"", "", "", {0}, _HardwareModel_MIN, 0, _Team_MIN, 0, 0, 0}
#define Position_init_zero {0, 0, 0, 0, 0, _Position_LocSource_MIN, _Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define User_init_zero {"", "", "", {0}, _HardwareModel_MIN, 0}
#define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}}
#define Routing_init_zero {0, {RouteDiscovery_init_zero}}
#define Data_init_zero {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0}
#define MeshPacket_init_zero {0, 0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN, 0, 0}
#define MeshPacket_init_zero {0, 0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0}
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0}
#define MyNodeInfo_init_zero {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0}
#define MyNodeInfo_init_zero {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0}
#define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN}
#define FromRadio_init_zero {0, 0, {MyNodeInfo_init_zero}}
#define ToRadio_init_zero {0, {MeshPacket_init_zero}}
@@ -375,14 +333,9 @@ extern "C" {
#define MyNodeInfo_error_address_tag 8
#define MyNodeInfo_error_count_tag 9
#define MyNodeInfo_reboot_count_tag 10
#define MyNodeInfo_bitrate_tag 11
#define MyNodeInfo_message_timeout_msec_tag 13
#define MyNodeInfo_min_app_version_tag 14
#define MyNodeInfo_max_channels_tag 15
#define MyNodeInfo_air_period_tx_tag 16
#define MyNodeInfo_air_period_rx_tag 17
#define MyNodeInfo_has_wifi_tag 18
#define MyNodeInfo_channel_utilization_tag 19
#define Position_latitude_i_tag 1
#define Position_longitude_i_tag 2
#define Position_altitude_tag 3
@@ -404,6 +357,11 @@ extern "C" {
#define Position_fix_type_tag 23
#define Position_sats_in_view_tag 24
#define Position_sensor_id_tag 25
#define Position_heading_tag 30
#define Position_roll_tag 31
#define Position_pitch_tag 32
#define Position_air_speed_tag 33
#define Position_ground_distance_cm_tag 34
#define Position_pos_next_update_tag 40
#define Position_pos_seq_number_tag 41
#define RouteDiscovery_route_tag 2
@@ -415,10 +373,6 @@ extern "C" {
#define User_macaddr_tag 4
#define User_hw_model_tag 6
#define User_is_licensed_tag 7
#define User_team_tag 8
#define User_tx_power_dbm_tag 10
#define User_ant_gain_dbi_tag 11
#define User_ant_azimuth_tag 12
#define MeshPacket_from_tag 1
#define MeshPacket_to_tag 2
#define MeshPacket_channel_tag 3
@@ -431,9 +385,6 @@ extern "C" {
#define MeshPacket_want_ack_tag 11
#define MeshPacket_priority_tag 12
#define MeshPacket_rx_rssi_tag 13
#define MeshPacket_delayed_tag 15
#define MeshPacket_reply_id_tag 16
#define MeshPacket_is_tapback_tag 17
#define NodeInfo_num_tag 1
#define NodeInfo_user_tag 2
#define NodeInfo_position_tag 3
@@ -477,6 +428,11 @@ X(a, STATIC, SINGULAR, UINT32, fix_quality, 22) \
X(a, STATIC, SINGULAR, UINT32, fix_type, 23) \
X(a, STATIC, SINGULAR, UINT32, sats_in_view, 24) \
X(a, STATIC, SINGULAR, UINT32, sensor_id, 25) \
X(a, STATIC, SINGULAR, UINT32, heading, 30) \
X(a, STATIC, SINGULAR, SINT32, roll, 31) \
X(a, STATIC, SINGULAR, SINT32, pitch, 32) \
X(a, STATIC, SINGULAR, UINT32, air_speed, 33) \
X(a, STATIC, SINGULAR, UINT32, ground_distance_cm, 34) \
X(a, STATIC, SINGULAR, UINT32, pos_next_update, 40) \
X(a, STATIC, SINGULAR, UINT32, pos_seq_number, 41)
#define Position_CALLBACK NULL
@@ -488,11 +444,7 @@ X(a, STATIC, SINGULAR, STRING, long_name, 2) \
X(a, STATIC, SINGULAR, STRING, short_name, 3) \
X(a, STATIC, SINGULAR, FIXED_LENGTH_BYTES, macaddr, 4) \
X(a, STATIC, SINGULAR, UENUM, hw_model, 6) \
X(a, STATIC, SINGULAR, BOOL, is_licensed, 7) \
X(a, STATIC, SINGULAR, UENUM, team, 8) \
X(a, STATIC, SINGULAR, UINT32, tx_power_dbm, 10) \
X(a, STATIC, SINGULAR, UINT32, ant_gain_dbi, 11) \
X(a, STATIC, SINGULAR, UINT32, ant_azimuth, 12)
X(a, STATIC, SINGULAR, BOOL, is_licensed, 7)
#define User_CALLBACK NULL
#define User_DEFAULT NULL
@@ -532,10 +484,7 @@ X(a, STATIC, SINGULAR, FLOAT, rx_snr, 8) \
X(a, STATIC, SINGULAR, UINT32, hop_limit, 10) \
X(a, STATIC, SINGULAR, BOOL, want_ack, 11) \
X(a, STATIC, SINGULAR, UENUM, priority, 12) \
X(a, STATIC, SINGULAR, INT32, rx_rssi, 13) \
X(a, STATIC, SINGULAR, UENUM, delayed, 15) \
X(a, STATIC, SINGULAR, FIXED32, reply_id, 16) \
X(a, STATIC, SINGULAR, BOOL, is_tapback, 17)
X(a, STATIC, SINGULAR, INT32, rx_rssi, 13)
#define MeshPacket_CALLBACK NULL
#define MeshPacket_DEFAULT NULL
#define MeshPacket_payloadVariant_decoded_MSGTYPE Data
@@ -562,14 +511,9 @@ X(a, STATIC, SINGULAR, UENUM, error_code, 7) \
X(a, STATIC, SINGULAR, UINT32, error_address, 8) \
X(a, STATIC, SINGULAR, UINT32, error_count, 9) \
X(a, STATIC, SINGULAR, UINT32, reboot_count, 10) \
X(a, STATIC, SINGULAR, FLOAT, bitrate, 11) \
X(a, STATIC, SINGULAR, UINT32, message_timeout_msec, 13) \
X(a, STATIC, SINGULAR, UINT32, min_app_version, 14) \
X(a, STATIC, SINGULAR, UINT32, max_channels, 15) \
X(a, STATIC, REPEATED, UINT32, air_period_tx, 16) \
X(a, STATIC, REPEATED, UINT32, air_period_rx, 17) \
X(a, STATIC, SINGULAR, BOOL, has_wifi, 18) \
X(a, STATIC, SINGULAR, FLOAT, channel_utilization, 19)
X(a, STATIC, SINGULAR, UINT32, max_channels, 15)
#define MyNodeInfo_CALLBACK NULL
#define MyNodeInfo_DEFAULT NULL
@@ -640,17 +584,17 @@ extern const pb_msgdesc_t ToRadio_PeerInfo_msg;
#define ToRadio_PeerInfo_fields &ToRadio_PeerInfo_msg
/* Maximum encoded size of messages (where known) */
#define Position_size 153
#define User_size 96
#define Position_size 188
#define User_size 76
#define RouteDiscovery_size 40
#define Routing_size 42
#define Data_size 260
#define MeshPacket_size 320
#define NodeInfo_size 270
#define MyNodeInfo_size 451
#define MeshPacket_size 309
#define NodeInfo_size 285
#define MyNodeInfo_size 101
#define LogRecord_size 81
#define FromRadio_size 460
#define ToRadio_size 323
#define FromRadio_size 318
#define ToRadio_size 312
#define ToRadio_PeerInfo_size 8
#ifdef __cplusplus

Some files were not shown because too many files have changed in this diff Show More