sforkowany z mirror/meshtastic-firmware
trunk roundhouse kick
rodzic
6cf18b7d07
commit
51b2c431d9
|
@ -1,3 +1,4 @@
|
|||
* text=auto eol=lf
|
||||
*.{cmd,[cC][mM][dD]} text eol=crlf
|
||||
*.{bat,[bB][aA][tT]} text eol=crlf
|
||||
*.{sh,[sS][hH]} text eol=lf
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
set -e
|
||||
|
||||
VERSION=`bin/buildinfo.py long`
|
||||
SHORT_VERSION=`bin/buildinfo.py short`
|
||||
VERSION=$(bin/buildinfo.py long)
|
||||
SHORT_VERSION=$(bin/buildinfo.py short)
|
||||
|
||||
OUTDIR=release/
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
set -e
|
||||
|
||||
VERSION=`bin/buildinfo.py long`
|
||||
SHORT_VERSION=`bin/buildinfo.py short`
|
||||
VERSION=$(bin/buildinfo.py long)
|
||||
SHORT_VERSION=$(bin/buildinfo.py short)
|
||||
|
||||
OUTDIR=release/
|
||||
|
||||
|
@ -20,4 +20,3 @@ cp .pio/build/native/program $OUTDIR/meshtasticd_linux_amd64
|
|||
|
||||
cp bin/device-install.* $OUTDIR
|
||||
cp bin/device-update.* $OUTDIR
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
set -e
|
||||
|
||||
VERSION=`bin/buildinfo.py long`
|
||||
SHORT_VERSION=`bin/buildinfo.py short`
|
||||
VERSION=$(bin/buildinfo.py long)
|
||||
SHORT_VERSION=$(bin/buildinfo.py short)
|
||||
|
||||
OUTDIR=release/
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
set -e
|
||||
|
||||
VERSION=`bin/buildinfo.py long`
|
||||
SHORT_VERSION=`bin/buildinfo.py short`
|
||||
VERSION=$(bin/buildinfo.py long)
|
||||
SHORT_VERSION=$(bin/buildinfo.py short)
|
||||
|
||||
OUTDIR=release/
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
set -e
|
||||
|
||||
VERSION=`bin/buildinfo.py long`
|
||||
VERSION=$(bin/buildinfo.py long)
|
||||
|
||||
# The shell vars the build tool expects to find
|
||||
export APP_VERSION=$VERSION
|
||||
|
|
|
@ -18,18 +18,20 @@ Flash image file to device, but first erasing and writing system information"
|
|||
EOF
|
||||
}
|
||||
|
||||
|
||||
while getopts ":hp:P:f:" opt; do
|
||||
case "${opt}" in
|
||||
h)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
p) export ESPTOOL_PORT=${OPTARG}
|
||||
p)
|
||||
export ESPTOOL_PORT=${OPTARG}
|
||||
;;
|
||||
P) PYTHON=${OPTARG}
|
||||
P)
|
||||
PYTHON=${OPTARG}
|
||||
;;
|
||||
f) FILENAME=${OPTARG}
|
||||
f)
|
||||
FILENAME=${OPTARG}
|
||||
;;
|
||||
*)
|
||||
echo "Invalid flag."
|
||||
|
|
|
@ -16,18 +16,20 @@ Flash image file to device, leave existing system intact."
|
|||
EOF
|
||||
}
|
||||
|
||||
|
||||
while getopts ":hp:P:f:" opt; do
|
||||
case "${opt}" in
|
||||
h)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
p) export ESPTOOL_PORT=${OPTARG}
|
||||
p)
|
||||
export ESPTOOL_PORT=${OPTARG}
|
||||
;;
|
||||
P) PYTHON=${OPTARG}
|
||||
P)
|
||||
PYTHON=${OPTARG}
|
||||
;;
|
||||
f) FILENAME=${OPTARG}
|
||||
f)
|
||||
FILENAME=${OPTARG}
|
||||
;;
|
||||
*)
|
||||
echo "Invalid flag."
|
||||
|
|
|
@ -4,7 +4,7 @@ set -e
|
|||
|
||||
echo "This script is only for developers who are publishing new builds on github. Most users don't need it"
|
||||
|
||||
VERSION=`bin/buildinfo.py long`
|
||||
VERSION=$(bin/buildinfo.py long)
|
||||
|
||||
# Must have a V prefix to trigger github
|
||||
git tag "v${VERSION}"
|
||||
|
|
|
@ -8,4 +8,3 @@ sleep 20 # 5 seconds was not enough
|
|||
|
||||
echo "Simulator started, launching python test..."
|
||||
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
|
||||
|
||||
|
|
|
@ -7,12 +7,7 @@
|
|||
"cpu": "cortex-m4",
|
||||
"extra_flags": "-DARDUINO_NRF52840_TTGO_EINK -DNRF52840_XXAA",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x239A",
|
||||
"0x4405"
|
||||
]
|
||||
],
|
||||
"hwids": [["0x239A", "0x4405"]],
|
||||
"usb_product": "TTGO_eink",
|
||||
"mcu": "nrf52840",
|
||||
"variant": "eink0.1",
|
||||
|
@ -30,19 +25,13 @@
|
|||
"settings_addr": "0xFF000"
|
||||
}
|
||||
},
|
||||
"connectivity": [
|
||||
"bluetooth"
|
||||
],
|
||||
"connectivity": ["bluetooth"],
|
||||
"debug": {
|
||||
"jlink_device": "nRF52840_xxAA",
|
||||
"onboard_tools": [
|
||||
"jlink"
|
||||
],
|
||||
"onboard_tools": ["jlink"],
|
||||
"svd_path": "nrf52840.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"frameworks": ["arduino"],
|
||||
"name": "TTGO eink (Adafruit BSP)",
|
||||
"upload": {
|
||||
"maximum_ram_size": 248832,
|
||||
|
@ -50,11 +39,7 @@
|
|||
"require_upload_port": true,
|
||||
"speed": 115200,
|
||||
"protocol": "jlink",
|
||||
"protocols": [
|
||||
"jlink",
|
||||
"nrfjprog",
|
||||
"stlink"
|
||||
]
|
||||
"protocols": ["jlink", "nrfjprog", "stlink"]
|
||||
},
|
||||
"url": "FIXME",
|
||||
"vendor": "TTGO"
|
||||
|
|
|
@ -9,9 +9,7 @@
|
|||
"product_line": "STM32WLE5xx"
|
||||
},
|
||||
"debug": {
|
||||
"default_tools": [
|
||||
"stlink"
|
||||
],
|
||||
"default_tools": ["stlink"],
|
||||
"jlink_device": "STM32WLE5CC",
|
||||
"openocd_target": "stm32wlx",
|
||||
"svd_path": "STM32WLE5_CM4.svd"
|
||||
|
@ -22,9 +20,7 @@
|
|||
"maximum_ram_size": 65536,
|
||||
"maximum_size": 262144,
|
||||
"protocol": "cmsis-dap",
|
||||
"protocols": [
|
||||
"cmsis-dap"
|
||||
]
|
||||
"protocols": ["cmsis-dap"]
|
||||
},
|
||||
"url": "https://www.st.com/en/microcontrollers-microprocessors/stm32wl-series.html",
|
||||
"vendor": "ST"
|
||||
|
|
|
@ -19,16 +19,12 @@
|
|||
"sd_fwid": "0x00B7"
|
||||
}
|
||||
},
|
||||
"connectivity": [
|
||||
"bluetooth"
|
||||
],
|
||||
"connectivity": ["bluetooth"],
|
||||
"debug": {
|
||||
"jlink_device": "nRF52832_xxAA",
|
||||
"svd_path": "nrf52.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"frameworks": ["arduino"],
|
||||
"name": "lora ISP4520",
|
||||
"upload": {
|
||||
"maximum_ram_size": 65536,
|
||||
|
@ -36,12 +32,7 @@
|
|||
"require_upload_port": true,
|
||||
"speed": 115200,
|
||||
"protocol": "nrfutil",
|
||||
"protocols": [
|
||||
"jlink",
|
||||
"nrfjprog",
|
||||
"nrfutil",
|
||||
"stlink"
|
||||
]
|
||||
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"]
|
||||
},
|
||||
"url": "",
|
||||
"vendor": "PsiSoft"
|
||||
|
|
|
@ -8,22 +8,10 @@
|
|||
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x239A",
|
||||
"0x8029"
|
||||
],
|
||||
[
|
||||
"0x239A",
|
||||
"0x0029"
|
||||
],
|
||||
[
|
||||
"0x239A",
|
||||
"0x002A"
|
||||
],
|
||||
[
|
||||
"0x239A",
|
||||
"0x802A"
|
||||
]
|
||||
["0x239A", "0x8029"],
|
||||
["0x239A", "0x0029"],
|
||||
["0x239A", "0x002A"],
|
||||
["0x239A", "0x802A"]
|
||||
],
|
||||
"usb_product": "PCA10059",
|
||||
"mcu": "nrf52840",
|
||||
|
@ -41,28 +29,19 @@
|
|||
"settings_addr": "0xFF000"
|
||||
}
|
||||
},
|
||||
"connectivity": [
|
||||
"bluetooth"
|
||||
],
|
||||
"connectivity": ["bluetooth"],
|
||||
"debug": {
|
||||
"jlink_device": "nRF52840_xxAA",
|
||||
"svd_path": "nrf52840.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"frameworks": ["arduino"],
|
||||
"name": "nRF52840 Dongle",
|
||||
"upload": {
|
||||
"maximum_ram_size": 248832,
|
||||
"maximum_size": 815104,
|
||||
"speed": 115200,
|
||||
"protocol": "nrfutil",
|
||||
"protocols": [
|
||||
"jlink",
|
||||
"nrfjprog",
|
||||
"nrfutil",
|
||||
"stlink"
|
||||
],
|
||||
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
|
||||
"use_1200bps_touch": true,
|
||||
"require_upload_port": true,
|
||||
"wait_for_upload_port": true
|
||||
|
|
|
@ -44,4 +44,3 @@
|
|||
"url": "https://meshtastic.org/",
|
||||
"vendor": "Nordic Semi"
|
||||
}
|
||||
|
|
@ -7,12 +7,7 @@
|
|||
"cpu": "cortex-m4",
|
||||
"extra_flags": "-DARDUINO_NRF52840_TTGO_EINK -DNRF52840_XXAA",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x239A",
|
||||
"0x4405"
|
||||
]
|
||||
],
|
||||
"hwids": [["0x239A", "0x4405"]],
|
||||
"usb_product": "TTGO_eink",
|
||||
"mcu": "nrf52840",
|
||||
"variant": "t-echo",
|
||||
|
@ -30,31 +25,20 @@
|
|||
"settings_addr": "0xFF000"
|
||||
}
|
||||
},
|
||||
"connectivity": [
|
||||
"bluetooth"
|
||||
],
|
||||
"connectivity": ["bluetooth"],
|
||||
"debug": {
|
||||
"jlink_device": "nRF52840_xxAA",
|
||||
"onboard_tools": [
|
||||
"jlink"
|
||||
],
|
||||
"onboard_tools": ["jlink"],
|
||||
"svd_path": "nrf52840.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"frameworks": ["arduino"],
|
||||
"name": "TTGO eink (Adafruit BSP)",
|
||||
"upload": {
|
||||
"maximum_ram_size": 248832,
|
||||
"maximum_size": 815104,
|
||||
"speed": 115200,
|
||||
"protocol": "nrfutil",
|
||||
"protocols": [
|
||||
"jlink",
|
||||
"nrfjprog",
|
||||
"nrfutil",
|
||||
"stlink"
|
||||
],
|
||||
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
|
||||
"use_1200bps_touch": true,
|
||||
"require_upload_port": true,
|
||||
"wait_for_upload_port": true
|
||||
|
|
|
@ -15,24 +15,15 @@
|
|||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "dio",
|
||||
"hwids": [
|
||||
[
|
||||
"0X303A",
|
||||
"0x1001"
|
||||
]
|
||||
],
|
||||
"hwids": [["0X303A", "0x1001"]],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "tbeam-s3-core"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi"
|
||||
],
|
||||
"connectivity": ["wifi"],
|
||||
"debug": {
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"frameworks": ["arduino"],
|
||||
"name": "LilyGo TBeam-S3-Core",
|
||||
"upload": {
|
||||
"flash_size": "8MB",
|
||||
|
|
|
@ -14,25 +14,15 @@
|
|||
"f_cpu": "240000000L",
|
||||
"f_flash": "80000000L",
|
||||
"flash_mode": "dio",
|
||||
"hwids": [
|
||||
[
|
||||
"0X303A",
|
||||
"0x1001"
|
||||
]
|
||||
],
|
||||
"hwids": [["0X303A", "0x1001"]],
|
||||
"mcu": "esp32s3",
|
||||
"variant": "tlora-t3s3-v1"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi"
|
||||
],
|
||||
"connectivity": ["wifi"],
|
||||
"debug": {
|
||||
"openocd_target": "esp32s3.cfg"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"frameworks": ["arduino", "espidf"],
|
||||
"name": "LilyGo TLora-T3S3-V1",
|
||||
"upload": {
|
||||
"flash_size": "4MB",
|
||||
|
|
|
@ -11,26 +11,14 @@
|
|||
"mcu": "esp32",
|
||||
"variant": "WisCore_RAK11200_Board"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi",
|
||||
"bluetooth",
|
||||
"ethernet",
|
||||
"can"
|
||||
],
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"espidf"
|
||||
],
|
||||
"connectivity": ["wifi", "bluetooth", "ethernet", "can"],
|
||||
"frameworks": ["arduino", "espidf"],
|
||||
"name": "WisCore RAK11200 Board",
|
||||
"upload": {
|
||||
"flash_size": "4MB",
|
||||
"maximum_ram_size": 327680,
|
||||
"maximum_size": 4194304,
|
||||
"protocols": [
|
||||
"esptool",
|
||||
"espota",
|
||||
"ftdi"
|
||||
],
|
||||
"protocols": ["esptool", "espota", "ftdi"],
|
||||
"require_upload_port": true,
|
||||
"speed": 460800
|
||||
},
|
||||
|
|
|
@ -8,22 +8,10 @@
|
|||
"extra_flags": "-DNRF52832_XXAA -DNRF52",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x239A",
|
||||
"0x8029"
|
||||
],
|
||||
[
|
||||
"0x239A",
|
||||
"0x0029"
|
||||
],
|
||||
[
|
||||
"0x239A",
|
||||
"0x002A"
|
||||
],
|
||||
[
|
||||
"0x239A",
|
||||
"0x802A"
|
||||
]
|
||||
["0x239A", "0x8029"],
|
||||
["0x239A", "0x0029"],
|
||||
["0x239A", "0x002A"],
|
||||
["0x239A", "0x802A"]
|
||||
],
|
||||
"usb_product": "Feather nRF52832 Express",
|
||||
"mcu": "nrf52832",
|
||||
|
@ -41,17 +29,12 @@
|
|||
"variant": "nrf52_adafruit_feather"
|
||||
}
|
||||
},
|
||||
"connectivity": [
|
||||
"bluetooth"
|
||||
],
|
||||
"connectivity": ["bluetooth"],
|
||||
"debug": {
|
||||
"jlink_device": "nRF52832_xxAA",
|
||||
"svd_path": "nrf52.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino",
|
||||
"zephyr"
|
||||
],
|
||||
"frameworks": ["arduino", "zephyr"],
|
||||
"name": "Adafruit Bluefruit nRF52832 Feather",
|
||||
"upload": {
|
||||
"maximum_ram_size": 65536,
|
||||
|
@ -59,12 +42,7 @@
|
|||
"require_upload_port": true,
|
||||
"speed": 115200,
|
||||
"protocol": "nrfutil",
|
||||
"protocols": [
|
||||
"jlink",
|
||||
"nrfjprog",
|
||||
"nrfutil",
|
||||
"stlink"
|
||||
]
|
||||
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"]
|
||||
},
|
||||
"url": "https://www.adafruit.com/product/3406",
|
||||
"vendor": "Adafruit"
|
||||
|
|
|
@ -8,22 +8,10 @@
|
|||
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [
|
||||
[
|
||||
"0x239A",
|
||||
"0x8029"
|
||||
],
|
||||
[
|
||||
"0x239A",
|
||||
"0x0029"
|
||||
],
|
||||
[
|
||||
"0x239A",
|
||||
"0x002A"
|
||||
],
|
||||
[
|
||||
"0x239A",
|
||||
"0x802A"
|
||||
]
|
||||
["0x239A", "0x8029"],
|
||||
["0x239A", "0x0029"],
|
||||
["0x239A", "0x002A"],
|
||||
["0x239A", "0x802A"]
|
||||
],
|
||||
"usb_product": "WisCore RAK4631 Board",
|
||||
"mcu": "nrf52840",
|
||||
|
@ -41,28 +29,19 @@
|
|||
"settings_addr": "0xFF000"
|
||||
}
|
||||
},
|
||||
"connectivity": [
|
||||
"bluetooth"
|
||||
],
|
||||
"connectivity": ["bluetooth"],
|
||||
"debug": {
|
||||
"jlink_device": "nRF52840_xxAA",
|
||||
"svd_path": "nrf52840.svd"
|
||||
},
|
||||
"frameworks": [
|
||||
"arduino"
|
||||
],
|
||||
"frameworks": ["arduino"],
|
||||
"name": "WisCore RAK4631 Board",
|
||||
"upload": {
|
||||
"maximum_ram_size": 248832,
|
||||
"maximum_size": 815104,
|
||||
"speed": 115200,
|
||||
"protocol": "nrfutil",
|
||||
"protocols": [
|
||||
"jlink",
|
||||
"nrfjprog",
|
||||
"nrfutil",
|
||||
"stlink"
|
||||
],
|
||||
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
|
||||
"use_1200bps_touch": true,
|
||||
"require_upload_port": true,
|
||||
"wait_for_upload_port": true
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "configuration.h"
|
||||
#include "BluetoothCommon.h"
|
||||
#include "configuration.h"
|
||||
|
||||
// NRF52 wants these constants as byte arrays
|
||||
// Generated here https://yupana-engineering.com/online-uuid-to-c-array-converter - but in REVERSE BYTE ORDER
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
#include "configuration.h"
|
||||
#include "FSCommon.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
#include <SPI.h>
|
||||
#include <SD.h>
|
||||
|
||||
#include <SPI.h>
|
||||
|
||||
#ifdef SDCARD_USE_SPI1
|
||||
SPIClass SPI1(HSPI);
|
||||
#define SDHandler SPI1
|
||||
#endif
|
||||
|
||||
|
||||
#endif // HAS_SDCARD
|
||||
|
||||
bool copyFile(const char *from, const char *to)
|
||||
|
@ -168,8 +166,7 @@ void rmDir(const char * dirname)
|
|||
void fsInit()
|
||||
{
|
||||
#ifdef FSCom
|
||||
if (!FSBegin())
|
||||
{
|
||||
if (!FSBegin()) {
|
||||
LOG_ERROR("Filesystem mount Failed.\n");
|
||||
// assert(0); This auto-formats the partition, so no need to fail here.
|
||||
}
|
||||
|
@ -182,7 +179,6 @@ void fsInit()
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
void setupSDCard()
|
||||
{
|
||||
#ifdef HAS_SDCARD
|
||||
|
@ -214,6 +210,3 @@ void setupSDCard()
|
|||
LOG_DEBUG("Used space: %llu MB\n", SD.usedBytes() / (1024 * 1024));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -88,22 +88,31 @@ class GPSStatus : public Status
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t getDOP() const { return p.PDOP; }
|
||||
uint32_t getDOP() const
|
||||
{
|
||||
return p.PDOP;
|
||||
}
|
||||
|
||||
uint32_t getHeading() const { return p.ground_track; }
|
||||
uint32_t getHeading() const
|
||||
{
|
||||
return p.ground_track;
|
||||
}
|
||||
|
||||
uint32_t getNumSatellites() const { return p.sats_in_view; }
|
||||
uint32_t getNumSatellites() const
|
||||
{
|
||||
return p.sats_in_view;
|
||||
}
|
||||
|
||||
bool matches(const GPSStatus *newStatus) const
|
||||
{
|
||||
#ifdef GPS_EXTRAVERBOSE
|
||||
LOG_DEBUG("GPSStatus.match() new pos@%x to old pos@%x\n", newStatus->p.pos_timestamp, p.pos_timestamp);
|
||||
#endif
|
||||
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected || newStatus->isPowerSaving !=isPowerSaving ||
|
||||
newStatus->p.latitude_i != p.latitude_i || newStatus->p.longitude_i != p.longitude_i ||
|
||||
newStatus->p.altitude != p.altitude || newStatus->p.altitude_hae != p.altitude_hae ||
|
||||
newStatus->p.PDOP != p.PDOP || newStatus->p.ground_track != p.ground_track ||
|
||||
newStatus->p.ground_speed != p.ground_speed ||
|
||||
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected ||
|
||||
newStatus->isPowerSaving != isPowerSaving || newStatus->p.latitude_i != p.latitude_i ||
|
||||
newStatus->p.longitude_i != p.longitude_i || newStatus->p.altitude != p.altitude ||
|
||||
newStatus->p.altitude_hae != p.altitude_hae || newStatus->p.PDOP != p.PDOP ||
|
||||
newStatus->p.ground_track != p.ground_track || newStatus->p.ground_speed != p.ground_speed ||
|
||||
newStatus->p.sats_in_view != p.sats_in_view);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
#pragma once
|
||||
#include <Arduino.h>
|
||||
#include "Status.h"
|
||||
#include "configuration.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
namespace meshtastic {
|
||||
namespace meshtastic
|
||||
{
|
||||
|
||||
/// Describes the state of the NodeDB system.
|
||||
class NodeStatus : public Status
|
||||
{
|
||||
|
||||
private:
|
||||
CallbackObserver<NodeStatus, const NodeStatus *> statusObserver = CallbackObserver<NodeStatus, const NodeStatus *>(this, &NodeStatus::updateStatus);
|
||||
CallbackObserver<NodeStatus, const NodeStatus *> statusObserver =
|
||||
CallbackObserver<NodeStatus, const NodeStatus *>(this, &NodeStatus::updateStatus);
|
||||
|
||||
uint8_t numOnline = 0;
|
||||
uint8_t numTotal = 0;
|
||||
|
@ -20,9 +22,7 @@ namespace meshtastic {
|
|||
public:
|
||||
bool forceUpdate = false;
|
||||
|
||||
NodeStatus() {
|
||||
statusType = STATUS_TYPE_NODE;
|
||||
}
|
||||
NodeStatus() { statusType = STATUS_TYPE_NODE; }
|
||||
NodeStatus(uint8_t numOnline, uint8_t numTotal, bool forceUpdate = false) : Status()
|
||||
{
|
||||
this->forceUpdate = forceUpdate;
|
||||
|
@ -32,34 +32,20 @@ namespace meshtastic {
|
|||
NodeStatus(const NodeStatus &);
|
||||
NodeStatus &operator=(const NodeStatus &);
|
||||
|
||||
void observe(Observable<const NodeStatus *> *source)
|
||||
{
|
||||
statusObserver.observe(source);
|
||||
}
|
||||
void observe(Observable<const NodeStatus *> *source) { statusObserver.observe(source); }
|
||||
|
||||
uint8_t getNumOnline() const
|
||||
{
|
||||
return numOnline;
|
||||
}
|
||||
uint8_t getNumOnline() const { return numOnline; }
|
||||
|
||||
uint8_t getNumTotal() const
|
||||
{
|
||||
return numTotal;
|
||||
}
|
||||
uint8_t getNumTotal() const { return numTotal; }
|
||||
|
||||
uint8_t getLastNumTotal() const
|
||||
{
|
||||
return lastNumTotal;
|
||||
}
|
||||
uint8_t getLastNumTotal() const { return lastNumTotal; }
|
||||
|
||||
bool matches(const NodeStatus *newStatus) const
|
||||
{
|
||||
return (
|
||||
newStatus->getNumOnline() != numOnline ||
|
||||
newStatus->getNumTotal() != numTotal
|
||||
);
|
||||
return (newStatus->getNumOnline() != numOnline || newStatus->getNumTotal() != numTotal);
|
||||
}
|
||||
int updateStatus(const NodeStatus *newStatus) {
|
||||
int updateStatus(const NodeStatus *newStatus)
|
||||
{
|
||||
// Only update the status if values have actually changed
|
||||
lastNumTotal = numTotal;
|
||||
bool isDirty;
|
||||
|
@ -75,9 +61,8 @@ namespace meshtastic {
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace meshtastic
|
||||
|
||||
extern meshtastic::NodeStatus *nodeStatus;
|
|
@ -1,5 +1,5 @@
|
|||
#include "configuration.h"
|
||||
#include "OSTimer.h"
|
||||
#include "configuration.h"
|
||||
|
||||
/**
|
||||
* Schedule a callback to run. The callback must _not_ block, though it is called from regular thread level (not ISR)
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
#include "configuration.h"
|
||||
#include "Observer.h"
|
||||
|
||||
#include "configuration.h"
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
#include "power.h"
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "buzz/buzz.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include "sleep.h"
|
||||
#include "utils.h"
|
||||
#include "buzz/buzz.h"
|
||||
|
||||
#ifdef HAS_PMU
|
||||
#include "XPowersLibInterface.hpp"
|
||||
#include "XPowersAXP2101.tpp"
|
||||
#include "XPowersAXP192.tpp"
|
||||
#include "XPowersAXP2101.tpp"
|
||||
#include "XPowersLibInterface.hpp"
|
||||
XPowersLibInterface *PMU = NULL;
|
||||
#else
|
||||
// Copy of the base class defined in axp20x.h.
|
||||
|
@ -108,15 +108,15 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||
|
||||
#ifdef BATTERY_PIN
|
||||
// Override variant or default ADC_MULTIPLIER if we have the override pref
|
||||
float operativeAdcMultiplier = config.power.adc_multiplier_override > 0
|
||||
? config.power.adc_multiplier_override
|
||||
: ADC_MULTIPLIER;
|
||||
float operativeAdcMultiplier =
|
||||
config.power.adc_multiplier_override > 0 ? config.power.adc_multiplier_override : ADC_MULTIPLIER;
|
||||
// Do not call analogRead() often.
|
||||
const uint32_t min_read_interval = 5000;
|
||||
if (millis() - last_read_time_ms > min_read_interval) {
|
||||
last_read_time_ms = millis();
|
||||
|
||||
//Set the number of samples, it has an effect of increasing sensitivity, especially in complex electromagnetic environment.
|
||||
// Set the number of samples, it has an effect of increasing sensitivity, especially in complex electromagnetic
|
||||
// environment.
|
||||
uint32_t raw = 0;
|
||||
for (uint32_t i = 0; i < BATTERY_SENSE_SAMPLES; i++) {
|
||||
raw += analogRead(BATTERY_PIN);
|
||||
|
@ -143,15 +143,24 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
|||
/**
|
||||
* return true if there is a battery installed in this unit
|
||||
*/
|
||||
virtual bool isBatteryConnect() override { return getBatteryPercent() != -1; }
|
||||
virtual bool isBatteryConnect() override
|
||||
{
|
||||
return getBatteryPercent() != -1;
|
||||
}
|
||||
|
||||
/// If we see a battery voltage higher than physics allows - assume charger is pumping
|
||||
/// in power
|
||||
virtual bool isVbusIn() override { return getBattVoltage() > chargingVolt; }
|
||||
virtual bool isVbusIn() override
|
||||
{
|
||||
return getBattVoltage() > chargingVolt;
|
||||
}
|
||||
|
||||
/// Assume charging if we have a battery and external power is connected.
|
||||
/// we can't be smart enough to say 'full'?
|
||||
virtual bool isCharging() override { return isBatteryConnect() && isVbusIn(); }
|
||||
virtual bool isCharging() override
|
||||
{
|
||||
return isBatteryConnect() && isVbusIn();
|
||||
}
|
||||
|
||||
private:
|
||||
/// If we see a battery voltage higher than physics allows - assume charger is pumping
|
||||
|
@ -298,7 +307,8 @@ void Power::readPowerStatus()
|
|||
}
|
||||
}
|
||||
LOG_DEBUG("\n");
|
||||
LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads\n", ESP.getFreeHeap(), ESP.getHeapSize(), ESP.getFreeHeap() - lastheap, running, concurrency::mainController.size(false));
|
||||
LOG_DEBUG("Heap status: %d/%d bytes free (%d), running %d/%d threads\n", ESP.getFreeHeap(), ESP.getHeapSize(),
|
||||
ESP.getFreeHeap() - lastheap, running, concurrency::mainController.size(false));
|
||||
lastheap = ESP.getFreeHeap();
|
||||
}
|
||||
#endif
|
||||
|
@ -450,7 +460,6 @@ bool Power::axpChipInit()
|
|||
PMU->setPowerChannelVoltage(XPOWERS_LDO2, 3300);
|
||||
PMU->enablePowerOutput(XPOWERS_LDO2);
|
||||
|
||||
|
||||
// oled module power channel,
|
||||
// disable it will cause abnormal communication between boot and AXP power supply,
|
||||
// do not turn it off
|
||||
|
@ -458,12 +467,10 @@ bool Power::axpChipInit()
|
|||
// enable oled power
|
||||
PMU->enablePowerOutput(XPOWERS_DCDC1);
|
||||
|
||||
|
||||
// gnss module power channel - now turned on in setGpsPower
|
||||
PMU->setPowerChannelVoltage(XPOWERS_LDO3, 3300);
|
||||
// PMU->enablePowerOutput(XPOWERS_LDO3);
|
||||
|
||||
|
||||
// protected oled power source
|
||||
PMU->setProtectedChannel(XPOWERS_DCDC1);
|
||||
// protected esp32 power source
|
||||
|
@ -537,7 +544,6 @@ bool Power::axpChipInit()
|
|||
PMU->setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2);
|
||||
}
|
||||
|
||||
|
||||
PMU->clearIrqStatus();
|
||||
|
||||
// TBeam1.1 /T-Beam S3-Core has no external TS detection,
|
||||
|
@ -550,40 +556,52 @@ bool Power::axpChipInit()
|
|||
|
||||
LOG_DEBUG("=======================================================================\n");
|
||||
if (PMU->isChannelAvailable(XPOWERS_DCDC1)) {
|
||||
LOG_DEBUG("DC1 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC1));
|
||||
LOG_DEBUG("DC1 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-",
|
||||
PMU->getPowerChannelVoltage(XPOWERS_DCDC1));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_DCDC2)) {
|
||||
LOG_DEBUG("DC2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC2));
|
||||
LOG_DEBUG("DC2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-",
|
||||
PMU->getPowerChannelVoltage(XPOWERS_DCDC2));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_DCDC3)) {
|
||||
LOG_DEBUG("DC3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC3));
|
||||
LOG_DEBUG("DC3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-",
|
||||
PMU->getPowerChannelVoltage(XPOWERS_DCDC3));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_DCDC4)) {
|
||||
LOG_DEBUG("DC4 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC4));
|
||||
LOG_DEBUG("DC4 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-",
|
||||
PMU->getPowerChannelVoltage(XPOWERS_DCDC4));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_LDO2)) {
|
||||
LOG_DEBUG("LDO2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO2));
|
||||
LOG_DEBUG("LDO2 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-",
|
||||
PMU->getPowerChannelVoltage(XPOWERS_LDO2));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_LDO3)) {
|
||||
LOG_DEBUG("LDO3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO3));
|
||||
LOG_DEBUG("LDO3 : %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-",
|
||||
PMU->getPowerChannelVoltage(XPOWERS_LDO3));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_ALDO1)) {
|
||||
LOG_DEBUG("ALDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO1));
|
||||
LOG_DEBUG("ALDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-",
|
||||
PMU->getPowerChannelVoltage(XPOWERS_ALDO1));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_ALDO2)) {
|
||||
LOG_DEBUG("ALDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO2));
|
||||
LOG_DEBUG("ALDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-",
|
||||
PMU->getPowerChannelVoltage(XPOWERS_ALDO2));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_ALDO3)) {
|
||||
LOG_DEBUG("ALDO3: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO3));
|
||||
LOG_DEBUG("ALDO3: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-",
|
||||
PMU->getPowerChannelVoltage(XPOWERS_ALDO3));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_ALDO4)) {
|
||||
LOG_DEBUG("ALDO4: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO4));
|
||||
LOG_DEBUG("ALDO4: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-",
|
||||
PMU->getPowerChannelVoltage(XPOWERS_ALDO4));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_BLDO1)) {
|
||||
LOG_DEBUG("BLDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO1));
|
||||
LOG_DEBUG("BLDO1: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-",
|
||||
PMU->getPowerChannelVoltage(XPOWERS_BLDO1));
|
||||
}
|
||||
if (PMU->isChannelAvailable(XPOWERS_BLDO2)) {
|
||||
LOG_DEBUG("BLDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO2));
|
||||
LOG_DEBUG("BLDO2: %s Voltage:%u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-",
|
||||
PMU->getPowerChannelVoltage(XPOWERS_BLDO2));
|
||||
}
|
||||
LOG_DEBUG("=======================================================================\n");
|
||||
|
||||
|
@ -597,7 +615,6 @@ bool Power::axpChipInit()
|
|||
PMU->setSysPowerDownVoltage(2600);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef PMU_IRQ
|
||||
uint64_t pmuIrqMask = 0;
|
||||
|
||||
|
|
|
@ -199,7 +199,8 @@ static void onEnter()
|
|||
|
||||
uint32_t now = millis();
|
||||
|
||||
if ((now - lastPingMs) > 30 * 1000) { // if more than a minute since our last press, ask node we are looking at to update their state
|
||||
if ((now - lastPingMs) >
|
||||
30 * 1000) { // if more than a minute since our last press, ask node we are looking at to update their state
|
||||
if (displayedNodeNum)
|
||||
service.sendNetworkPing(displayedNodeNum, true); // Refresh the currently displayed node
|
||||
lastPingMs = now;
|
||||
|
@ -249,7 +250,8 @@ void PowerFSM_setup()
|
|||
|
||||
// We need this transition, because we might not transition if we were waiting to enter light-sleep, because when we wake from
|
||||
// light sleep we _always_ transition to NB or dark and
|
||||
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, exiting light sleep");
|
||||
powerFSM.add_transition(&stateLS, isRouter ? &stateNB : &stateDARK, EVENT_PACKET_FOR_PHONE, NULL,
|
||||
"Received packet, exiting light sleep");
|
||||
powerFSM.add_transition(&stateNB, &stateNB, EVENT_PACKET_FOR_PHONE, NULL, "Received packet, resetting win wake");
|
||||
|
||||
// Handle press events - note: we ignore button presses when in API mode
|
||||
|
@ -258,7 +260,8 @@ void PowerFSM_setup()
|
|||
powerFSM.add_transition(&stateDARK, &stateON, EVENT_PRESS, NULL, "Press");
|
||||
powerFSM.add_transition(&statePOWER, &statePOWER, EVENT_PRESS, screenPress, "Press");
|
||||
powerFSM.add_transition(&stateON, &stateON, EVENT_PRESS, screenPress, "Press"); // reenter On to restart our timers
|
||||
powerFSM.add_transition(&stateSERIAL, &stateSERIAL, EVENT_PRESS, screenPress, "Press"); // Allow button to work while in serial API
|
||||
powerFSM.add_transition(&stateSERIAL, &stateSERIAL, EVENT_PRESS, screenPress,
|
||||
"Press"); // Allow button to work while in serial API
|
||||
|
||||
// Handle critically low power battery by forcing deep sleep
|
||||
powerFSM.add_transition(&stateBOOT, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
|
||||
|
@ -324,7 +327,9 @@ void PowerFSM_setup()
|
|||
|
||||
powerFSM.add_transition(&stateDARK, &stateDARK, EVENT_CONTACT_FROM_PHONE, NULL, "Contact from phone");
|
||||
|
||||
powerFSM.add_timed_transition(&stateON, &stateDARK, getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL, "Screen-on timeout");
|
||||
powerFSM.add_timed_transition(&stateON, &stateDARK,
|
||||
getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
|
||||
"Screen-on timeout");
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
State *lowPowerState = &stateLS;
|
||||
|
@ -332,14 +337,18 @@ void PowerFSM_setup()
|
|||
|
||||
// See: https://github.com/meshtastic/firmware/issues/1071
|
||||
if (isRouter || config.power.is_power_saving) {
|
||||
powerFSM.add_timed_transition(&stateNB, &stateLS, getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL, "Min wake timeout");
|
||||
powerFSM.add_timed_transition(&stateDARK, &stateLS, getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs), NULL, "Bluetooth timeout");
|
||||
powerFSM.add_timed_transition(&stateNB, &stateLS,
|
||||
getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL,
|
||||
"Min wake timeout");
|
||||
powerFSM.add_timed_transition(&stateDARK, &stateLS,
|
||||
getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs),
|
||||
NULL, "Bluetooth timeout");
|
||||
}
|
||||
|
||||
if (config.power.sds_secs != UINT32_MAX)
|
||||
powerFSM.add_timed_transition(lowPowerState, &stateSDS, getConfiguredOrDefaultMs(config.power.sds_secs), NULL, "mesh timeout");
|
||||
powerFSM.add_timed_transition(lowPowerState, &stateSDS, getConfiguredOrDefaultMs(config.power.sds_secs), NULL,
|
||||
"mesh timeout");
|
||||
#endif
|
||||
|
||||
|
||||
powerFSM.run_machine(); // run one interation of the state machine, so we run our on enter tasks for the initial DARK state
|
||||
}
|
||||
|
|
|
@ -26,9 +26,10 @@ class PowerFSMThread : public OSThread
|
|||
|
||||
if (powerStatus->getHasUSB()) {
|
||||
timeLastPowered = millis();
|
||||
} else if (config.power.on_battery_shutdown_after_secs > 0 &&
|
||||
config.power.on_battery_shutdown_after_secs != UINT32_MAX &&
|
||||
millis() > (timeLastPowered + getConfiguredOrDefaultMs(config.power.on_battery_shutdown_after_secs))) { // shutdown after 30 minutes unpowered
|
||||
} else if (config.power.on_battery_shutdown_after_secs > 0 && config.power.on_battery_shutdown_after_secs != UINT32_MAX &&
|
||||
millis() > (timeLastPowered +
|
||||
getConfiguredOrDefaultMs(
|
||||
config.power.on_battery_shutdown_after_secs))) { // shutdown after 30 minutes unpowered
|
||||
powerFSM.trigger(EVENT_SHUTDOWN);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#include "configuration.h"
|
||||
#include "RedirectablePrint.h"
|
||||
#include "RTC.h"
|
||||
#include "NodeDB.h"
|
||||
#include "RTC.h"
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "configuration.h"
|
||||
#include <assert.h>
|
||||
#include <cstring>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <cstring>
|
||||
|
||||
/**
|
||||
* A printer that doesn't go anywhere
|
||||
|
@ -42,7 +42,8 @@ size_t RedirectablePrint::vprintf(const char *format, va_list arg)
|
|||
size_t len = vsnprintf(printBuf, sizeof(printBuf), format, copy);
|
||||
va_end(copy);
|
||||
|
||||
// If the resulting string is longer than sizeof(printBuf)-1 characters, the remaining characters are still counted for the return value
|
||||
// If the resulting string is longer than sizeof(printBuf)-1 characters, the remaining characters are still counted for the
|
||||
// return value
|
||||
|
||||
if (len > sizeof(printBuf) - 1) {
|
||||
len = sizeof(printBuf) - 1;
|
||||
|
@ -104,7 +105,8 @@ size_t RedirectablePrint::log(const char *logLevel, const char *format, ...)
|
|||
return r;
|
||||
}
|
||||
|
||||
void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16_t len) {
|
||||
void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16_t len)
|
||||
{
|
||||
const char alphabet[17] = "0123456789abcdef";
|
||||
log(logLevel, " +------------------------------------------------+ +----------------+\n");
|
||||
log(logLevel, " |.0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f | | ASCII |\n");
|
||||
|
@ -119,12 +121,15 @@ void RedirectablePrint::hexDump(const char *logLevel, unsigned char *buf, uint16
|
|||
s[ix++] = alphabet[(c >> 4) & 0x0F];
|
||||
s[ix++] = alphabet[c & 0x0F];
|
||||
ix++;
|
||||
if (c > 31 && c < 128) s[iy++] = c;
|
||||
else s[iy++] = '.';
|
||||
if (c > 31 && c < 128)
|
||||
s[iy++] = c;
|
||||
else
|
||||
s[iy++] = '.';
|
||||
}
|
||||
}
|
||||
uint8_t index = i / 16;
|
||||
if (i < 256) log(logLevel, " ");
|
||||
if (i < 256)
|
||||
log(logLevel, " ");
|
||||
log(logLevel, "%02x", index);
|
||||
log(logLevel, ".");
|
||||
log(logLevel, s);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "configuration.h"
|
||||
#include "SPILock.h"
|
||||
#include "configuration.h"
|
||||
#include <Arduino.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
|
|
@ -49,7 +49,8 @@ int32_t SerialConsole::runOnce()
|
|||
return runOncePart();
|
||||
}
|
||||
|
||||
void SerialConsole::flush() {
|
||||
void SerialConsole::flush()
|
||||
{
|
||||
Port.flush();
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ class SerialConsole : public StreamAPI, public RedirectablePrint, private concur
|
|||
void flush();
|
||||
|
||||
protected:
|
||||
|
||||
/// Check the current underlying physical link to see if the client is currently connected
|
||||
virtual bool checkIsConnected() override;
|
||||
};
|
||||
|
|
36
src/Status.h
36
src/Status.h
|
@ -8,7 +8,6 @@
|
|||
#define STATUS_TYPE_GPS 2
|
||||
#define STATUS_TYPE_NODE 3
|
||||
|
||||
|
||||
namespace meshtastic
|
||||
{
|
||||
|
||||
|
@ -17,7 +16,8 @@ namespace meshtastic
|
|||
{
|
||||
protected:
|
||||
// Allows us to observe an Observable
|
||||
CallbackObserver<Status, const Status *> statusObserver = CallbackObserver<Status, const Status *>(this, &Status::updateStatus);
|
||||
CallbackObserver<Status, const Status *> statusObserver =
|
||||
CallbackObserver<Status, const Status *>(this, &Status::updateStatus);
|
||||
bool initialized = false;
|
||||
// Workaround for no typeid support
|
||||
int statusType = 0;
|
||||
|
@ -29,9 +29,9 @@ namespace meshtastic
|
|||
// Enable polymorphism ?
|
||||
virtual ~Status() = default;
|
||||
|
||||
Status() {
|
||||
if (!statusType)
|
||||
Status()
|
||||
{
|
||||
if (!statusType) {
|
||||
statusType = STATUS_TYPE_BASE;
|
||||
}
|
||||
}
|
||||
|
@ -41,32 +41,16 @@ namespace meshtastic
|
|||
Status &operator=(const Status &) = delete;
|
||||
|
||||
// Start observing a source of data
|
||||
void observe(Observable<const Status *> *source)
|
||||
{
|
||||
statusObserver.observe(source);
|
||||
}
|
||||
void observe(Observable<const Status *> *source) { statusObserver.observe(source); }
|
||||
|
||||
// Determines whether or not existing data matches the data in another Status instance
|
||||
bool matches(const Status *otherStatus) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool matches(const Status *otherStatus) const { return true; }
|
||||
|
||||
bool isInitialized() const
|
||||
{
|
||||
return initialized;
|
||||
}
|
||||
bool isInitialized() const { return initialized; }
|
||||
|
||||
int getStatusType() const
|
||||
{
|
||||
return statusType;
|
||||
}
|
||||
int getStatusType() const { return statusType; }
|
||||
|
||||
// Called when the Observable we're observing generates a new notification
|
||||
int updateStatus(const Status *newStatus)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
};
|
||||
int updateStatus(const Status *newStatus) { return 0; }
|
||||
};
|
||||
}; // namespace meshtastic
|
||||
|
|
|
@ -34,11 +34,13 @@ uint8_t AirTime::currentPeriodIndex()
|
|||
return ((getSecondsSinceBoot() / SECONDS_PER_PERIOD) % PERIODS_TO_LOG);
|
||||
}
|
||||
|
||||
uint8_t AirTime::getPeriodUtilMinute() {
|
||||
uint8_t AirTime::getPeriodUtilMinute()
|
||||
{
|
||||
return (getSecondsSinceBoot() / 10) % CHANNEL_UTILIZATION_PERIODS;
|
||||
}
|
||||
|
||||
uint8_t AirTime::getPeriodUtilHour() {
|
||||
uint8_t AirTime::getPeriodUtilHour()
|
||||
{
|
||||
return (getSecondsSinceBoot() / 60) % MINUTES_IN_HOUR;
|
||||
}
|
||||
|
||||
|
@ -128,14 +130,14 @@ bool AirTime::isTxAllowedChannelUtil(bool polite)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
bool AirTime::isTxAllowedAirUtil()
|
||||
{
|
||||
if (!config.lora.override_duty_cycle && myRegion->dutyCycle < 100) {
|
||||
if (utilizationTXPercent() < myRegion->dutyCycle * polite_duty_cycle_percent / 100) {
|
||||
return true;
|
||||
} else {
|
||||
LOG_WARN("Tx air utilization is >%f percent. Skipping this opportunity to send.\n", myRegion->dutyCycle * polite_duty_cycle_percent / 100);
|
||||
LOG_WARN("Tx air utilization is >%f percent. Skipping this opportunity to send.\n",
|
||||
myRegion->dutyCycle * polite_duty_cycle_percent / 100);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -155,9 +157,7 @@ uint8_t AirTime::getSilentMinutes(float txPercent, float dutyCycle)
|
|||
return MINUTES_IN_HOUR;
|
||||
}
|
||||
|
||||
|
||||
AirTime::AirTime() : concurrency::OSThread("AirTime"),airtimes({}) {
|
||||
}
|
||||
AirTime::AirTime() : concurrency::OSThread("AirTime"), airtimes({}) {}
|
||||
|
||||
int32_t AirTime::runOnce()
|
||||
{
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include "MeshRadio.h"
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "configuration.h"
|
||||
#include <Arduino.h>
|
||||
#include <functional>
|
||||
#include "MeshRadio.h"
|
||||
|
||||
/*
|
||||
TX_LOG - Time on air this device has transmitted
|
||||
|
@ -33,7 +33,6 @@
|
|||
#define MS_IN_MINUTE (SECONDS_IN_MINUTE * 1000)
|
||||
#define MS_IN_HOUR (MINUTES_IN_HOUR * SECONDS_IN_MINUTE * 1000)
|
||||
|
||||
|
||||
enum reportTypes { TX_LOG, RX_LOG, RX_ALL_LOG };
|
||||
|
||||
void logAirtime(reportTypes reportType, uint32_t airtime_ms);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "buzz.h"
|
||||
#include "configuration.h"
|
||||
#include "NodeDB.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#if !defined(ARCH_ESP32) && !defined(ARCH_RP2040) && !defined(ARCH_PORTDUINO)
|
||||
#include "Tone.h"
|
||||
|
@ -33,7 +33,8 @@ struct ToneDuration {
|
|||
const int DURATION_1_8 = 125; // 1/8 note
|
||||
const int DURATION_1_4 = 250; // 1/4 note
|
||||
|
||||
void playTones(const ToneDuration *tone_durations, int size) {
|
||||
void playTones(const ToneDuration *tone_durations, int size)
|
||||
{
|
||||
#ifdef PIN_BUZZER
|
||||
if (!config.device.buzzer_gpio)
|
||||
config.device.buzzer_gpio = PIN_BUZZER;
|
||||
|
@ -48,22 +49,20 @@ void playTones(const ToneDuration *tone_durations, int size) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void playBeep() {
|
||||
void playBeep()
|
||||
{
|
||||
ToneDuration melody[] = {{NOTE_B3, DURATION_1_4}};
|
||||
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
||||
}
|
||||
|
||||
void playStartMelody() {
|
||||
ToneDuration melody[] = {{NOTE_FS3, DURATION_1_8},
|
||||
{NOTE_AS3, DURATION_1_8},
|
||||
{NOTE_CS4, DURATION_1_4}};
|
||||
void playStartMelody()
|
||||
{
|
||||
ToneDuration melody[] = {{NOTE_FS3, DURATION_1_8}, {NOTE_AS3, DURATION_1_8}, {NOTE_CS4, DURATION_1_4}};
|
||||
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
||||
}
|
||||
|
||||
void playShutdownMelody() {
|
||||
ToneDuration melody[] = {{NOTE_CS4, DURATION_1_8},
|
||||
{NOTE_AS3, DURATION_1_8},
|
||||
{NOTE_FS3, DURATION_1_4}};
|
||||
void playShutdownMelody()
|
||||
{
|
||||
ToneDuration melody[] = {{NOTE_CS4, DURATION_1_8}, {NOTE_AS3, DURATION_1_8}, {NOTE_FS3, DURATION_1_4}};
|
||||
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "configuration.h"
|
||||
#include "concurrency/BinarySemaphoreFreeRTOS.h"
|
||||
#include "configuration.h"
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef HAS_FREE_RTOS
|
||||
|
|
|
@ -1,18 +1,14 @@
|
|||
#include "configuration.h"
|
||||
#include "concurrency/BinarySemaphorePosix.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#ifndef HAS_FREE_RTOS
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
|
||||
BinarySemaphorePosix::BinarySemaphorePosix()
|
||||
{
|
||||
}
|
||||
BinarySemaphorePosix::BinarySemaphorePosix() {}
|
||||
|
||||
BinarySemaphorePosix::~BinarySemaphorePosix()
|
||||
{
|
||||
}
|
||||
BinarySemaphorePosix::~BinarySemaphorePosix() {}
|
||||
|
||||
/**
|
||||
* Returns false if we timed out
|
||||
|
@ -23,13 +19,9 @@ bool BinarySemaphorePosix::take(uint32_t msec)
|
|||
return false;
|
||||
}
|
||||
|
||||
void BinarySemaphorePosix::give()
|
||||
{
|
||||
}
|
||||
void BinarySemaphorePosix::give() {}
|
||||
|
||||
IRAM_ATTR void BinarySemaphorePosix::giveFromISR(BaseType_t *pxHigherPriorityTaskWoken)
|
||||
{
|
||||
}
|
||||
IRAM_ATTR void BinarySemaphorePosix::giveFromISR(BaseType_t *pxHigherPriorityTaskWoken) {}
|
||||
|
||||
} // namespace concurrency
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "configuration.h"
|
||||
#include "concurrency/InterruptableDelay.h"
|
||||
#include "configuration.h"
|
||||
|
||||
namespace concurrency
|
||||
{
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include "../freertosinc.h"
|
||||
|
||||
|
||||
#ifdef HAS_FREE_RTOS
|
||||
#include "concurrency/BinarySemaphoreFreeRTOS.h"
|
||||
#define BinarySemaphore BinarySemaphoreFreeRTOS
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "configuration.h"
|
||||
#include "Lock.h"
|
||||
#include "configuration.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace concurrency
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include "configuration.h"
|
||||
#include "LockGuard.h"
|
||||
#include "configuration.h"
|
||||
|
||||
namespace concurrency {
|
||||
namespace concurrency
|
||||
{
|
||||
|
||||
LockGuard::LockGuard(Lock *lock) : lock(lock)
|
||||
{
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
#include "Lock.h"
|
||||
|
||||
namespace concurrency {
|
||||
namespace concurrency
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief RAII lock guard
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "configuration.h"
|
||||
#include "NotifiedWorkerThread.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
|
||||
namespace concurrency
|
||||
|
@ -80,8 +80,6 @@ void NotifiedWorkerThread::checkNotification()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32_t NotifiedWorkerThread::runOnce()
|
||||
{
|
||||
enabled = false; // Only run once per notification
|
||||
|
|
|
@ -41,9 +41,9 @@ class NotifiedWorkerThread : public OSThread
|
|||
/// just calls checkNotification()
|
||||
virtual int32_t runOnce() override;
|
||||
|
||||
/// Sometimes we might want to check notifications independently of when our thread was getting woken up (i.e. if we are about to change
|
||||
/// radio transmit/receive modes we want to handle any pending interrupts first). You can call this method and if any notifications are currently
|
||||
/// pending they will be handled immediately.
|
||||
/// Sometimes we might want to check notifications independently of when our thread was getting woken up (i.e. if we are about
|
||||
/// to change radio transmit/receive modes we want to handle any pending interrupts first). You can call this method and if
|
||||
/// any notifications are currently pending they will be handled immediately.
|
||||
void checkNotification();
|
||||
|
||||
private:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "configuration.h"
|
||||
#include "OSThread.h"
|
||||
#include "configuration.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace concurrency
|
||||
|
|
|
@ -42,7 +42,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#error APP_VERSION must be set by the build environment
|
||||
#endif
|
||||
|
||||
// FIXME: This is still needed by the Bluetooth Stack and needs to be replaced by something better. Remnant of the old versioning system.
|
||||
// FIXME: This is still needed by the Bluetooth Stack and needs to be replaced by something better. Remnant of the old versioning
|
||||
// system.
|
||||
#ifndef HW_VERSION
|
||||
#define HW_VERSION "1.0"
|
||||
#endif
|
||||
|
@ -175,8 +176,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#define HAS_BLUETOOTH 0
|
||||
#endif
|
||||
|
||||
#include "RF95Configuration.h"
|
||||
#include "DebugConfiguration.h"
|
||||
#include "RF95Configuration.h"
|
||||
|
||||
#ifndef HW_VENDOR
|
||||
#error HW_VENDOR must be defined
|
||||
|
|
|
@ -7,41 +7,48 @@
|
|||
void d_writeCommand(uint8_t c)
|
||||
{
|
||||
SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
|
||||
if (PIN_EINK_DC >= 0) digitalWrite(PIN_EINK_DC, LOW);
|
||||
if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, LOW);
|
||||
if (PIN_EINK_DC >= 0)
|
||||
digitalWrite(PIN_EINK_DC, LOW);
|
||||
if (PIN_EINK_CS >= 0)
|
||||
digitalWrite(PIN_EINK_CS, LOW);
|
||||
SPI1.transfer(c);
|
||||
if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, HIGH);
|
||||
if (PIN_EINK_DC >= 0) digitalWrite(PIN_EINK_DC, HIGH);
|
||||
if (PIN_EINK_CS >= 0)
|
||||
digitalWrite(PIN_EINK_CS, HIGH);
|
||||
if (PIN_EINK_DC >= 0)
|
||||
digitalWrite(PIN_EINK_DC, HIGH);
|
||||
SPI1.endTransaction();
|
||||
}
|
||||
|
||||
void d_writeData(uint8_t d)
|
||||
{
|
||||
SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
|
||||
if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, LOW);
|
||||
if (PIN_EINK_CS >= 0)
|
||||
digitalWrite(PIN_EINK_CS, LOW);
|
||||
SPI1.transfer(d);
|
||||
if (PIN_EINK_CS >= 0) digitalWrite(PIN_EINK_CS, HIGH);
|
||||
if (PIN_EINK_CS >= 0)
|
||||
digitalWrite(PIN_EINK_CS, HIGH);
|
||||
SPI1.endTransaction();
|
||||
}
|
||||
|
||||
unsigned long d_waitWhileBusy(uint16_t busy_time)
|
||||
{
|
||||
if (PIN_EINK_BUSY >= 0)
|
||||
{
|
||||
if (PIN_EINK_BUSY >= 0) {
|
||||
delay(1); // add some margin to become active
|
||||
unsigned long start = micros();
|
||||
while (1)
|
||||
{
|
||||
if (digitalRead(PIN_EINK_BUSY) != HIGH) break;
|
||||
while (1) {
|
||||
if (digitalRead(PIN_EINK_BUSY) != HIGH)
|
||||
break;
|
||||
delay(1);
|
||||
if (digitalRead(PIN_EINK_BUSY) != HIGH) break;
|
||||
if (micros() - start > 10000000) break;
|
||||
if (digitalRead(PIN_EINK_BUSY) != HIGH)
|
||||
break;
|
||||
if (micros() - start > 10000000)
|
||||
break;
|
||||
}
|
||||
unsigned long elapsed = micros() - start;
|
||||
(void)start;
|
||||
return elapsed;
|
||||
}
|
||||
else return busy_time;
|
||||
} else
|
||||
return busy_time;
|
||||
}
|
||||
|
||||
void scanEInkDevice(void)
|
||||
|
|
|
@ -21,7 +21,8 @@ GPS *gps;
|
|||
/// only init that port once.
|
||||
static bool didSerialInit;
|
||||
|
||||
bool GPS::getACK(uint8_t c, uint8_t i) {
|
||||
bool GPS::getACK(uint8_t c, uint8_t i)
|
||||
{
|
||||
uint8_t b;
|
||||
uint8_t ack = 0;
|
||||
const uint8_t ackP[2] = {c, i};
|
||||
|
@ -50,8 +51,7 @@ bool GPS::getACK(uint8_t c, uint8_t i) {
|
|||
b = _serial_gps->read();
|
||||
if (b == buf[ack]) {
|
||||
ack++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
ack = 0;
|
||||
}
|
||||
}
|
||||
|
@ -178,8 +178,8 @@ if (!config.position.tx_gpio)
|
|||
* t-beam-s3-core uses the same L76K GNSS module as t-echo.
|
||||
* Unlike t-echo, L76K uses 9600 baud rate for communication by default.
|
||||
* */
|
||||
// _serial_gps->begin(9600); //The baud rate of 9600 has been initialized at the beginning of setupGPS, this line is the redundant part
|
||||
// delay(250);
|
||||
// _serial_gps->begin(9600); //The baud rate of 9600 has been initialized at the beginning of setupGPS, this line
|
||||
// is the redundant part delay(250);
|
||||
|
||||
// Initialize the L76K Chip, use GPS + GLONASS
|
||||
_serial_gps->write("$PCAS04,5*1C\r\n");
|
||||
|
@ -210,7 +210,8 @@ if (!config.position.tx_gpio)
|
|||
// ublox-M10S can be compatible with UBLOX traditional protocol, so the following sentence settings are also valid
|
||||
|
||||
// disable GGL
|
||||
byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x05, 0x3A};
|
||||
byte _message_GGL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01,
|
||||
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x05, 0x3A};
|
||||
_serial_gps->write(_message_GGL, sizeof(_message_GGL));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
LOG_WARN("Unable to disable NMEA GGL.\n");
|
||||
|
@ -218,7 +219,8 @@ if (!config.position.tx_gpio)
|
|||
}
|
||||
|
||||
// disable GSA
|
||||
byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x41};
|
||||
byte _message_GSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02,
|
||||
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x41};
|
||||
_serial_gps->write(_message_GSA, sizeof(_message_GSA));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
LOG_WARN("Unable to disable NMEA GSA.\n");
|
||||
|
@ -226,7 +228,8 @@ if (!config.position.tx_gpio)
|
|||
}
|
||||
|
||||
// disable GSV
|
||||
byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x48};
|
||||
byte _message_GSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03,
|
||||
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x48};
|
||||
_serial_gps->write(_message_GSV, sizeof(_message_GSV));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
LOG_WARN("Unable to disable NMEA GSV.\n");
|
||||
|
@ -234,7 +237,8 @@ if (!config.position.tx_gpio)
|
|||
}
|
||||
|
||||
// disable VTG
|
||||
byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x09, 0x56};
|
||||
byte _message_VTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05,
|
||||
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x09, 0x56};
|
||||
_serial_gps->write(_message_VTG, sizeof(_message_VTG));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
LOG_WARN("Unable to disable NMEA VTG.\n");
|
||||
|
@ -242,7 +246,8 @@ if (!config.position.tx_gpio)
|
|||
}
|
||||
|
||||
// enable RMC
|
||||
byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09, 0x54};
|
||||
byte _message_RMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09, 0x54};
|
||||
_serial_gps->write(_message_RMC, sizeof(_message_RMC));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
LOG_WARN("Unable to enable NMEA RMC.\n");
|
||||
|
@ -250,7 +255,8 @@ if (!config.position.tx_gpio)
|
|||
}
|
||||
|
||||
// enable GGA
|
||||
byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x38};
|
||||
byte _message_GGA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x05, 0x38};
|
||||
_serial_gps->write(_message_GGA, sizeof(_message_GGA));
|
||||
if (!getACK(0x06, 0x01)) {
|
||||
LOG_WARN("Unable to enable NMEA GGA.\n");
|
||||
|
@ -574,7 +580,6 @@ GnssModel_t GPS::probe()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x0E, 0x30};
|
||||
_serial_gps->write(cfg_rate, sizeof(cfg_rate));
|
||||
// Check that the returned response class and message ID are correct
|
||||
|
@ -662,8 +667,7 @@ GPS *createGps()
|
|||
new_gps->setup();
|
||||
return new_gps;
|
||||
}
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
GPS *new_gps = new NMEAGPS();
|
||||
new_gps->setup();
|
||||
return new_gps;
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include "Observer.h"
|
||||
#include "concurrency/OSThread.h"
|
||||
|
||||
|
||||
struct uBloxGnssModelInfo {
|
||||
char swVersion[30];
|
||||
char hwVersion[10];
|
||||
|
|
|
@ -1,21 +1,25 @@
|
|||
#include "GeoCoord.h"
|
||||
|
||||
GeoCoord::GeoCoord() {
|
||||
GeoCoord::GeoCoord()
|
||||
{
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
GeoCoord::GeoCoord (int32_t lat, int32_t lon, int32_t alt) : _latitude(lat), _longitude(lon), _altitude(alt) {
|
||||
GeoCoord::GeoCoord(int32_t lat, int32_t lon, int32_t alt) : _latitude(lat), _longitude(lon), _altitude(alt)
|
||||
{
|
||||
GeoCoord::setCoords();
|
||||
}
|
||||
|
||||
GeoCoord::GeoCoord (float lat, float lon, int32_t alt) : _altitude(alt) {
|
||||
GeoCoord::GeoCoord(float lat, float lon, int32_t alt) : _altitude(alt)
|
||||
{
|
||||
// Change decimial reprsentation to int32_t. I.e., 12.345 becomes 123450000
|
||||
_latitude = int32_t(lat * 1e+7);
|
||||
_longitude = int32_t(lon * 1e+7);
|
||||
GeoCoord::setCoords();
|
||||
}
|
||||
|
||||
GeoCoord::GeoCoord(double lat, double lon, int32_t alt): _altitude(alt) {
|
||||
GeoCoord::GeoCoord(double lat, double lon, int32_t alt) : _altitude(alt)
|
||||
{
|
||||
// Change decimial reprsentation to int32_t. I.e., 12.345 becomes 123450000
|
||||
_latitude = int32_t(lat * 1e+7);
|
||||
_longitude = int32_t(lon * 1e+7);
|
||||
|
@ -23,7 +27,8 @@ GeoCoord::GeoCoord(double lat, double lon, int32_t alt): _altitude(alt) {
|
|||
}
|
||||
|
||||
// Initialize all the coordinate systems
|
||||
void GeoCoord::setCoords() {
|
||||
void GeoCoord::setCoords()
|
||||
{
|
||||
double lat = _latitude * 1e-7;
|
||||
double lon = _longitude * 1e-7;
|
||||
GeoCoord::latLongToDMS(lat, lon, _dms);
|
||||
|
@ -34,7 +39,8 @@ void GeoCoord::setCoords() {
|
|||
_dirty = false;
|
||||
}
|
||||
|
||||
void GeoCoord::updateCoords(int32_t lat, int32_t lon, int32_t alt) {
|
||||
void GeoCoord::updateCoords(int32_t lat, int32_t lon, int32_t alt)
|
||||
{
|
||||
// If marked dirty or new coordiantes
|
||||
if (_dirty || _latitude != lat || _longitude != lon || _altitude != alt) {
|
||||
_dirty = true;
|
||||
|
@ -45,7 +51,8 @@ void GeoCoord::updateCoords(int32_t lat, int32_t lon, int32_t alt) {
|
|||
}
|
||||
}
|
||||
|
||||
void GeoCoord::updateCoords(const double lat, const double lon, const int32_t alt) {
|
||||
void GeoCoord::updateCoords(const double lat, const double lon, const int32_t alt)
|
||||
{
|
||||
int32_t iLat = lat * 1e+7;
|
||||
int32_t iLon = lon * 1e+7;
|
||||
// If marked dirty or new coordiantes
|
||||
|
@ -56,10 +63,10 @@ void GeoCoord::updateCoords(const double lat, const double lon, const int32_t al
|
|||
_altitude = alt;
|
||||
setCoords();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GeoCoord::updateCoords(const float lat, const float lon, const int32_t alt) {
|
||||
void GeoCoord::updateCoords(const float lat, const float lon, const int32_t alt)
|
||||
{
|
||||
int32_t iLat = lat * 1e+7;
|
||||
int32_t iLon = lon * 1e+7;
|
||||
// If marked dirty or new coordiantes
|
||||
|
@ -76,9 +83,12 @@ void GeoCoord::updateCoords(const float lat, const float lon, const int32_t alt)
|
|||
* Converts lat long coordinates from decimal degrees to degrees minutes seconds format.
|
||||
* DD°MM'SS"C DDD°MM'SS"C
|
||||
*/
|
||||
void GeoCoord::latLongToDMS(const double lat, const double lon, DMS &dms) {
|
||||
if (lat < 0) dms.latCP = 'S';
|
||||
else dms.latCP = 'N';
|
||||
void GeoCoord::latLongToDMS(const double lat, const double lon, DMS &dms)
|
||||
{
|
||||
if (lat < 0)
|
||||
dms.latCP = 'S';
|
||||
else
|
||||
dms.latCP = 'N';
|
||||
|
||||
double latDeg = lat;
|
||||
|
||||
|
@ -90,8 +100,10 @@ void GeoCoord::latLongToDMS(const double lat, const double lon, DMS &dms) {
|
|||
dms.latMin = floor(latMin);
|
||||
dms.latSec = (latMin - dms.latMin) * 60;
|
||||
|
||||
if (lon < 0) dms.lonCP = 'W';
|
||||
else dms.lonCP = 'E';
|
||||
if (lon < 0)
|
||||
dms.lonCP = 'W';
|
||||
else
|
||||
dms.lonCP = 'E';
|
||||
|
||||
double lonDeg = lon;
|
||||
|
||||
|
@ -108,7 +120,8 @@ void GeoCoord::latLongToDMS(const double lat, const double lon, DMS &dms) {
|
|||
* Converts lat long coordinates to UTM.
|
||||
* based on this: https://github.com/walvok/LatLonToUTM/blob/master/latlon_utm.ino
|
||||
*/
|
||||
void GeoCoord::latLongToUTM(const double lat, const double lon, UTM &utm) {
|
||||
void GeoCoord::latLongToUTM(const double lat, const double lon, UTM &utm)
|
||||
{
|
||||
|
||||
const std::string latBands = "CDEFGHJKLMNPQRSTUVWXX";
|
||||
utm.zone = int((lon + 180) / 6 + 1);
|
||||
|
@ -124,10 +137,14 @@ void GeoCoord::latLongToUTM(const double lat, const double lon, UTM &utm) {
|
|||
if (lat >= 56.0 && lat < 64.0 && lonTemp >= 3.0 && lonTemp < 12.0) // Norway
|
||||
utm.zone = 32;
|
||||
if (lat >= 72.0 && lat < 84.0) { // Svalbard
|
||||
if ( lonTemp >= 0.0 && lonTemp < 9.0 ) utm.zone = 31;
|
||||
else if( lonTemp >= 9.0 && lonTemp < 21.0 ) utm.zone = 33;
|
||||
else if( lonTemp >= 21.0 && lonTemp < 33.0 ) utm.zone = 35;
|
||||
else if( lonTemp >= 33.0 && lonTemp < 42.0 ) utm.zone = 37;
|
||||
if (lonTemp >= 0.0 && lonTemp < 9.0)
|
||||
utm.zone = 31;
|
||||
else if (lonTemp >= 9.0 && lonTemp < 21.0)
|
||||
utm.zone = 33;
|
||||
else if (lonTemp >= 21.0 && lonTemp < 33.0)
|
||||
utm.zone = 35;
|
||||
else if (lonTemp >= 33.0 && lonTemp < 42.0)
|
||||
utm.zone = 37;
|
||||
}
|
||||
|
||||
double lonOrigin = (utm.zone - 1) * 6 - 180 + 3; // puts origin in middle of zone
|
||||
|
@ -137,21 +154,28 @@ void GeoCoord::latLongToUTM(const double lat, const double lon, UTM &utm) {
|
|||
double T = tan(latRad) * tan(latRad);
|
||||
double C = eccPrimeSquared * cos(latRad) * cos(latRad);
|
||||
double A = cos(latRad) * (lonRad - lonOriginRad);
|
||||
double M = a*((1 - eccSquared/4 - 3*eccSquared*eccSquared/64 - 5*eccSquared*eccSquared*eccSquared/256)*latRad
|
||||
- (3*eccSquared/8 + 3*eccSquared*eccSquared/32 + 45*eccSquared*eccSquared*eccSquared/1024)*sin(2*latRad)
|
||||
+ (15*eccSquared*eccSquared/256 + 45*eccSquared*eccSquared*eccSquared/1024)*sin(4*latRad)
|
||||
- (35*eccSquared*eccSquared*eccSquared/3072)*sin(6*latRad));
|
||||
utm.easting = (double)(k0*N*(A+(1-T+C)*pow(A, 3)/6 + (5-18*T+T*T+72*C-58*eccPrimeSquared)*A*A*A*A*A/120)
|
||||
+ 500000.0);
|
||||
utm.northing = (double)(k0*(M+N*tan(latRad)*(A*A/2+(5-T+9*C+4*C*C)*A*A*A*A/24
|
||||
+ (61-58*T+T*T+600*C-330*eccPrimeSquared)*A*A*A*A*A*A/720)));
|
||||
double M =
|
||||
a * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256) * latRad -
|
||||
(3 * eccSquared / 8 + 3 * eccSquared * eccSquared / 32 + 45 * eccSquared * eccSquared * eccSquared / 1024) *
|
||||
sin(2 * latRad) +
|
||||
(15 * eccSquared * eccSquared / 256 + 45 * eccSquared * eccSquared * eccSquared / 1024) * sin(4 * latRad) -
|
||||
(35 * eccSquared * eccSquared * eccSquared / 3072) * sin(6 * latRad));
|
||||
utm.easting = (double)(k0 * N *
|
||||
(A + (1 - T + C) * pow(A, 3) / 6 +
|
||||
(5 - 18 * T + T * T + 72 * C - 58 * eccPrimeSquared) * A * A * A * A * A / 120) +
|
||||
500000.0);
|
||||
utm.northing =
|
||||
(double)(k0 * (M + N * tan(latRad) *
|
||||
(A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24 +
|
||||
(61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared) * A * A * A * A * A * A / 720)));
|
||||
|
||||
if (lat < 0)
|
||||
utm.northing += 10000000.0; // 10000000 meter offset for southern hemisphere
|
||||
}
|
||||
|
||||
// Converts lat long coordinates to an MGRS.
|
||||
void GeoCoord::latLongToMGRS(const double lat, const double lon, MGRS &mgrs) {
|
||||
void GeoCoord::latLongToMGRS(const double lat, const double lon, MGRS &mgrs)
|
||||
{
|
||||
const std::string e100kLetters[3] = {"ABCDEFGH", "JKLMNPQR", "STUVWXYZ"};
|
||||
const std::string n100kLetters[2] = {"ABCDEFGHJKLMNPQRSTUV", "FGHJKLMNPQRSTUVABCDE"};
|
||||
UTM utm;
|
||||
|
@ -170,7 +194,8 @@ void GeoCoord::latLongToMGRS(const double lat, const double lon, MGRS &mgrs) {
|
|||
* Converts lat long coordinates to Ordnance Survey Grid Reference (UK National Grid Ref).
|
||||
* Based on: https://www.movable-type.co.uk/scripts/latlong-os-gridref.html
|
||||
*/
|
||||
void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr) {
|
||||
void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr)
|
||||
{
|
||||
const char letter[] = "ABCDEFGHJKLMNOPQRSTUVWXYZ"; // No 'I' in OSGR
|
||||
double a = 6377563.396; // Airy 1830 semi-major axis
|
||||
double b = 6356256.909; // Airy 1830 semi-minor axis
|
||||
|
@ -211,7 +236,8 @@ void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr) {
|
|||
|
||||
double deltaLambda = lambda - lambda0;
|
||||
double deltaLambda2 = deltaLambda * deltaLambda;
|
||||
double northing = I + II*deltaLambda2 + III*deltaLambda2*deltaLambda2 + IIIA*deltaLambda2*deltaLambda2*deltaLambda2;
|
||||
double northing =
|
||||
I + II * deltaLambda2 + III * deltaLambda2 * deltaLambda2 + IIIA * deltaLambda2 * deltaLambda2 * deltaLambda2;
|
||||
double easting = e0 + IV * deltaLambda + V * deltaLambda2 * deltaLambda + VI * deltaLambda2 * deltaLambda2 * deltaLambda;
|
||||
|
||||
if (easting < 0 || easting > 700000 || northing < 0 || northing > 1300000) // Check if out of boundaries
|
||||
|
@ -232,7 +258,8 @@ void GeoCoord::latLongToOSGR(const double lat, const double lon, OSGR &osgr) {
|
|||
* Converts lat long coordinates to Open Location Code.
|
||||
* Based on: https://github.com/google/open-location-code/blob/main/c/src/olc.c
|
||||
*/
|
||||
void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc) {
|
||||
void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc)
|
||||
{
|
||||
char tempCode[] = "1234567890abc";
|
||||
const char kAlphabet[] = "23456789CFGHJMPQRVWX";
|
||||
double latitude;
|
||||
|
@ -304,7 +331,8 @@ void GeoCoord::latLongToOLC(double lat, double lon, OLC &olc) {
|
|||
}
|
||||
|
||||
// Converts the coordinate in WGS84 datum to the OSGB36 datum.
|
||||
void GeoCoord::convertWGS84ToOSGB36(const double lat, const double lon, double &osgb_Latitude, double &osgb_Longitude) {
|
||||
void GeoCoord::convertWGS84ToOSGB36(const double lat, const double lon, double &osgb_Latitude, double &osgb_Longitude)
|
||||
{
|
||||
// Convert lat long to cartesian
|
||||
double phi = toRadians(lat);
|
||||
double lambda = toRadians(lon);
|
||||
|
@ -340,7 +368,8 @@ void GeoCoord::convertWGS84ToOSGB36(const double lat, const double lon, double &
|
|||
double tanBeta = (airyB * osgbZ) / (airyA * p) * (1 + airyEcc2 * airyB / R);
|
||||
double sinBeta = tanBeta / sqrt(1 + tanBeta * tanBeta);
|
||||
double cosBeta = sinBeta / tanBeta;
|
||||
osgb_Latitude = atan2(osgbZ + airyEcc2*airyB*sinBeta*sinBeta*sinBeta, p - airyEcc*airyA*cosBeta*cosBeta*cosBeta); // leave in radians
|
||||
osgb_Latitude = atan2(osgbZ + airyEcc2 * airyB * sinBeta * sinBeta * sinBeta,
|
||||
p - airyEcc * airyA * cosBeta * cosBeta * cosBeta); // leave in radians
|
||||
osgb_Longitude = atan2(osgbY, osgbX); // leave in radians
|
||||
// osgb height = p*cos(osgb.latitude) + osgbZ*sin(osgb.latitude) -
|
||||
//(airyA*airyA/(airyA / sqrt(1 - airyEcc*sin(osgb.latitude)*sin(osgb.latitude)))); // Not used, no OSTN data
|
||||
|
@ -399,7 +428,8 @@ float GeoCoord::bearing(double lat1, double lon1, double lat2, double lon2)
|
|||
* The range in meters
|
||||
* @return range in radians on a great circle
|
||||
*/
|
||||
float GeoCoord::rangeMetersToRadians(double range_meters) {
|
||||
float GeoCoord::rangeMetersToRadians(double range_meters)
|
||||
{
|
||||
// 1 nm is 1852 meters
|
||||
double distance_nm = range_meters * 1852;
|
||||
return (PI / (180 * 60)) * distance_nm;
|
||||
|
@ -412,20 +442,25 @@ float GeoCoord::rangeMetersToRadians(double range_meters) {
|
|||
* The range in radians
|
||||
* @return Range in meters on a great circle
|
||||
*/
|
||||
float GeoCoord::rangeRadiansToMeters(double range_radians) {
|
||||
float GeoCoord::rangeRadiansToMeters(double range_radians)
|
||||
{
|
||||
double distance_nm = ((180 * 60) / PI) * range_radians;
|
||||
// 1 meter is 0.000539957 nm
|
||||
return distance_nm * 0.000539957;
|
||||
}
|
||||
|
||||
// Find distance from point to passed in point
|
||||
int32_t GeoCoord::distanceTo(const GeoCoord& pointB) {
|
||||
return latLongToMeter(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7, pointB.getLongitude() * 1e-7);
|
||||
int32_t GeoCoord::distanceTo(const GeoCoord &pointB)
|
||||
{
|
||||
return latLongToMeter(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7,
|
||||
pointB.getLongitude() * 1e-7);
|
||||
}
|
||||
|
||||
// Find bearing from point to passed in point
|
||||
int32_t GeoCoord::bearingTo(const GeoCoord& pointB) {
|
||||
return bearing(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7, pointB.getLongitude() * 1e-7);
|
||||
int32_t GeoCoord::bearingTo(const GeoCoord &pointB)
|
||||
{
|
||||
return bearing(this->getLatitude() * 1e-7, this->getLongitude() * 1e-7, pointB.getLatitude() * 1e-7,
|
||||
pointB.getLongitude() * 1e-7);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -437,7 +472,8 @@ int32_t GeoCoord::bearingTo(const GeoCoord& pointB) {
|
|||
* range in meters
|
||||
* @return GeoCoord object of point at bearing and range from initial point
|
||||
*/
|
||||
std::shared_ptr<GeoCoord> GeoCoord::pointAtDistance(double bearing, double range_meters) {
|
||||
std::shared_ptr<GeoCoord> GeoCoord::pointAtDistance(double bearing, double range_meters)
|
||||
{
|
||||
double range_radians = rangeMetersToRadians(range_meters);
|
||||
double lat1 = this->getLatitude() * 1e-7;
|
||||
double lon1 = this->getLongitude() * 1e-7;
|
||||
|
@ -446,5 +482,4 @@ std::shared_ptr<GeoCoord> GeoCoord::pointAtDistance(double bearing, double range
|
|||
double lon = fmod(lon1 - dlon + PI, 2 * PI) - PI;
|
||||
|
||||
return std::make_shared<GeoCoord>(double(lat), double(lon), this->getAltitude());
|
||||
|
||||
}
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
#define OLC_CODE_LEN 11
|
||||
|
||||
// Helper functions
|
||||
// Raises a number to an exponent, handling negative exponents.
|
||||
static inline double pow_neg(double base, double exponent) {
|
||||
static inline double pow_neg(double base, double exponent)
|
||||
{
|
||||
if (exponent == 0) {
|
||||
return 1;
|
||||
} else if (exponent > 0) {
|
||||
|
@ -35,8 +36,7 @@ static inline double toDegrees(double r)
|
|||
|
||||
// GeoCoord structs/classes
|
||||
// A struct to hold the data for a DMS coordinate.
|
||||
struct DMS
|
||||
{
|
||||
struct DMS {
|
||||
uint8_t latDeg;
|
||||
uint8_t latMin;
|
||||
uint32_t latSec;
|
||||
|
@ -48,8 +48,7 @@ struct DMS
|
|||
};
|
||||
|
||||
// A struct to hold the data for a UTM coordinate, this is also used when creating an MGRS coordinate.
|
||||
struct UTM
|
||||
{
|
||||
struct UTM {
|
||||
uint8_t zone;
|
||||
char band;
|
||||
uint32_t easting;
|
||||
|
@ -57,8 +56,7 @@ struct UTM
|
|||
};
|
||||
|
||||
// A struct to hold the data for a MGRS coordinate.
|
||||
struct MGRS
|
||||
{
|
||||
struct MGRS {
|
||||
uint8_t zone;
|
||||
char band;
|
||||
char east100k;
|
||||
|
@ -80,7 +78,8 @@ struct OLC {
|
|||
char code[OLC_CODE_LEN + 1]; // +1 for null termination
|
||||
};
|
||||
|
||||
class GeoCoord {
|
||||
class GeoCoord
|
||||
{
|
||||
private:
|
||||
int32_t _latitude = 0;
|
||||
int32_t _longitude = 0;
|
||||
|
@ -161,4 +160,3 @@ class GeoCoord {
|
|||
// OLC getter
|
||||
void getOLCCode(char *code) { strncpy(code, _olc.code, OLC_CODE_LEN + 1); } // +1 for null termination
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "configuration.h"
|
||||
#include "NMEAGPS.h"
|
||||
#include "RTC.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#include <TinyGPS++.h>
|
||||
|
||||
|
@ -29,9 +29,8 @@ bool NMEAGPS::factoryReset()
|
|||
|
||||
// send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's UBLOX.
|
||||
// Factory Reset
|
||||
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF,
|
||||
0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
|
||||
byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
|
||||
_serial_gps->write(_message_reset, sizeof(_message_reset));
|
||||
delay(1000);
|
||||
return true;
|
||||
|
@ -85,7 +84,8 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
|
|||
t.tm_year = d.year() - 1900;
|
||||
t.tm_isdst = false;
|
||||
if (t.tm_mon > -1) {
|
||||
LOG_DEBUG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
|
||||
LOG_DEBUG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min,
|
||||
t.tm_sec);
|
||||
perhapsSetRTC(RTCQualityGPS, t);
|
||||
return true;
|
||||
} else
|
||||
|
@ -117,8 +117,7 @@ bool NMEAGPS::lookForLocation()
|
|||
return false;
|
||||
|
||||
#ifdef GPS_EXTRAVERBOSE
|
||||
LOG_DEBUG("AGE: LOC=%d FIX=%d DATE=%d TIME=%d\n",
|
||||
reader.location.age(),
|
||||
LOG_DEBUG("AGE: LOC=%d FIX=%d DATE=%d TIME=%d\n", reader.location.age(),
|
||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||
gsafixtype.age(),
|
||||
#else
|
||||
|
@ -134,9 +133,7 @@ bool NMEAGPS::lookForLocation()
|
|||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||
(gsafixtype.age() < GPS_SOL_EXPIRY_MS) &&
|
||||
#endif
|
||||
(reader.time.age() < GPS_SOL_EXPIRY_MS) &&
|
||||
(reader.date.age() < GPS_SOL_EXPIRY_MS)))
|
||||
{
|
||||
(reader.time.age() < GPS_SOL_EXPIRY_MS) && (reader.date.age() < GPS_SOL_EXPIRY_MS))) {
|
||||
LOG_WARN("SOME data is TOO OLD: LOC %u, TIME %u, DATE %u\n", reader.location.age(), reader.time.age(), reader.date.age());
|
||||
return false;
|
||||
}
|
||||
|
@ -210,10 +207,10 @@ bool NMEAGPS::lookForLocation()
|
|||
|
||||
if (reader.course.isUpdated() && reader.course.isValid()) {
|
||||
if (reader.course.value() < 36000) { // sanity check
|
||||
p.ground_track = reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5
|
||||
p.ground_track =
|
||||
reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5
|
||||
} else {
|
||||
LOG_WARN("BOGUS course.value() REJECTED: %d\n",
|
||||
reader.course.value());
|
||||
LOG_WARN("BOGUS course.value() REJECTED: %d\n", reader.course.value());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -224,7 +221,6 @@ bool NMEAGPS::lookForLocation()
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NMEAGPS::hasLock()
|
||||
{
|
||||
// Using GPGGA fix quality indicator
|
||||
|
|
|
@ -19,14 +19,10 @@
|
|||
uint32_t printWPL(char *buf, size_t bufsz, const Position &pos, const char *name)
|
||||
{
|
||||
GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude);
|
||||
uint32_t len = snprintf(buf, bufsz, "$GNWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s",
|
||||
geoCoord.getDMSLatDeg(),
|
||||
(abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6,
|
||||
geoCoord.getDMSLatCP(),
|
||||
geoCoord.getDMSLonDeg(),
|
||||
(abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
|
||||
geoCoord.getDMSLonCP(),
|
||||
name);
|
||||
uint32_t len = snprintf(buf, bufsz, "$GNWPL,%02d%07.4f,%c,%03d%07.4f,%c,%s", geoCoord.getDMSLatDeg(),
|
||||
(abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6, geoCoord.getDMSLatCP(),
|
||||
geoCoord.getDMSLonDeg(), (abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
|
||||
geoCoord.getDMSLonCP(), name);
|
||||
uint32_t chk = 0;
|
||||
for (uint32_t i = 1; i < len; i++) {
|
||||
chk ^= buf[i];
|
||||
|
@ -51,35 +47,21 @@ uint32_t printWPL(char *buf, size_t bufsz, const Position &pos, const char *name
|
|||
* 8 Horizontal Dilution of precision (meters)
|
||||
* 9 Antenna Altitude above/below mean-sea-level (geoid) (in meters)
|
||||
* 10 Units of antenna altitude, meters
|
||||
* 11 Geoidal separation, the difference between the WGS-84 earth ellipsoid and mean-sea-level (geoid), "-" means mean-sea-level below ellipsoid
|
||||
* 12 Units of geoidal separation, meters
|
||||
* 13 Age of differential GPS data, time in seconds since last SC104 type 1 or 9 update, null field when DGPS is not used
|
||||
* 14 Differential reference station ID, 0000-1023
|
||||
* 15 Checksum
|
||||
* 11 Geoidal separation, the difference between the WGS-84 earth ellipsoid and mean-sea-level (geoid), "-" means mean-sea-level
|
||||
* below ellipsoid 12 Units of geoidal separation, meters 13 Age of differential GPS data, time in seconds since last SC104 type 1
|
||||
* or 9 update, null field when DGPS is not used 14 Differential reference station ID, 0000-1023 15 Checksum
|
||||
* -------------------------------------------
|
||||
*/
|
||||
|
||||
uint32_t printGGA(char *buf, size_t bufsz, const Position &pos)
|
||||
{
|
||||
GeoCoord geoCoord(pos.latitude_i, pos.longitude_i, pos.altitude);
|
||||
uint32_t len = snprintf(buf, bufsz, "$GNGGA,%06u.%03u,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d",
|
||||
pos.time / 1000,
|
||||
pos.time % 1000,
|
||||
geoCoord.getDMSLatDeg(),
|
||||
(abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6,
|
||||
geoCoord.getDMSLatCP(),
|
||||
geoCoord.getDMSLonDeg(),
|
||||
(abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6,
|
||||
geoCoord.getDMSLonCP(),
|
||||
pos.fix_type,
|
||||
pos.sats_in_view,
|
||||
pos.HDOP,
|
||||
geoCoord.getAltitude(),
|
||||
'M',
|
||||
pos.altitude_geoidal_separation,
|
||||
'M',
|
||||
0,
|
||||
0);
|
||||
uint32_t len =
|
||||
snprintf(buf, bufsz, "$GNGGA,%06u.%03u,%02d%07.4f,%c,%03d%07.4f,%c,%u,%02u,%04u,%04d,%c,%04d,%c,%d,%04d", pos.time / 1000,
|
||||
pos.time % 1000, geoCoord.getDMSLatDeg(), (abs(geoCoord.getLatitude()) - geoCoord.getDMSLatDeg() * 1e+7) * 6e-6,
|
||||
geoCoord.getDMSLatCP(), geoCoord.getDMSLonDeg(),
|
||||
(abs(geoCoord.getLongitude()) - geoCoord.getDMSLonDeg() * 1e+7) * 6e-6, geoCoord.getDMSLonCP(), pos.fix_type,
|
||||
pos.sats_in_view, pos.HDOP, geoCoord.getAltitude(), 'M', pos.altitude_geoidal_separation, 'M', 0, 0);
|
||||
|
||||
uint32_t chk = 0;
|
||||
for (uint32_t i = 1; i < len; i++) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "main.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
uint32_t printWPL(char *buf, size_t bufsz, const Position &pos, const char *name);
|
||||
uint32_t printGGA(char *buf, size_t bufsz, const Position &pos);
|
||||
|
|
|
@ -91,8 +91,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
|
|||
// Every 12 hrs we will slam in a new GPS time, to correct for local RTC clock drift
|
||||
shouldSet = true;
|
||||
LOG_DEBUG("Reapplying external time to correct clock drift %ld secs\n", tv->tv_sec);
|
||||
}
|
||||
else
|
||||
} else
|
||||
shouldSet = false;
|
||||
|
||||
if (shouldSet) {
|
||||
|
@ -109,7 +108,8 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
|
|||
rtc.initI2C();
|
||||
tm *t = localtime(&tv->tv_sec);
|
||||
rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
||||
LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
|
||||
LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
|
||||
t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
|
||||
}
|
||||
#elif defined(PCF8563_RTC)
|
||||
if (rtc_found == PCF8563_RTC) {
|
||||
|
@ -121,7 +121,8 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
|
|||
#endif
|
||||
tm *t = localtime(&tv->tv_sec);
|
||||
rtc.setDateTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
||||
LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
|
||||
LOG_DEBUG("PCF8563_RTC setDateTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
|
||||
t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
|
||||
}
|
||||
#elif defined(ARCH_ESP32)
|
||||
settimeofday(tv, NULL);
|
||||
|
|
|
@ -8,7 +8,8 @@ const uint8_t SATELLITE_IMAGE[] PROGMEM = {0x00, 0x08, 0x00, 0x1C, 0x00, 0x0E, 0
|
|||
|
||||
const uint8_t imgSatellite[] PROGMEM = {0x70, 0x71, 0x22, 0xFA, 0xFA, 0x22, 0x71, 0x70};
|
||||
const uint8_t imgUSB[] PROGMEM = {0x60, 0x60, 0x30, 0x18, 0x18, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x7E, 0x24, 0x24, 0x24, 0x3C};
|
||||
const uint8_t imgPower[] PROGMEM = { 0x40, 0x40, 0x40, 0x58, 0x48, 0x08, 0x08, 0x08, 0x1C, 0x22, 0x22, 0x41, 0x7F, 0x22, 0x22, 0x22 };
|
||||
const uint8_t imgPower[] PROGMEM = {0x40, 0x40, 0x40, 0x58, 0x48, 0x08, 0x08, 0x08,
|
||||
0x1C, 0x22, 0x22, 0x41, 0x7F, 0x22, 0x22, 0x22};
|
||||
const uint8_t imgUser[] PROGMEM = {0x3C, 0x42, 0x99, 0xA5, 0xA5, 0x99, 0x42, 0x3C};
|
||||
const uint8_t imgPositionEmpty[] PROGMEM = {0x20, 0x30, 0x28, 0x24, 0x42, 0xFF};
|
||||
const uint8_t imgPositionSolid[] PROGMEM = {0x20, 0x30, 0x38, 0x3C, 0x7E, 0xFF};
|
||||
|
@ -18,8 +19,10 @@ const uint8_t imgQuestionL1[] PROGMEM = { 0xff, 0x01, 0x01, 0x32, 0x7b, 0
|
|||
const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};
|
||||
const uint8_t imgInfoL1[] PROGMEM = {0xff, 0x01, 0x01, 0x01, 0x1e, 0x7f, 0x1e, 0x01, 0x01, 0x01, 0x01, 0xff};
|
||||
const uint8_t imgInfoL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};
|
||||
const uint8_t imgSFL1[] PROGMEM = { 0xb6, 0x8f, 0x19, 0x11, 0x31, 0xe3, 0xc2, 0x01, 0x01, 0xf9, 0xf9, 0x89, 0x89, 0x89, 0x09, 0xeb};
|
||||
const uint8_t imgSFL2[] PROGMEM = { 0x0e, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x00, 0x0f, 0x0f, 0x00, 0x08, 0x08, 0x08, 0x0f};
|
||||
const uint8_t imgSFL1[] PROGMEM = {0xb6, 0x8f, 0x19, 0x11, 0x31, 0xe3, 0xc2, 0x01,
|
||||
0x01, 0xf9, 0xf9, 0x89, 0x89, 0x89, 0x09, 0xeb};
|
||||
const uint8_t imgSFL2[] PROGMEM = {0x0e, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08,
|
||||
0x00, 0x0f, 0x0f, 0x00, 0x08, 0x08, 0x08, 0x0f};
|
||||
#else
|
||||
const uint8_t imgInfo[] PROGMEM = {0xff, 0x81, 0x00, 0xfb, 0xfb, 0x00, 0x81, 0xff};
|
||||
const uint8_t imgQuestion[] PROGMEM = {0xbf, 0x41, 0xc0, 0x8b, 0xdb, 0x70, 0xa1, 0xdf};
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
|
||||
InputBroker *inputBroker;
|
||||
|
||||
InputBroker::InputBroker()
|
||||
{
|
||||
};
|
||||
InputBroker::InputBroker(){};
|
||||
|
||||
void InputBroker::registerSource(Observable<const InputEvent *> *source)
|
||||
{
|
||||
|
|
|
@ -9,8 +9,7 @@ typedef struct _InputEvent {
|
|||
char inputEvent;
|
||||
char kbchar;
|
||||
} InputEvent;
|
||||
class InputBroker :
|
||||
public Observable<const InputEvent *>
|
||||
class InputBroker : public Observable<const InputEvent *>
|
||||
{
|
||||
CallbackObserver<InputBroker, const InputEvent *> inputEventObserver =
|
||||
CallbackObserver<InputBroker, const InputEvent *>(this, &InputBroker::handleInputEvent);
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
* to your device as you wish, but you always need to have separate event
|
||||
* handlers, thus you need to have a RotaryEncoderInterrupt implementation.
|
||||
*/
|
||||
class RotaryEncoderInterruptImpl1 :
|
||||
public RotaryEncoderInterruptBase
|
||||
class RotaryEncoderInterruptImpl1 : public RotaryEncoderInterruptBase
|
||||
{
|
||||
public:
|
||||
RotaryEncoderInterruptImpl1();
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
#include "configuration.h"
|
||||
#include "UpDownInterruptBase.h"
|
||||
#include "configuration.h"
|
||||
|
||||
UpDownInterruptBase::UpDownInterruptBase(
|
||||
const char *name)
|
||||
UpDownInterruptBase::UpDownInterruptBase(const char *name)
|
||||
{
|
||||
this->_originName = name;
|
||||
}
|
||||
|
||||
void UpDownInterruptBase::init(
|
||||
uint8_t pinDown, uint8_t pinUp, uint8_t pinPress,
|
||||
char eventDown, char eventUp, char eventPressed,
|
||||
void UpDownInterruptBase::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinPress, char eventDown, char eventUp, char eventPressed,
|
||||
void (*onIntDown)(), void (*onIntUp)(), void (*onIntPress)())
|
||||
{
|
||||
this->_pinDown = pinDown;
|
||||
|
@ -26,8 +23,7 @@ void UpDownInterruptBase::init(
|
|||
attachInterrupt(this->_pinDown, onIntDown, RISING);
|
||||
attachInterrupt(this->_pinUp, onIntUp, RISING);
|
||||
|
||||
LOG_DEBUG("GPIO initialized (%d, %d, %d)\n",
|
||||
this->_pinDown, this->_pinUp, pinPress);
|
||||
LOG_DEBUG("GPIO initialized (%d, %d, %d)\n", this->_pinDown, this->_pinUp, pinPress);
|
||||
}
|
||||
|
||||
void UpDownInterruptBase::intPressHandler()
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#pragma once
|
||||
#include "UpDownInterruptBase.h"
|
||||
|
||||
class UpDownInterruptImpl1 :
|
||||
public UpDownInterruptBase
|
||||
class UpDownInterruptImpl1 : public UpDownInterruptBase
|
||||
{
|
||||
public:
|
||||
UpDownInterruptImpl1();
|
||||
|
|
|
@ -3,15 +3,11 @@
|
|||
|
||||
CardKbI2cImpl *cardKbI2cImpl;
|
||||
|
||||
CardKbI2cImpl::CardKbI2cImpl() :
|
||||
KbI2cBase("cardKB")
|
||||
{
|
||||
}
|
||||
CardKbI2cImpl::CardKbI2cImpl() : KbI2cBase("cardKB") {}
|
||||
|
||||
void CardKbI2cImpl::init()
|
||||
{
|
||||
if (cardkb_found != CARDKB_ADDR)
|
||||
{
|
||||
if (cardkb_found != CARDKB_ADDR) {
|
||||
disable();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
* to your device as you wish, but you always need to have separate event
|
||||
* handlers, thus you need to have a RotaryEncoderInterrupt implementation.
|
||||
*/
|
||||
class CardKbI2cImpl :
|
||||
public KbI2cBase
|
||||
class CardKbI2cImpl : public KbI2cBase
|
||||
{
|
||||
public:
|
||||
CardKbI2cImpl();
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "SinglePortModule.h" // TODO: what header file to include?
|
||||
#include "InputBroker.h"
|
||||
#include "SinglePortModule.h" // TODO: what header file to include?
|
||||
|
||||
class KbI2cBase :
|
||||
public Observable<const InputEvent *>,
|
||||
public concurrency::OSThread
|
||||
class KbI2cBase : public Observable<const InputEvent *>, public concurrency::OSThread
|
||||
{
|
||||
public:
|
||||
explicit KbI2cBase(const char *name);
|
||||
|
|
|
@ -267,8 +267,7 @@ const char *Channels::getName(size_t chIndex)
|
|||
channelName = "Invalid";
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
channelName = "Custom";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ class Channels
|
|||
int16_t hashes[MAX_NUM_CHANNELS] = {};
|
||||
|
||||
public:
|
||||
|
||||
Channels() {}
|
||||
|
||||
/// Well known channel names
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "configuration.h"
|
||||
#include "CryptoEngine.h"
|
||||
#include "configuration.h"
|
||||
|
||||
void CryptoEngine::setKey(const CryptoKey &k)
|
||||
{
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#include "SX126xInterface.h"
|
||||
#include "SX126xInterface.cpp"
|
||||
#include "SX128xInterface.h"
|
||||
#include "SX126xInterface.h"
|
||||
#include "SX128xInterface.cpp"
|
||||
#include "api/ServerAPI.h"
|
||||
#include "SX128xInterface.h"
|
||||
#include "api/ServerAPI.cpp"
|
||||
#include "api/ServerAPI.h"
|
||||
|
||||
// We need this declaration for proper linking in derived classes
|
||||
template class SX126xInterface<SX1262>;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "configuration.h"
|
||||
#include "LLCC68Interface.h"
|
||||
#include "configuration.h"
|
||||
#include "error.h"
|
||||
|
||||
LLCC68Interface::LLCC68Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "configuration.h"
|
||||
#include "MeshModule.h"
|
||||
#include "Channels.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "configuration.h"
|
||||
#include "modules/RoutingModule.h"
|
||||
#include <assert.h>
|
||||
|
||||
|
@ -106,8 +106,8 @@ void MeshModule::callPlugins(const MeshPacket &mp, RxSource src)
|
|||
/// Is the channel this packet arrived on acceptable? (security check)
|
||||
/// Note: we can't know channel names for encrypted packets, so those are NEVER sent to boundChannel modules
|
||||
|
||||
/// 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.
|
||||
/// 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) || (strcasecmp(ch->settings.name, pi.boundChannel) == 0);
|
||||
|
||||
|
@ -175,8 +175,7 @@ void MeshModule::callPlugins(const MeshPacket &mp, RxSource src)
|
|||
}
|
||||
|
||||
if (!moduleFound)
|
||||
LOG_DEBUG("No modules interested in portnum=%d, src=%s\n",
|
||||
mp.decoded.portnum,
|
||||
LOG_DEBUG("No modules interested in portnum=%d, src=%s\n", mp.decoded.portnum,
|
||||
(src == RX_SRC_LOCAL) ? "LOCAL" : "REMOTE");
|
||||
}
|
||||
|
||||
|
@ -235,14 +234,12 @@ std::vector<MeshModule *> MeshModule::GetMeshModulesWithUIFrames()
|
|||
return modulesWithUIFrames;
|
||||
}
|
||||
|
||||
void MeshModule::observeUIEvents(
|
||||
Observer<const UIFrameEvent *> *observer)
|
||||
void MeshModule::observeUIEvents(Observer<const UIFrameEvent *> *observer)
|
||||
{
|
||||
if (modules) {
|
||||
for (auto i = modules->begin(); i != modules->end(); ++i) {
|
||||
auto &pi = **i;
|
||||
Observable<const UIFrameEvent *> *observable =
|
||||
pi.getUIFrameObservable();
|
||||
Observable<const UIFrameEvent *> *observable = pi.getUIFrameObservable();
|
||||
if (observable != NULL) {
|
||||
LOG_DEBUG("Module wants a UI Frame\n");
|
||||
observer->observe(observable);
|
||||
|
@ -251,24 +248,19 @@ void MeshModule::observeUIEvents(
|
|||
}
|
||||
}
|
||||
|
||||
AdminMessageHandleResult MeshModule::handleAdminMessageForAllPlugins(const MeshPacket &mp, AdminMessage *request, AdminMessage *response)
|
||||
AdminMessageHandleResult MeshModule::handleAdminMessageForAllPlugins(const MeshPacket &mp, AdminMessage *request,
|
||||
AdminMessage *response)
|
||||
{
|
||||
AdminMessageHandleResult handled = AdminMessageHandleResult::NOT_HANDLED;
|
||||
if (modules) {
|
||||
for (auto i = modules->begin(); i != modules->end(); ++i) {
|
||||
auto &pi = **i;
|
||||
AdminMessageHandleResult h = pi.handleAdminMessageForModule(mp, request, response);
|
||||
if (h == AdminMessageHandleResult::HANDLED_WITH_RESPONSE)
|
||||
{
|
||||
if (h == AdminMessageHandleResult::HANDLED_WITH_RESPONSE) {
|
||||
// In case we have a response it always has priority.
|
||||
LOG_DEBUG("Reply prepared by module '%s' of variant: %d\n",
|
||||
pi.name,
|
||||
response->which_payload_variant);
|
||||
LOG_DEBUG("Reply prepared by module '%s' of variant: %d\n", pi.name, response->which_payload_variant);
|
||||
handled = h;
|
||||
}
|
||||
else if ((handled != AdminMessageHandleResult::HANDLED_WITH_RESPONSE) &&
|
||||
(h == AdminMessageHandleResult::HANDLED))
|
||||
{
|
||||
} else if ((handled != AdminMessageHandleResult::HANDLED_WITH_RESPONSE) && (h == AdminMessageHandleResult::HANDLED)) {
|
||||
// In case the message is handled it should be populated, but will not overwrite
|
||||
// a result with response.
|
||||
handled = h;
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
*
|
||||
* Use ProcessMessage::STOP to stop further message processing.
|
||||
*/
|
||||
enum class ProcessMessage
|
||||
{
|
||||
enum class ProcessMessage {
|
||||
CONTINUE = 0,
|
||||
STOP = 1,
|
||||
};
|
||||
|
@ -27,8 +26,7 @@ enum class ProcessMessage
|
|||
* If response is also prepared for the request, then HANDLED_WITH_RESPONSE
|
||||
* should be returned.
|
||||
*/
|
||||
enum class AdminMessageHandleResult
|
||||
{
|
||||
enum class AdminMessageHandleResult {
|
||||
NOT_HANDLED = 0,
|
||||
HANDLED = 1,
|
||||
HANDLED_WITH_RESPONSE = 2,
|
||||
|
@ -70,10 +68,13 @@ class MeshModule
|
|||
|
||||
static std::vector<MeshModule *> GetMeshModulesWithUIFrames();
|
||||
static void observeUIEvents(Observer<const UIFrameEvent *> *observer);
|
||||
static AdminMessageHandleResult handleAdminMessageForAllPlugins(
|
||||
const MeshPacket &mp, AdminMessage *request, AdminMessage *response);
|
||||
static AdminMessageHandleResult handleAdminMessageForAllPlugins(const MeshPacket &mp, AdminMessage *request,
|
||||
AdminMessage *response);
|
||||
#if HAS_SCREEN
|
||||
virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { return; }
|
||||
virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
protected:
|
||||
const char *name;
|
||||
|
@ -127,9 +128,13 @@ class MeshModule
|
|||
|
||||
/** Called to handle a particular incoming message
|
||||
|
||||
@return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it
|
||||
@return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for
|
||||
it
|
||||
*/
|
||||
virtual ProcessMessage handleReceived(const MeshPacket &mp) { return ProcessMessage::CONTINUE; }
|
||||
virtual ProcessMessage handleReceived(const MeshPacket &mp)
|
||||
{
|
||||
return ProcessMessage::CONTINUE;
|
||||
}
|
||||
|
||||
/** Messages can be received that have the want_response bit set. If set, this callback will be invoked
|
||||
* so that subclasses can (optionally) send a response back to the original sender.
|
||||
|
@ -142,8 +147,14 @@ class MeshModule
|
|||
/***
|
||||
* @return true if you want to be alloced a UI screen frame
|
||||
*/
|
||||
virtual bool wantUIFrame() { return false; }
|
||||
virtual Observable<const UIFrameEvent *>* getUIFrameObservable() { return NULL; }
|
||||
virtual bool wantUIFrame()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual Observable<const UIFrameEvent *> *getUIFrameObservable()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MeshPacket *allocAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex);
|
||||
|
||||
|
@ -160,8 +171,11 @@ class MeshModule
|
|||
* HANDLED if message was handled
|
||||
* HANDLED_WITH_RESPONSE if a response is also prepared and to be sent.
|
||||
*/
|
||||
virtual AdminMessageHandleResult handleAdminMessageForModule(
|
||||
const MeshPacket &mp, AdminMessage *request, AdminMessage *response) { return AdminMessageHandleResult::NOT_HANDLED; };
|
||||
virtual AdminMessageHandleResult handleAdminMessageForModule(const MeshPacket &mp, AdminMessage *request,
|
||||
AdminMessage *response)
|
||||
{
|
||||
return AdminMessageHandleResult::NOT_HANDLED;
|
||||
};
|
||||
|
||||
private:
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "configuration.h"
|
||||
#include "MeshPacketQueue.h"
|
||||
#include "configuration.h"
|
||||
#include <assert.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -26,7 +26,8 @@ bool CompareMeshPacketFunc(const MeshPacket *p1, const MeshPacket *p2)
|
|||
|
||||
MeshPacketQueue::MeshPacketQueue(size_t _maxLen) : maxLen(_maxLen) {}
|
||||
|
||||
bool MeshPacketQueue::empty() {
|
||||
bool MeshPacketQueue::empty()
|
||||
{
|
||||
return queue.empty();
|
||||
}
|
||||
|
||||
|
@ -40,8 +41,9 @@ void fixPriority(MeshPacket *p)
|
|||
if (p->priority == MeshPacket_Priority_UNSET) {
|
||||
// if acks give high priority
|
||||
// if a reliable message give a bit higher default priority
|
||||
p->priority = (p->decoded.portnum == PortNum_ROUTING_APP) ? MeshPacket_Priority_ACK :
|
||||
(p->want_ack ? MeshPacket_Priority_RELIABLE : MeshPacket_Priority_DEFAULT);
|
||||
p->priority = (p->decoded.portnum == PortNum_ROUTING_APP)
|
||||
? MeshPacket_Priority_ACK
|
||||
: (p->want_ack ? MeshPacket_Priority_RELIABLE : MeshPacket_Priority_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,7 +101,8 @@ MeshPacket *MeshPacketQueue::remove(NodeNum from, PacketId id)
|
|||
}
|
||||
|
||||
/** Attempt to find and remove a packet from this queue. Returns the packet which was removed from the queue */
|
||||
bool MeshPacketQueue::replaceLowerPriorityPacket(MeshPacket *p) {
|
||||
bool MeshPacketQueue::replaceLowerPriorityPacket(MeshPacket *p)
|
||||
{
|
||||
std::sort_heap(queue.begin(), queue.end(), &CompareMeshPacketFunc); // sort ascending based on priority (0 -> 127)
|
||||
|
||||
// find first packet which does not compare less (in priority) than parameter packet
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#include <queue>
|
||||
|
||||
|
||||
/**
|
||||
* A priority queue of packets
|
||||
*/
|
||||
|
@ -13,7 +12,8 @@ class MeshPacketQueue
|
|||
size_t maxLen;
|
||||
std::vector<MeshPacket *> queue;
|
||||
|
||||
/** Replace a lower priority package in the queue with 'mp' (provided there are lower pri packages). Return true if replaced. */
|
||||
/** Replace a lower priority package in the queue with 'mp' (provided there are lower pri packages). Return true if replaced.
|
||||
*/
|
||||
bool replaceLowerPriorityPacket(MeshPacket *mp);
|
||||
|
||||
public:
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
#include <assert.h>
|
||||
#include <string>
|
||||
|
||||
#include "GPS.h"
|
||||
#include "../concurrency/Periodic.h"
|
||||
#include "BluetoothCommon.h" // needed for updateBatteryLevel, FIXME, eventually when we pull mesh out into a lib we shouldn't be whacking bluetooth from here
|
||||
#include "GPS.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
|
@ -140,7 +140,8 @@ void MeshService::handleToRadio(MeshPacket &p)
|
|||
Compressed *decoded = NULL;
|
||||
if (p.which_payload_variant == MeshPacket_decoded_tag) {
|
||||
memset(&scratch, 0, sizeof(scratch));
|
||||
p.decoded.payload.size = pb_decode_from_bytes(p.decoded.payload.bytes, p.decoded.payload.size, &Compressed_msg, &scratch);
|
||||
p.decoded.payload.size =
|
||||
pb_decode_from_bytes(p.decoded.payload.bytes, p.decoded.payload.size, &Compressed_msg, &scratch);
|
||||
if (p.decoded.payload.size) {
|
||||
decoded = &scratch;
|
||||
// Extract the original payload and replace
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
#include "error.h"
|
||||
#include "main.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
#include <ErriezCRC32.h>
|
||||
#include <pb_decode.h>
|
||||
#include <pb_encode.h>
|
||||
#include <ErriezCRC32.h>
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
#include "mesh/http/WiFiAPClient.h"
|
||||
|
@ -160,7 +160,8 @@ void NodeDB::installDefaultConfig()
|
|||
config.has_power = true;
|
||||
config.has_network = true;
|
||||
config.has_bluetooth = true;
|
||||
config.lora.tx_enabled = true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off)
|
||||
config.lora.tx_enabled =
|
||||
true; // FIXME: maybe false in the future, and setting region to enable it. (unset region forces it off)
|
||||
config.lora.override_duty_cycle = false;
|
||||
config.lora.region = Config_LoRaConfig_RegionCode_UNSET;
|
||||
config.lora.modem_preset = Config_LoRaConfig_ModemPreset_LONG_FAST;
|
||||
|
@ -178,9 +179,11 @@ void NodeDB::installDefaultConfig()
|
|||
#else
|
||||
bool hasScreen = screen_found;
|
||||
#endif
|
||||
config.bluetooth.mode = hasScreen ? Config_BluetoothConfig_PairingMode_RANDOM_PIN : Config_BluetoothConfig_PairingMode_FIXED_PIN;
|
||||
config.bluetooth.mode =
|
||||
hasScreen ? Config_BluetoothConfig_PairingMode_RANDOM_PIN : Config_BluetoothConfig_PairingMode_FIXED_PIN;
|
||||
// for backward compat, default position flags are ALT+MSL
|
||||
config.position.position_flags = (Config_PositionConfig_PositionFlags_ALTITUDE | Config_PositionConfig_PositionFlags_ALTITUDE_MSL);
|
||||
config.position.position_flags =
|
||||
(Config_PositionConfig_PositionFlags_ALTITUDE | Config_PositionConfig_PositionFlags_ALTITUDE_MSL);
|
||||
|
||||
initConfigIntervals();
|
||||
}
|
||||
|
@ -285,7 +288,8 @@ void NodeDB::init()
|
|||
|
||||
myNodeInfo.max_channels = MAX_NUM_CHANNELS; // tell others the max # of channels we can understand
|
||||
|
||||
myNodeInfo.error_code = CriticalErrorCode_NONE; // For the error code, only show values from this boot (discard value from flash)
|
||||
myNodeInfo.error_code =
|
||||
CriticalErrorCode_NONE; // For the error code, only show values from this boot (discard value from flash)
|
||||
myNodeInfo.error_address = 0;
|
||||
|
||||
// likewise - we always want the app requirements to come from the running appload
|
||||
|
@ -364,7 +368,6 @@ static const char *moduleConfigFileName = "/prefs/module.proto";
|
|||
static const char *channelFileName = "/prefs/channels.proto";
|
||||
static const char *oemConfigFile = "/oem/oem.proto";
|
||||
|
||||
|
||||
/** Load a protobuf from a file, return true for success */
|
||||
bool NodeDB::loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct)
|
||||
{
|
||||
|
@ -422,7 +425,8 @@ void NodeDB::loadFromDisk()
|
|||
}
|
||||
}
|
||||
|
||||
if (!loadProto(moduleConfigFileName, LocalModuleConfig_size, sizeof(LocalModuleConfig), &LocalModuleConfig_msg, &moduleConfig)) {
|
||||
if (!loadProto(moduleConfigFileName, LocalModuleConfig_size, sizeof(LocalModuleConfig), &LocalModuleConfig_msg,
|
||||
&moduleConfig)) {
|
||||
installDefaultModuleConfig(); // Our in RAM copy might now be corrupt
|
||||
} else {
|
||||
if (moduleConfig.version < DEVICESTATE_MIN_VER) {
|
||||
|
|
|
@ -58,7 +58,8 @@ class NodeDB
|
|||
void init();
|
||||
|
||||
/// write to flash
|
||||
void saveToDisk(int saveWhat = SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS), saveChannelsToDisk(), saveDeviceStateToDisk();
|
||||
void saveToDisk(int saveWhat = SEGMENT_CONFIG | SEGMENT_MODULECONFIG | SEGMENT_DEVICESTATE | SEGMENT_CHANNELS),
|
||||
saveChannelsToDisk(), saveDeviceStateToDisk();
|
||||
|
||||
/** Reinit radio config if needed, because either:
|
||||
* a) sometimes a buggy android app might send us bogus settings or
|
||||
|
@ -140,13 +141,11 @@ class NodeDB
|
|||
newStatus.notifyObservers(&status);
|
||||
}
|
||||
|
||||
|
||||
/// read our db from flash
|
||||
void loadFromDisk();
|
||||
|
||||
/// Reinit device state from scratch (not loading from disk)
|
||||
void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(),
|
||||
installDefaultModuleConfig();
|
||||
void installDefaultDeviceState(), installDefaultChannels(), installDefaultConfig(), installDefaultModuleConfig();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -203,13 +202,15 @@ extern NodeDB nodeDB;
|
|||
|
||||
inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval)
|
||||
{
|
||||
if (configuredInterval > 0) return configuredInterval * 1000;
|
||||
if (configuredInterval > 0)
|
||||
return configuredInterval * 1000;
|
||||
return default_broadcast_interval_secs * 1000;
|
||||
}
|
||||
|
||||
inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t defaultInterval)
|
||||
{
|
||||
if (configuredInterval > 0) return configuredInterval * 1000;
|
||||
if (configuredInterval > 0)
|
||||
return configuredInterval * 1000;
|
||||
return defaultInterval * 1000;
|
||||
}
|
||||
|
||||
|
@ -218,4 +219,7 @@ inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval, uint32_t d
|
|||
*/
|
||||
extern uint32_t radioGeneration;
|
||||
|
||||
#define Module_Config_size (ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + ModuleConfig_TelemetryConfig_size + ModuleConfig_size)
|
||||
#define Module_Config_size \
|
||||
(ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + \
|
||||
ModuleConfig_RangeTestConfig_size + ModuleConfig_SerialConfig_size + ModuleConfig_StoreForwardConfig_size + \
|
||||
ModuleConfig_TelemetryConfig_size + ModuleConfig_size)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "configuration.h"
|
||||
#include "PacketHistory.h"
|
||||
#include "configuration.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
|
||||
PacketHistory::PacketHistory()
|
||||
|
@ -58,7 +58,8 @@ bool PacketHistory::wasSeenRecently(const MeshPacket *p, bool withUpdate)
|
|||
/**
|
||||
* Iterate through all recent packets, and remove all older than FLOOD_EXPIRE_TIME
|
||||
*/
|
||||
void PacketHistory::clearExpiredRecentPackets() {
|
||||
void PacketHistory::clearExpiredRecentPackets()
|
||||
{
|
||||
uint32_t now = millis();
|
||||
|
||||
LOG_DEBUG("recentPackets size=%ld\n", recentPackets.size());
|
||||
|
|
|
@ -1,4 +1,2 @@
|
|||
#include "configuration.h"
|
||||
#include "ProtobufModule.h"
|
||||
|
||||
|
||||
#include "configuration.h"
|
||||
|
|
|
@ -22,8 +22,6 @@ template <class T> class ProtobufModule : protected SinglePortModule
|
|||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
/**
|
||||
* Handle a received message, the data field in the message is already decoded and is provided
|
||||
*
|
||||
|
@ -62,7 +60,8 @@ template <class T> class ProtobufModule : protected SinglePortModule
|
|||
private:
|
||||
/** Called to handle a particular incoming message
|
||||
|
||||
@return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it
|
||||
@return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for
|
||||
it
|
||||
*/
|
||||
virtual ProcessMessage handleReceived(const MeshPacket &mp) override
|
||||
{
|
||||
|
@ -70,8 +69,7 @@ template <class T> class ProtobufModule : protected SinglePortModule
|
|||
// it would be better to update even if the message was destined to others.
|
||||
|
||||
auto &p = mp.decoded;
|
||||
LOG_INFO("Received %s from=0x%0x, id=0x%x, portnum=%d, payloadlen=%d\n", name, mp.from, mp.id, p.portnum,
|
||||
p.payload.size);
|
||||
LOG_INFO("Received %s from=0x%0x, id=0x%x, portnum=%d, payloadlen=%d\n", name, mp.from, mp.id, p.portnum, p.payload.size);
|
||||
|
||||
T scratch;
|
||||
T *decoded = NULL;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "configuration.h"
|
||||
#include "RF95Interface.h"
|
||||
#include "MeshRadio.h" // kinda yucky, but we need to know which region we are in
|
||||
#include "RadioLibRF95.h"
|
||||
#include "configuration.h"
|
||||
#include "error.h"
|
||||
|
||||
#define MAX_POWER 20
|
||||
|
@ -146,7 +146,6 @@ void RF95Interface::addReceiveMetadata(MeshPacket *mp)
|
|||
{
|
||||
mp->rx_snr = lora->getSNR();
|
||||
mp->rx_rssi = lround(lora->getRSSI());
|
||||
|
||||
}
|
||||
|
||||
void RF95Interface::setStandby()
|
||||
|
|
|
@ -38,9 +38,9 @@ const RegionInfo regions[] = {
|
|||
|
||||
Special Note:
|
||||
The link above describes LoRaWAN's band plan, stating a power limit of 16 dBm. This is their own suggested specification,
|
||||
we do not need to follow it. The European Union regulations clearly state that the power limit for this frequency range is 500 mW, or 27 dBm.
|
||||
It also states that we can use interference avoidance and spectrum access techniques to avoid a duty cycle.
|
||||
(Please refer to section 4.21 in the following document)
|
||||
we do not need to follow it. The European Union regulations clearly state that the power limit for this frequency range is
|
||||
500 mW, or 27 dBm. It also states that we can use interference avoidance and spectrum access techniques to avoid a duty
|
||||
cycle. (Please refer to section 4.21 in the following document)
|
||||
https://ec.europa.eu/growth/tools-databases/tris/index.cfm/ro/search/?trisaction=search.detail&year=2021&num=528&dLang=EN
|
||||
*/
|
||||
RDEF(EU_868, 869.4f, 869.65f, 10, 0, 27, false, false, false),
|
||||
|
@ -226,8 +226,7 @@ uint32_t RadioInterface::getTxDelayMsecWeighted(float snr)
|
|||
uint32_t delay = 0;
|
||||
uint8_t CWsize = map(snr, SNR_MIN, SNR_MAX, CWmin, CWmax);
|
||||
// LOG_DEBUG("rx_snr of %f so setting CWsize to:%d\n", snr, CWsize);
|
||||
if (config.device.role == Config_DeviceConfig_Role_ROUTER ||
|
||||
config.device.role == Config_DeviceConfig_Role_ROUTER_CLIENT) {
|
||||
if (config.device.role == Config_DeviceConfig_Role_ROUTER || config.device.role == Config_DeviceConfig_Role_ROUTER_CLIENT) {
|
||||
delay = random(0, 2 * CWsize) * slotTimeMsec;
|
||||
LOG_DEBUG("rx_snr found in packet. As a router, setting tx delay:%d\n", delay);
|
||||
} else {
|
||||
|
@ -459,8 +458,10 @@ void RadioInterface::applyModemConfig()
|
|||
saveFreq(freq + config.lora.frequency_offset);
|
||||
|
||||
LOG_INFO("Radio freq=%.3f, config.lora.frequency_offset=%.3f\n", freq, config.lora.frequency_offset);
|
||||
LOG_INFO("Set radio: region=%s, name=%s, config=%u, ch=%d, power=%d\n", myRegion->name, channelName, loraConfig.modem_preset, channel_num, power);
|
||||
LOG_INFO("Radio myRegion->freqStart -> myRegion->freqEnd: %f -> %f (%f mhz)\n", myRegion->freqStart, myRegion->freqEnd, myRegion->freqEnd - myRegion->freqStart);
|
||||
LOG_INFO("Set radio: region=%s, name=%s, config=%u, ch=%d, power=%d\n", myRegion->name, channelName, loraConfig.modem_preset,
|
||||
channel_num, power);
|
||||
LOG_INFO("Radio myRegion->freqStart -> myRegion->freqEnd: %f -> %f (%f mhz)\n", myRegion->freqStart, myRegion->freqEnd,
|
||||
myRegion->freqEnd - myRegion->freqStart);
|
||||
LOG_INFO("Radio myRegion->numChannels: %d x %.3fkHz\n", numChannels, bw);
|
||||
LOG_INFO("Radio channel_num: %d\n", channel_num);
|
||||
LOG_INFO("Radio frequency: %f\n", getFreq());
|
||||
|
@ -486,7 +487,6 @@ void RadioInterface::limitPower()
|
|||
LOG_INFO("Set radio: final power level=%d\n", power);
|
||||
}
|
||||
|
||||
|
||||
void RadioInterface::deliverToReceiver(MeshPacket *p)
|
||||
{
|
||||
if (router)
|
||||
|
|
|
@ -51,7 +51,6 @@ class RadioInterface
|
|||
CallbackObserver<RadioInterface, void *> notifyDeepSleepObserver =
|
||||
CallbackObserver<RadioInterface, void *>(this, &RadioInterface::notifyDeepSleepCb);
|
||||
|
||||
|
||||
protected:
|
||||
bool disabled = false;
|
||||
|
||||
|
@ -65,7 +64,8 @@ class RadioInterface
|
|||
- MAC processing time (measured on T-beam) */
|
||||
uint32_t slotTimeMsec = 8.5 * pow(2, sf) / bw + 0.2 + 0.4 + 7;
|
||||
uint16_t preambleLength = 32; // 8 is default, but we use longer to increase the amount of sleep time when receiving
|
||||
const uint32_t PROCESSING_TIME_MSEC = 4500; // time to construct, process and construct a packet again (empirically determined)
|
||||
const uint32_t PROCESSING_TIME_MSEC =
|
||||
4500; // time to construct, process and construct a packet again (empirically determined)
|
||||
const uint8_t CWmin = 2; // minimum CWsize
|
||||
const uint8_t CWmax = 8; // maximum CWsize
|
||||
|
||||
|
@ -116,7 +116,8 @@ class RadioInterface
|
|||
virtual ErrorCode send(MeshPacket *p) = 0;
|
||||
|
||||
/** Return TX queue status */
|
||||
virtual QueueStatus getQueueStatus() {
|
||||
virtual QueueStatus getQueueStatus()
|
||||
{
|
||||
QueueStatus qs;
|
||||
qs.res = qs.mesh_packet_id = qs.free = qs.maxlen = 0;
|
||||
return qs;
|
||||
|
@ -146,7 +147,6 @@ class RadioInterface
|
|||
/** The delay to use when we want to flood a message. Use a weighted scale based on SNR */
|
||||
uint32_t getTxDelayMsecWeighted(float snr);
|
||||
|
||||
|
||||
/**
|
||||
* Calculate airtime per
|
||||
* https://www.rs-online.com/designspark/rel-assets/ds-assets/uploads/knowledge-items/application-notes-for-the-internet-of-things/LoRa%20Design%20Guide.pdf
|
||||
|
@ -220,6 +220,5 @@ class RadioInterface
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
/// Debug printing for packets
|
||||
void printPacket(const char *prefix, const MeshPacket *p);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "concurrency/NotifiedWorkerThread.h"
|
||||
#include "RadioInterface.h"
|
||||
#include "MeshPacketQueue.h"
|
||||
#include "RadioInterface.h"
|
||||
#include "concurrency/NotifiedWorkerThread.h"
|
||||
|
||||
#include <RadioLib.h>
|
||||
|
||||
|
@ -62,13 +62,12 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
|
|||
MeshPacketQueue txQueue = MeshPacketQueue(MAX_TX_QUEUE);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* We use a meshtastic sync word, but hashed with the Channel name. For releases before 1.2 we used 0x12 (or for very old loads 0x14)
|
||||
* Note: do not use 0x34 - that is reserved for lorawan
|
||||
* We use a meshtastic sync word, but hashed with the Channel name. For releases before 1.2 we used 0x12 (or for very old
|
||||
* loads 0x14) Note: do not use 0x34 - that is reserved for lorawan
|
||||
*
|
||||
* We now use 0x2b (so that someday we can possibly use NOT 2b - because that would be funny pun). We will be staying with this code
|
||||
* for a long time.
|
||||
* We now use 0x2b (so that someday we can possibly use NOT 2b - because that would be funny pun). We will be staying with
|
||||
* this code for a long time.
|
||||
*/
|
||||
const uint8_t syncWord = 0x2b;
|
||||
|
||||
|
@ -131,8 +130,8 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
|
|||
virtual bool cancelSending(NodeNum from, PacketId id) override;
|
||||
|
||||
private:
|
||||
/** if we have something waiting to send, start a short (random) timer so we can come check for collision before actually doing
|
||||
* the transmit */
|
||||
/** if we have something waiting to send, start a short (random) timer so we can come check for collision before actually
|
||||
* doing the transmit */
|
||||
void setTransmitDelay();
|
||||
|
||||
/** random timer with certain min. and max. settings */
|
||||
|
@ -156,7 +155,6 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
|
|||
QueueStatus getQueueStatus();
|
||||
|
||||
protected:
|
||||
|
||||
/** Do any hardware setup needed on entry into send configuration for the radio. Subclasses can customize */
|
||||
virtual void configHardwareForSend() {}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "configuration.h"
|
||||
#include "RadioLibRF95.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#define RF95_CHIP_VERSION 0x12
|
||||
#define RF95_ALT_VERSION 0x11 // Supposedly some versions of the chip have id 0x11
|
||||
|
@ -7,11 +7,10 @@
|
|||
// From datasheet but radiolib doesn't know anything about this
|
||||
#define SX127X_REG_TCXO 0x4B
|
||||
|
||||
|
||||
RadioLibRF95::RadioLibRF95(Module *mod) : SX1278(mod) {}
|
||||
|
||||
int16_t RadioLibRF95::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power,
|
||||
uint16_t preambleLength, uint8_t gain)
|
||||
int16_t RadioLibRF95::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength,
|
||||
uint8_t gain)
|
||||
{
|
||||
// execute common part
|
||||
int16_t state = SX127x::begin(RF95_CHIP_VERSION, syncWord, preambleLength);
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
|
||||
\brief Derived class for %RFM95 modules. Overrides some methods from SX1278 due to different parameter ranges.
|
||||
*/
|
||||
class RadioLibRF95: public SX1278 {
|
||||
class RadioLibRF95 : public SX1278
|
||||
{
|
||||
public:
|
||||
|
||||
// constructor
|
||||
|
||||
/*!
|
||||
|
@ -31,19 +31,21 @@ class RadioLibRF95: public SX1278 {
|
|||
|
||||
\param cr %LoRa link coding rate denominator. Allowed values range from 5 to 8.
|
||||
|
||||
\param syncWord %LoRa sync word. Can be used to distinguish different networks. Note that value 0x34 is reserved for LoRaWAN networks.
|
||||
\param syncWord %LoRa sync word. Can be used to distinguish different networks. Note that value 0x34 is reserved for LoRaWAN
|
||||
networks.
|
||||
|
||||
\param power Transmission output power in dBm. Allowed values range from 2 to 17 dBm.
|
||||
|
||||
\param preambleLength Length of %LoRa transmission preamble in symbols. The actual preamble length is 4.25 symbols longer than the set number.
|
||||
Allowed values range from 6 to 65535.
|
||||
\param preambleLength Length of %LoRa transmission preamble in symbols. The actual preamble length is 4.25 symbols longer
|
||||
than the set number. Allowed values range from 6 to 65535.
|
||||
|
||||
\param gain Gain of receiver LNA (low-noise amplifier). Can be set to any integer in range 1 to 6 where 1 is the highest gain.
|
||||
Set to 0 to enable automatic gain control (recommended).
|
||||
\param gain Gain of receiver LNA (low-noise amplifier). Can be set to any integer in range 1 to 6 where 1 is the highest
|
||||
gain. Set to 0 to enable automatic gain control (recommended).
|
||||
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t begin(float freq = 915.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX127X_SYNC_WORD, int8_t power = 17, uint16_t preambleLength = 8, uint8_t gain = 0);
|
||||
int16_t begin(float freq = 915.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7,
|
||||
uint8_t syncWord = RADIOLIB_SX127X_SYNC_WORD, int8_t power = 17, uint16_t preambleLength = 8, uint8_t gain = 0);
|
||||
|
||||
// configuration methods
|
||||
|
||||
|
@ -67,4 +69,3 @@ class RadioLibRF95: public SX1278 {
|
|||
// use the previous value
|
||||
float currentLimit = 100;
|
||||
};
|
||||
|
||||
|
|
|
@ -88,8 +88,7 @@ void ReliableRouter::sniffReceived(const MeshPacket *p, const Routing *c)
|
|||
if (p->want_ack) {
|
||||
if (MeshModule::currentReply)
|
||||
LOG_DEBUG("Some other module has replied to this message, no need for a 2nd ack\n");
|
||||
else
|
||||
if (p->which_payload_variant == MeshPacket_decoded_tag)
|
||||
else if (p->which_payload_variant == MeshPacket_decoded_tag)
|
||||
sendAckNak(Routing_Error_NONE, getFrom(p), p->id, p->channel);
|
||||
else
|
||||
// Send a 'NO_CHANNEL' error on the primary channel if want_ack packet destined for us cannot be decoded
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "Router.h"
|
||||
#include "Channels.h"
|
||||
#include "CryptoEngine.h"
|
||||
#include "NodeDB.h"
|
||||
#include "MeshRadio.h"
|
||||
#include "NodeDB.h"
|
||||
#include "RTC.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "configuration.h"
|
||||
#include "SX1262Interface.h"
|
||||
#include "configuration.h"
|
||||
#include "error.h"
|
||||
|
||||
SX1262Interface::SX1262Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "configuration.h"
|
||||
#include "SX1268Interface.h"
|
||||
#include "configuration.h"
|
||||
#include "error.h"
|
||||
|
||||
SX1268Interface::SX1268Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "configuration.h"
|
||||
#include "SX126xInterface.h"
|
||||
#include "configuration.h"
|
||||
#include "error.h"
|
||||
|
||||
// Particular boards might define a different max power based on what their hardware can do
|
||||
|
@ -18,8 +18,7 @@ SX126xInterface<T>::SX126xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq,
|
|||
/// Initialise the Driver transport hardware and software.
|
||||
/// Make sure the Driver is properly configured before calling init().
|
||||
/// \return true if initialisation succeeded.
|
||||
template<typename T>
|
||||
bool SX126xInterface<T>::init()
|
||||
template <typename T> bool SX126xInterface<T>::init()
|
||||
{
|
||||
#ifdef SX126X_POWER_EN
|
||||
digitalWrite(SX126X_POWER_EN, HIGH);
|
||||
|
@ -106,8 +105,7 @@ bool SX126xInterface<T>::init()
|
|||
return res == RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool SX126xInterface<T>::reconfigure()
|
||||
template <typename T> bool SX126xInterface<T>::reconfigure()
|
||||
{
|
||||
RadioLibInterface::reconfigure();
|
||||
|
||||
|
@ -156,14 +154,12 @@ bool SX126xInterface<T>::reconfigure()
|
|||
return RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void INTERRUPT_ATTR SX126xInterface<T>::disableInterrupt()
|
||||
template <typename T> void INTERRUPT_ATTR SX126xInterface<T>::disableInterrupt()
|
||||
{
|
||||
lora.clearDio1Action();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SX126xInterface<T>::setStandby()
|
||||
template <typename T> void SX126xInterface<T>::setStandby()
|
||||
{
|
||||
checkNotification(); // handle any pending interrupts before we force standby
|
||||
|
||||
|
@ -189,8 +185,7 @@ void SX126xInterface<T>::setStandby()
|
|||
/**
|
||||
* Add SNR data to received messages
|
||||
*/
|
||||
template<typename T>
|
||||
void SX126xInterface<T>::addReceiveMetadata(MeshPacket *mp)
|
||||
template <typename T> void SX126xInterface<T>::addReceiveMetadata(MeshPacket *mp)
|
||||
{
|
||||
// LOG_DEBUG("PacketStatus %x\n", lora.getPacketStatus());
|
||||
mp->rx_snr = lora.getSNR();
|
||||
|
@ -199,8 +194,7 @@ void SX126xInterface<T>::addReceiveMetadata(MeshPacket *mp)
|
|||
|
||||
/** We override to turn on transmitter power as needed.
|
||||
*/
|
||||
template<typename T>
|
||||
void SX126xInterface<T>::configHardwareForSend()
|
||||
template <typename T> void SX126xInterface<T>::configHardwareForSend()
|
||||
{
|
||||
#if defined(SX126X_TXEN) && (SX126X_TXEN != RADIOLIB_NC) // we have RXEN/TXEN control - turn on TX power / off RX power
|
||||
digitalWrite(SX126X_TXEN, HIGH);
|
||||
|
@ -215,8 +209,7 @@ void SX126xInterface<T>::configHardwareForSend()
|
|||
// For power draw measurements, helpful to force radio to stay sleeping
|
||||
// #define SLEEP_ONLY
|
||||
|
||||
template<typename T>
|
||||
void SX126xInterface<T>::startReceive()
|
||||
template <typename T> void SX126xInterface<T>::startReceive()
|
||||
{
|
||||
#ifdef SLEEP_ONLY
|
||||
sleep();
|
||||
|
@ -244,8 +237,7 @@ void SX126xInterface<T>::startReceive()
|
|||
}
|
||||
|
||||
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
||||
template<typename T>
|
||||
bool SX126xInterface<T>::isChannelActive()
|
||||
template <typename T> bool SX126xInterface<T>::isChannelActive()
|
||||
{
|
||||
// check if we can detect a LoRa preamble on the current channel
|
||||
int16_t result;
|
||||
|
@ -261,8 +253,7 @@ bool SX126xInterface<T>::isChannelActive()
|
|||
}
|
||||
|
||||
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
||||
template<typename T>
|
||||
bool SX126xInterface<T>::isActivelyReceiving()
|
||||
template <typename T> bool SX126xInterface<T>::isActivelyReceiving()
|
||||
{
|
||||
// The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet
|
||||
// received and handled the interrupt for reading the packet/handling errors.
|
||||
|
@ -279,8 +270,7 @@ bool SX126xInterface<T>::isActivelyReceiving()
|
|||
return hasPreamble;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool SX126xInterface<T>::sleep()
|
||||
template <typename T> bool SX126xInterface<T>::sleep()
|
||||
{
|
||||
// Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet
|
||||
// \todo Display actual typename of the adapter, not just `SX126x`
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
* \brief Adapter for SX126x radio family. Implements common logic for child classes.
|
||||
* \tparam T RadioLib module type for SX126x: SX1262, SX1268.
|
||||
*/
|
||||
template<class T>
|
||||
class SX126xInterface : public RadioLibInterface
|
||||
template <class T> class SX126xInterface : public RadioLibInterface
|
||||
{
|
||||
public:
|
||||
SX126xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
|
||||
|
@ -28,7 +27,6 @@ class SX126xInterface : public RadioLibInterface
|
|||
bool isIRQPending() override { return lora.getIrqStatus() != 0; }
|
||||
|
||||
protected:
|
||||
|
||||
float currentLimit = 140; // Higher OCP limit for SX126x PA
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "configuration.h"
|
||||
#include "SX1280Interface.h"
|
||||
#include "configuration.h"
|
||||
#include "error.h"
|
||||
|
||||
SX1280Interface::SX1280Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
* Our adapter for SX1280 radios
|
||||
*/
|
||||
|
||||
|
||||
class SX1280Interface : public SX128xInterface<SX1280>
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "configuration.h"
|
||||
#include "SX128xInterface.h"
|
||||
#include "mesh/NodeDB.h"
|
||||
#include "configuration.h"
|
||||
#include "error.h"
|
||||
#include "mesh/NodeDB.h"
|
||||
|
||||
// Particular boards might define a different max power based on what their hardware can do
|
||||
#ifndef SX128X_MAX_POWER
|
||||
|
@ -18,8 +18,7 @@ SX128xInterface<T>::SX128xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq,
|
|||
/// Initialise the Driver transport hardware and software.
|
||||
/// Make sure the Driver is properly configured before calling init().
|
||||
/// \return true if initialisation succeeded.
|
||||
template<typename T>
|
||||
bool SX128xInterface<T>::init()
|
||||
template <typename T> bool SX128xInterface<T>::init()
|
||||
{
|
||||
#ifdef SX128X_POWER_EN
|
||||
digitalWrite(SX128X_POWER_EN, HIGH);
|
||||
|
@ -83,8 +82,7 @@ bool SX128xInterface<T>::init()
|
|||
return res == RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool SX128xInterface<T>::reconfigure()
|
||||
template <typename T> bool SX128xInterface<T>::reconfigure()
|
||||
{
|
||||
RadioLibInterface::reconfigure();
|
||||
|
||||
|
@ -130,20 +128,17 @@ bool SX128xInterface<T>::reconfigure()
|
|||
return RADIOLIB_ERR_NONE;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void INTERRUPT_ATTR SX128xInterface<T>::disableInterrupt()
|
||||
template <typename T> void INTERRUPT_ATTR SX128xInterface<T>::disableInterrupt()
|
||||
{
|
||||
lora.clearDio1Action();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool SX128xInterface<T>::wideLora()
|
||||
template <typename T> bool SX128xInterface<T>::wideLora()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SX128xInterface<T>::setStandby()
|
||||
template <typename T> void SX128xInterface<T>::setStandby()
|
||||
{
|
||||
checkNotification(); // handle any pending interrupts before we force standby
|
||||
|
||||
|
@ -169,8 +164,7 @@ void SX128xInterface<T>::setStandby()
|
|||
/**
|
||||
* Add SNR data to received messages
|
||||
*/
|
||||
template<typename T>
|
||||
void SX128xInterface<T>::addReceiveMetadata(MeshPacket *mp)
|
||||
template <typename T> void SX128xInterface<T>::addReceiveMetadata(MeshPacket *mp)
|
||||
{
|
||||
// LOG_DEBUG("PacketStatus %x\n", lora.getPacketStatus());
|
||||
mp->rx_snr = lora.getSNR();
|
||||
|
@ -179,8 +173,7 @@ void SX128xInterface<T>::addReceiveMetadata(MeshPacket *mp)
|
|||
|
||||
/** We override to turn on transmitter power as needed.
|
||||
*/
|
||||
template<typename T>
|
||||
void SX128xInterface<T>::configHardwareForSend()
|
||||
template <typename T> void SX128xInterface<T>::configHardwareForSend()
|
||||
{
|
||||
#if defined(SX128X_TXEN) && (SX128X_TXEN != RADIOLIB_NC) // we have RXEN/TXEN control - turn on TX power / off RX power
|
||||
digitalWrite(SX128X_TXEN, HIGH);
|
||||
|
@ -195,8 +188,7 @@ void SX128xInterface<T>::configHardwareForSend()
|
|||
// For power draw measurements, helpful to force radio to stay sleeping
|
||||
// #define SLEEP_ONLY
|
||||
|
||||
template<typename T>
|
||||
void SX128xInterface<T>::startReceive()
|
||||
template <typename T> void SX128xInterface<T>::startReceive()
|
||||
{
|
||||
#ifdef SLEEP_ONLY
|
||||
sleep();
|
||||
|
@ -223,8 +215,7 @@ void SX128xInterface<T>::startReceive()
|
|||
}
|
||||
|
||||
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
||||
template<typename T>
|
||||
bool SX128xInterface<T>::isChannelActive()
|
||||
template <typename T> bool SX128xInterface<T>::isChannelActive()
|
||||
{
|
||||
// check if we can detect a LoRa preamble on the current channel
|
||||
int16_t result;
|
||||
|
@ -240,16 +231,14 @@ bool SX128xInterface<T>::isChannelActive()
|
|||
}
|
||||
|
||||
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
||||
template<typename T>
|
||||
bool SX128xInterface<T>::isActivelyReceiving()
|
||||
template <typename T> bool SX128xInterface<T>::isActivelyReceiving()
|
||||
{
|
||||
uint16_t irq = lora.getIrqStatus();
|
||||
bool hasPreamble = (irq & RADIOLIB_SX128X_IRQ_HEADER_VALID);
|
||||
return hasPreamble;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool SX128xInterface<T>::sleep()
|
||||
template <typename T> bool SX128xInterface<T>::sleep()
|
||||
{
|
||||
// Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet
|
||||
// \todo Display actual typename of the adapter, not just `SX128x`
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
* \brief Adapter for SX128x radio family. Implements common logic for child classes.
|
||||
* \tparam T RadioLib module type for SX128x: SX1280.
|
||||
*/
|
||||
template<class T>
|
||||
class SX128xInterface : public RadioLibInterface
|
||||
template <class T> class SX128xInterface : public RadioLibInterface
|
||||
{
|
||||
public:
|
||||
SX128xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
|
||||
|
@ -30,7 +29,6 @@ class SX128xInterface : public RadioLibInterface
|
|||
bool isIRQPending() override { return lora.getIrqStatus() != 0; }
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Specific module instance
|
||||
*/
|
||||
|
|
|
@ -28,7 +28,8 @@ int32_t StreamAPI::readStream()
|
|||
while (stream->available()) { // Currently we never want to block
|
||||
int cInt = stream->read();
|
||||
if (cInt < 0)
|
||||
break; // We ran out of characters (even though available said otherwise) - this can happen on rf52 adafruit arduino
|
||||
break; // We ran out of characters (even though available said otherwise) - this can happen on rf52 adafruit
|
||||
// arduino
|
||||
|
||||
uint8_t c = (uint8_t)cInt;
|
||||
|
||||
|
|
|
@ -19,10 +19,7 @@ template <class T> class TypedQueue
|
|||
concurrency::OSThread *reader = NULL;
|
||||
|
||||
public:
|
||||
explicit TypedQueue(int maxElements) : h(xQueueCreate(maxElements, sizeof(T)))
|
||||
{
|
||||
assert(h);
|
||||
}
|
||||
explicit TypedQueue(int maxElements) : h(xQueueCreate(maxElements, sizeof(T))) { assert(h); }
|
||||
|
||||
~TypedQueue() { vQueueDelete(h); }
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Ładowanie…
Reference in New Issue