diff --git a/.github/actions/initbuild/action.yml b/.github/actions/initbuild/action.yml
index db49b31ad..b852d0a6c 100644
--- a/.github/actions/initbuild/action.yml
+++ b/.github/actions/initbuild/action.yml
@@ -24,12 +24,13 @@ runs:
python -m pip install --upgrade pip
pip install -U platformio meshtastic adafruit-nrfutil
- - name: Cache platformio
- uses: actions/cache@v1
- id: cache-platformio # needed in if test
- with:
- path: ~/.platformio
- key: ${{ runner.os }}-platformio
+ # Don't cache for now because I want to be lazy with portuino updates githashes
+ # - name: Cache platformio
+ # uses: actions/cache@v1
+ # id: cache-platformio # needed in if test
+ # with:
+ # path: ~/.platformio
+ # key: ${{ runner.os }}-platformio
- name: Upgrade platformio
run: |
diff --git a/.gitignore b/.gitignore
index 67688a0b4..eeb1bcb09 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,8 @@ main/credentials.h
!.vscode/extensions.json
*.code-workspace
+.idea/workspace.xml
+
.DS_Store
Thumbs.db
.autotools
@@ -19,4 +21,5 @@ Thumbs.db
nanopb*
flash.uf2
cmake-build*
-__pycache__
\ No newline at end of file
+__pycache__
+
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
deleted file mode 100644
index dad7634ec..000000000
--- a/.idea/workspace.xml
+++ /dev/null
@@ -1,178 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1615788661896
-
-
- 1615788661896
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- file://$PROJECT_DIR$/src/mesh/wifi/WiFiServerAPI.cpp
- 53
-
-
-
- file://$PROJECT_DIR$/src/mesh/wifi/WiFiServerAPI.cpp
- 37
-
-
-
- file://$PROJECT_DIR$/src/mqtt/MQTT.cpp
- 166
-
-
-
- file://$PROJECT_DIR$/.pio/libdeps/native/PubSubClient/src/PubSubClient.cpp
- 468
-
-
-
- file://$PROJECT_DIR$/src/mesh/mesh-pb-constants.cpp
- 20
-
-
-
- file://$USER_HOME$/.platformio/packages/framework-portduino/cores/portduino/PortduinoGPIO.cpp
- 41
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/bin/build-all.sh b/bin/build-all.sh
index 110b3c915..6a1cf9830 100755
--- a/bin/build-all.sh
+++ b/bin/build-all.sh
@@ -8,7 +8,7 @@ BOARDS_ESP32="tlora-v2 tlora-v1 tlora_v1_3 tlora-v2-1-1.6 tbeam heltec tbeam0.7"
#BOARDS_ESP32=tbeam
# FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine
-BOARDS_NRF52="rak4631"
+BOARDS_NRF52="rak4631 t-echo"
OUTDIR=release/latest
diff --git a/bin/buildinfo.py b/bin/buildinfo.py
index 36f88f43e..1dc5d98ef 100755
--- a/bin/buildinfo.py
+++ b/bin/buildinfo.py
@@ -3,5 +3,5 @@ import configparser
from readprops import readProps
-verStr = readProps('version.properties')
-print(f"{verStr}")
+verObj = readProps('version.properties')
+print(f"{verObj['long']}")
diff --git a/bin/platformio-custom.py b/bin/platformio-custom.py
index ce811c9cb..d299f954f 100644
--- a/bin/platformio-custom.py
+++ b/bin/platformio-custom.py
@@ -9,11 +9,12 @@ from readprops import readProps
Import("projenv")
prefsLoc = projenv["PROJECT_DIR"] + "/version.properties"
-verStr = readProps(prefsLoc)
-print("Using meshtastic platform-custom.py, firmare version " + verStr)
+verObj = readProps(prefsLoc)
+print("Using meshtastic platform-custom.py, firmare version " + verObj['long'])
# print("path is" + ','.join(sys.path))
# General options that are passed to the C and C++ compilers
projenv.Append(CCFLAGS=[
- "-DAPP_VERSION=" + verStr
+ "-DAPP_VERSION=" + verObj['long'],
+ "-DAPP_VERSION_SHORT=" + verObj['short']
])
diff --git a/bin/readprops.py b/bin/readprops.py
index 7fc471774..25eba4852 100644
--- a/bin/readprops.py
+++ b/bin/readprops.py
@@ -12,6 +12,8 @@ def readProps(prefsLoc):
config = configparser.RawConfigParser()
config.read(prefsLoc)
version = dict(config.items('VERSION'))
+ verObj = dict(short = "{}.{}.{}".format(version["major"], version["minor"], version["build"]),
+ long = "unset")
# Try to find current build SHA if if the workspace is clean. This could fail if git is not installed
try:
@@ -23,14 +25,13 @@ def readProps(prefsLoc):
if isDirty:
# short for 'dirty', we want to keep our verstrings source for protobuf reasons
suffix = sha + "-d"
- verStr = "{}.{}.{}.{}".format(
+ verObj['long'] = "{}.{}.{}.{}".format(
version["major"], version["minor"], version["build"], suffix)
except:
# print("Unexpected error:", sys.exc_info()[0])
# traceback.print_exc()
- verStr = "{}.{}.{}".format(
- version["major"], version["minor"], version["build"])
+ verObj['long'] = verObj['short']
# print("firmare version " + verStr)
- return verStr
+ return verObj
# print("path is" + ','.join(sys.path))
diff --git a/bin/regen-protos.sh b/bin/regen-protos.sh
index a3335e535..2d96f2b7b 100755
--- a/bin/regen-protos.sh
+++ b/bin/regen-protos.sh
@@ -10,6 +10,6 @@ echo "prebuilt binaries for your computer into nanopb-0.4.4"
cd proto
../nanopb-0.4.4/generator-bin/protoc --nanopb_out=-v:../src/mesh/generated -I=../proto *.proto
-echo "Regenerating protobuf documentation - if you see an error message"
-echo "you can ignore it unless doing a new protobuf release to github."
-bin/regen-docs.sh
\ No newline at end of file
+#echo "Regenerating protobuf documentation - if you see an error message"
+#echo "you can ignore it unless doing a new protobuf release to github."
+#bin/regen-docs.sh
\ No newline at end of file
diff --git a/bin/upload-to-bootloader.sh b/bin/upload-to-bootloader.sh
index 95ade3e37..0dd87ef1d 100755
--- a/bin/upload-to-bootloader.sh
+++ b/bin/upload-to-bootloader.sh
@@ -1,5 +1,5 @@
set -e
echo "Converting to uf2 for NRF52 Adafruit bootloader"
-bin/uf2conv.py .pio/build/rak4631/firmware.hex -f 0xADA52840
+bin/uf2conv.py .pio/build/t-echo/firmware.hex -f 0xADA52840
cp flash.uf2 /media/kevinh/FTH*BOOT/
diff --git a/bin/upload-to-rak4631.sh b/bin/upload-to-rak4631.sh
new file mode 100755
index 000000000..95ade3e37
--- /dev/null
+++ b/bin/upload-to-rak4631.sh
@@ -0,0 +1,5 @@
+set -e
+
+echo "Converting to uf2 for NRF52 Adafruit bootloader"
+bin/uf2conv.py .pio/build/rak4631/firmware.hex -f 0xADA52840
+cp flash.uf2 /media/kevinh/FTH*BOOT/
diff --git a/boards/eink.json b/boards/t-echo.json
similarity index 71%
rename from boards/eink.json
rename to boards/t-echo.json
index e2414b23f..da67ef05e 100644
--- a/boards/eink.json
+++ b/boards/t-echo.json
@@ -15,7 +15,7 @@
],
"usb_product": "TTGO_eink",
"mcu": "nrf52840",
- "variant": "eink",
+ "variant": "t-echo",
"variants_dir": "variants",
"bsp": {
"name": "adafruit"
@@ -44,17 +44,20 @@
"arduino"
],
"name": "TTGO eink (Adafruit BSP)",
- "upload": {
- "maximum_ram_size": 248832,
- "maximum_size": 815104,
- "require_upload_port": true,
- "speed": 115200,
- "protocol": "jlink",
- "protocols": [
- "jlink",
- "nrfjprog",
- "stlink"
- ]
+ "upload": {
+ "maximum_ram_size": 248832,
+ "maximum_size": 815104,
+ "speed": 115200,
+ "protocol": "nrfutil",
+ "protocols": [
+ "jlink",
+ "nrfjprog",
+ "nrfutil",
+ "stlink"
+ ],
+ "use_1200bps_touch": true,
+ "require_upload_port": true,
+ "wait_for_upload_port": true
},
"url": "FIXME",
"vendor": "TTGO"
diff --git a/geeksville-private/TODO.md b/geeksville-private/TODO.md
index 286551b59..7dbf5b0fd 100644
--- a/geeksville-private/TODO.md
+++ b/geeksville-private/TODO.md
@@ -4,6 +4,7 @@ You probably don't care about this section - skip to the next one.
## before next release
+* turn on setTx(timeout) and state = setDioIrqParams(SX126X_IRQ_TX_DONE | SX126X_IRQ_TIMEOUT, SX126X_IRQ_TX_DONE | SX126X_IRQ_TIMEOUT); in sx1262 code
* pine64 lora module
* nrf52 USB is unreliable while sleeping?
* @havealoha fixedposition not working
diff --git a/platformio.ini b/platformio.ini
index 889ea5bae..7296a6069 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -16,7 +16,7 @@ default_envs = tbeam
;default_envs = tlora_v1_3
;default_envs = tlora-v2
;default_envs = lora-relay-v1 # nrf board
-;default_envs = eink
+;default_envs = t-echo
;default_envs = nrf52840dk-geeksville
;default_envs = native # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here
;default_envs = rak4631
@@ -72,7 +72,7 @@ lib_deps =
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
https://github.com/meshtastic/arduino-fsm.git#829e967b8a95c094f73c60ef8dacfe66eae38940
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad
- https://github.com/meshtastic/RadioLib.git#07de964e929238949035fb0d5887026a3058df1a
+ https://github.com/meshtastic/RadioLib.git#80ed10d689a0568782c5bd152906b0f97d2bce93
https://github.com/meshtastic/TinyGPSPlus.git#f0f47067ef2f67c856475933188251c1ef615e79
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
Wire ; explicitly needed here because the AXP202 library forgets to add it
@@ -88,7 +88,8 @@ framework = arduino
lib_deps =
${env.lib_deps}
-build_flags = ${env.build_flags} -Os
+build_flags = ${env.build_flags} -Os
+# -DRADIOLIB_GODMODE
src_filter = ${env.src_filter} -
@@ -211,7 +212,7 @@ lib_ignore =
monitor_port = /dev/ttyACM1
# we pass in options to jlink so it can understand freertos (note: we don't use "jlink" as the tool)
-debug_tool = jlink
+;debug_tool = jlink
debug_port = :2331
# Note: the ARGUMENTS MUST BE on multiple lines. Otherwise platformio/commands/debug/helpers.py misparses everything into the "executable"
# attribute and leaves "arguments" empty
@@ -340,32 +341,33 @@ lib_deps =
${arduino_base.lib_deps}
; First prototype eink/nrf52840/sx1262 device
-[env:eink]
+[env:t-echo]
extends = nrf52840_base
-board = eink
+board = t-echo
# add our variants files to the include and src paths
# define build flags for the TFT_eSPI library
-build_flags = ${nrf52_base.build_flags} -Ivariants/eink
+build_flags = ${nrf52_base.build_flags} -Ivariants/t-echo
-DBUSY_PIN=3 -DRST_PIN=2 -DDC_PIN=28 -DCS_PIN=30
-src_filter = ${nrf52_base.src_filter} +<../variants/eink>
+src_filter = ${nrf52_base.src_filter} +<../variants/t-echo>
lib_deps =
${nrf52840_base.lib_deps}
https://github.com/geeksville/EPD_Libraries.git
TFT_eSPI
+;upload_protocol = fs
-; First prototype eink/nrf52840/sx1262 device
-[env:eink0.1]
-extends = nrf52840_base
-board = eink0.1
-# add our variants files to the include and src paths
-# define build flags for the TFT_eSPI library
-build_flags = ${nrf52_base.build_flags} -Ivariants/eink0.1
- -DBUSY_PIN=3 -DRST_PIN=2 -DDC_PIN=28 -DCS_PIN=30
-src_filter = ${nrf52_base.src_filter} +<../variants/eink0.1>
-lib_deps =
- ${nrf52840_base.lib_deps}
- https://github.com/geeksville/EPD_Libraries.git
- TFT_eSPI
+; First prototype eink/nrf52840/sx1262 device (removed from build because didn't ship in quantity)
+;[env:eink0.1]
+;extends = nrf52840_base
+;board = eink0.1
+;# add our variants files to the include and src paths
+;# define build flags for the TFT_eSPI library
+;build_flags = ${nrf52_base.build_flags} -Ivariants/eink0.1
+; -DBUSY_PIN=3 -DRST_PIN=2 -DDC_PIN=28 -DCS_PIN=30
+;src_filter = ${nrf52_base.src_filter} +<../variants/eink0.1>
+;lib_deps =
+; ${nrf52840_base.lib_deps}
+; https://github.com/geeksville/EPD_Libraries.git
+; TFT_eSPI
; The https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay board by @BigCorvus
[env:lora-relay-v1]
@@ -417,7 +419,7 @@ lib_deps =
[env:native]
platform = https://github.com/geeksville/platform-native.git
src_filter = ${env.src_filter} - - - - -
-build_flags = ${arduino_base.build_flags} -O0
+build_flags = ${arduino_base.build_flags} -O0 -lgpiod
framework = arduino
board = native
lib_deps =
diff --git a/proto b/proto
index 157f9891d..5be5307c9 160000
--- a/proto
+++ b/proto
@@ -1 +1 @@
-Subproject commit 157f9891dd35d3087f51e32dc0b103fcb1f0ca7c
+Subproject commit 5be5307c906f1275e4134f839b1d93283484932e
diff --git a/src/Power.cpp b/src/Power.cpp
index 61533887c..2ff783ad9 100644
--- a/src/Power.cpp
+++ b/src/Power.cpp
@@ -120,7 +120,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
/// If we see a battery voltage higher than physics allows - assume charger is pumping
/// in power
- virtual bool isVBUSPlug() { return getBattVoltage() > 1000 * chargingVolt; }
+ virtual bool isVBUSPlug() { return getBattVoltage() > chargingVolt; }
/// Assume charging if we have a battery and external power is connected.
/// we can't be smart enough to say 'full'?
diff --git a/src/SerialConsole.cpp b/src/SerialConsole.cpp
index 137fbcf0d..7435981ea 100644
--- a/src/SerialConsole.cpp
+++ b/src/SerialConsole.cpp
@@ -32,6 +32,13 @@ SerialConsole::SerialConsole() : StreamAPI(&Port), RedirectablePrint(&Port)
emitRebooted();
}
+// For the serial port we can't really detect if any client is on the other side, so instead just look for recent messages
+bool SerialConsole::checkIsConnected()
+{
+ uint32_t now = millis();
+ return (now - lastContactMsec) < getPref_phone_timeout_secs() * 1000UL;
+}
+
/**
* we override this to notice when we've received a protobuf over the serial
* stream. Then we shunt off debug serial output.
@@ -46,14 +53,3 @@ bool SerialConsole::handleToRadio(const uint8_t *buf, size_t len)
return StreamAPI::handleToRadio(buf, len);
}
-/// Hookable to find out when connection changes
-void SerialConsole::onConnectionChanged(bool connected)
-{
- if (connected) { // To prevent user confusion, turn off bluetooth while using the serial port api
- powerFSM.trigger(EVENT_SERIAL_CONNECTED);
- } else {
- // FIXME, we get no notice of serial going away, we should instead automatically generate this event if we haven't
- // received a packet in a while
- powerFSM.trigger(EVENT_SERIAL_DISCONNECTED);
- }
-}
\ No newline at end of file
diff --git a/src/SerialConsole.h b/src/SerialConsole.h
index b057c1931..cc3ec4ec3 100644
--- a/src/SerialConsole.h
+++ b/src/SerialConsole.h
@@ -25,8 +25,9 @@ class SerialConsole : public StreamAPI, public RedirectablePrint
}
protected:
- /// Hookable to find out when connection changes
- virtual void onConnectionChanged(bool connected);
+
+ /// Check the current underlying physical link to see if the client is currently connected
+ virtual bool checkIsConnected();
};
// A simple wrapper to allow non class aware code write to the console
diff --git a/src/configuration.h b/src/configuration.h
index 1e58b7001..63ec177d9 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -413,6 +413,10 @@ along with this program. If not, see .
#define HW_VENDOR HardwareModel_RAK4631
+#elif defined(TTGO_T_ECHO)
+
+#define HW_VENDOR HardwareModel_T_ECHO
+
#elif NRF52_SERIES
#define HW_VENDOR HardwareModel_NRF52_UNKNOWN
@@ -423,11 +427,10 @@ along with this program. If not, see .
#define USE_SIM_RADIO
-#define USE_RF95
-#define LORA_DIO0 26 // a No connect on the SX1262 module
-#define LORA_RESET RADIOLIB_NC
-#define LORA_DIO1 33 // Not really used
-#define LORA_DIO2 32 // Not really used
+// Pine64 uses a common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if
+// not found then probe for SX1262. Currently the RF95 code is disabled because I think the RF95 module won't need to ship.
+// #define USE_RF95
+#define USE_SX1262
// Fake SPI device selections
#define RF95_SCK 5
@@ -435,6 +438,20 @@ along with this program. If not, see .
#define RF95_MOSI 27
#define RF95_NSS RADIOLIB_NC // the ch341f spi controller does CS for us
+#define LORA_DIO0 26 // a No connect on the SX1262 module
+#define LORA_RESET 14
+#define LORA_DIO1 33 // SX1262 IRQ, called DIO0 on pinelora schematic, pin 7 on ch341f "ack" - FIXME, enable hwints in linux
+#define LORA_DIO2 32 // SX1262 BUSY, actually connected to "DIO5" on pinelora schematic, pin 8 on ch341f "slct"
+#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TXCO is enabled
+
+#ifdef USE_SX1262
+#define SX1262_CS 20 // CS0 on pinelora schematic, hooked to gpio D0 on ch341f
+#define SX1262_DIO1 LORA_DIO1
+#define SX1262_BUSY LORA_DIO2
+#define SX1262_RESET LORA_RESET
+// HOPE RFM90 does not have a TCXO therefore not SX1262_E22
+#endif
+
#endif
// DEBUG LED
diff --git a/src/error.h b/src/error.h
index 12cb5a002..0893f02f8 100644
--- a/src/error.h
+++ b/src/error.h
@@ -4,5 +4,8 @@
#include "mesh/generated/mesh.pb.h" // For CriticalErrorCode
+/// A macro that include filename and line
+#define RECORD_CRITICALERROR(code) recordCriticalError(code, __LINE__, __FILE__)
+
/// Record an error that should be reported via analytics
-void recordCriticalError(CriticalErrorCode code = CriticalErrorCode_Unspecified, uint32_t address = 0);
+void recordCriticalError(CriticalErrorCode code = CriticalErrorCode_Unspecified, uint32_t address = 0, const char *filename = NULL);
diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp
index 5f6a54c5c..bc7e816cb 100644
--- a/src/gps/RTC.cpp
+++ b/src/gps/RTC.cpp
@@ -48,14 +48,22 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
shouldSet = false;
if (shouldSet) {
- lastSetMsec = now;
-#ifndef NO_ESP32
- settimeofday(tv, NULL);
- readFromRTC();
-#else
+ lastSetMsec = now;
+
+ // This delta value works on all platforms
timeStartMsec = now;
zeroOffsetSecs = tv->tv_sec;
+
+ // If this platform has a setable RTC, set it
+#ifndef NO_ESP32
+ settimeofday(tv, NULL);
#endif
+
+ // nrf52 doesn't have a readable RTC (yet - software not written)
+#if defined(PORTDUINO) || !defined(NO_ESP32)
+ readFromRTC();
+#endif
+
return true;
} else {
return false;
@@ -84,7 +92,7 @@ bool perhapsSetRTC(RTCQuality q, struct tm &t)
uint32_t getTime()
{
- return ((millis() - timeStartMsec) / 1000) + zeroOffsetSecs;
+ return (((uint32_t) millis() - timeStartMsec) / 1000) + zeroOffsetSecs;
}
uint32_t getValidTime(RTCQuality minQuality)
diff --git a/src/gps/UBloxGPS.cpp b/src/gps/UBloxGPS.cpp
index 8fda6bc43..632f5d5c9 100644
--- a/src/gps/UBloxGPS.cpp
+++ b/src/gps/UBloxGPS.cpp
@@ -43,7 +43,7 @@ bool UBloxGPS::setupGPS()
DEBUG_MSG("Connected to UBLOX GPS successfully\n");
if (!setUBXMode())
- recordCriticalError(CriticalErrorCode_UBloxInitFailed); // Don't halt the boot if saving the config fails, but do report the bug
+ RECORD_CRITICALERROR(CriticalErrorCode_UBloxInitFailed); // Don't halt the boot if saving the config fails, but do report the bug
return true;
} else {
diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp
index c7580f02d..332b9d6d7 100644
--- a/src/graphics/Screen.cpp
+++ b/src/graphics/Screen.cpp
@@ -130,7 +130,7 @@ static void drawIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDispl
// Draw version in upper right
char buf[16];
snprintf(buf, sizeof(buf), "%s",
- xstr(APP_VERSION)); // Note: we don't bother printing region or now, it makes the string too long
+ xstr(APP_VERSION_SHORT)); // Note: we don't bother printing region or now, it makes the string too long
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(buf), y + 0, buf);
screen->forceDisplay();
diff --git a/src/main.cpp b/src/main.cpp
index 11a52156c..1bf8bbcb1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -299,6 +299,13 @@ uint32_t ButtonThread::longPressTime = 0;
RadioInterface *rIf = NULL;
+/**
+ * Some platforms (nrf52) might provide an alterate version that supresses calling delay from sleep.
+ */
+__attribute__ ((weak, noinline)) bool loopCanSleep() {
+ return true;
+}
+
void setup()
{
concurrency::hasBeenSetup = true;
@@ -459,7 +466,7 @@ void setup()
// Do this after service.init (because that clears error_code)
#ifdef AXP192_SLAVE_ADDRESS
if (!axp192_found)
- recordCriticalError(CriticalErrorCode_NoAXP192); // Record a hardware fault for missing hardware
+ RECORD_CRITICALERROR(CriticalErrorCode_NoAXP192); // Record a hardware fault for missing hardware
#endif
// Don't call screen setup until after nodedb is setup (because we need
@@ -550,7 +557,7 @@ void setup()
airTime = new AirTime();
if (!rIf)
- recordCriticalError(CriticalErrorCode_NoRadio);
+ RECORD_CRITICALERROR(CriticalErrorCode_NoRadio);
else
router->addInterface(rIf);
@@ -640,7 +647,7 @@ void loop()
mainController.nextThread->tillRun(millis())); */
// We want to sleep as long as possible here - because it saves power
- if (!runASAP)
+ if (!runASAP && loopCanSleep())
mainDelay.delay(delayMsec);
// if (didWake) DEBUG_MSG("wake!\n");
}
diff --git a/src/mesh/MeshPlugin.cpp b/src/mesh/MeshPlugin.cpp
index 1c14001f2..a31a7b499 100644
--- a/src/mesh/MeshPlugin.cpp
+++ b/src/mesh/MeshPlugin.cpp
@@ -86,10 +86,11 @@ void MeshPlugin::callPlugins(const MeshPacket &mp)
/// We only call plugins that are interested in the packet (and the message is destined to us or we are promiscious)
bool wantsPacket = (isDecoded || pi.encryptedOk) && (pi.isPromiscuous || toUs) && pi.wantPacket(&mp);
- DEBUG_MSG("Plugin %s wantsPacket=%d\n", pi.name, wantsPacket);
assert(!pi.myReply); // If it is !null it means we have a bug, because it should have been sent the previous time
if (wantsPacket) {
+ DEBUG_MSG("Plugin %s wantsPacket=%d\n", pi.name, wantsPacket);
+
pluginFound = true;
/// received channel (or NULL if not decoded)
@@ -97,17 +98,21 @@ void MeshPlugin::callPlugins(const MeshPacket &mp)
/// 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 plugins
- bool rxChannelOk = !pi.boundChannel || (ch && ((mp.from == 0) || (strcmp(ch->settings.name, pi.boundChannel) == 0)));
+
+ /// Also: if a packet comes in on the local PC interface, we don't check for bound channels, because it is TRUSTED and it needs to
+ /// to be able to fetch the initial admin packets without yet knowing any channels.
+
+ bool rxChannelOk = !pi.boundChannel || (mp.from == 0) || (ch && (strcmp(ch->settings.name, pi.boundChannel) == 0));
if (!rxChannelOk) {
// no one should have already replied!
assert(!currentReply);
if (mp.decoded.want_response) {
- DEBUG_MSG("packet on wrong channel, returning error\n");
+ printPacket("packet on wrong channel, returning error", &mp);
currentReply = pi.allocErrorResponse(Routing_Error_NOT_AUTHORIZED, &mp);
} else
- DEBUG_MSG("packet on wrong channel, but client didn't want response\n");
+ printPacket("packet on wrong channel, but can't respond", &mp);
} else {
bool handled = pi.handleReceived(mp);
@@ -149,7 +154,9 @@ void MeshPlugin::callPlugins(const MeshPacket &mp)
printPacket("Sending response", currentReply);
service.sendToMesh(currentReply);
currentReply = NULL;
- } else {
+ } else if(mp.from != ourNodeNum) {
+ // Note: if the message started with the local node we don't want to send a no response reply
+
// No one wanted to reply to this requst, tell the requster that happened
DEBUG_MSG("No one responded, send a nak\n");
diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp
index a6ce8e4c8..f6833d867 100644
--- a/src/mesh/NodeDB.cpp
+++ b/src/mesh/NodeDB.cpp
@@ -541,15 +541,24 @@ NodeInfo *NodeDB::getOrCreateNode(NodeNum n)
}
/// Record an error that should be reported via analytics
-void recordCriticalError(CriticalErrorCode code, uint32_t address)
+void recordCriticalError(CriticalErrorCode code, uint32_t address, const char *filename)
{
// Print error to screen and serial port
String lcd = String("Critical error ") + code + "!\n";
screen->print(lcd.c_str());
- DEBUG_MSG("NOTE! Recording critical error %d, address=%lx\n", code, address);
+ if(filename)
+ DEBUG_MSG("NOTE! Recording critical error %d at %s:%lx\n", code, filename, address);
+ else
+ DEBUG_MSG("NOTE! Recording critical error %d, address=%lx\n", code, address);
// Record error to DB
myNodeInfo.error_code = code;
myNodeInfo.error_address = address;
myNodeInfo.error_count++;
+
+ // Currently portuino is mostly used for simulation. Make sue the user notices something really bad happend
+#ifdef PORTDUINO
+ DEBUG_MSG("A critical failure occurred, portduino is exiting...");
+ exit(2);
+#endif
}
diff --git a/src/mesh/PacketHistory.cpp b/src/mesh/PacketHistory.cpp
index 19ce41bc8..be5a0abc3 100644
--- a/src/mesh/PacketHistory.cpp
+++ b/src/mesh/PacketHistory.cpp
@@ -27,7 +27,7 @@ bool PacketHistory::wasSeenRecently(const MeshPacket *p, bool withUpdate)
recentPackets.erase(recentPackets.begin() + i); // delete old record
} else {
if (r.id == p->id && r.sender == getFrom(p)) {
- DEBUG_MSG("Found existing packet record for fr=0x%x,to=0x%x,id=%d\n", p->from, p->to, p->id);
+ DEBUG_MSG("Found existing packet record for fr=0x%x,to=0x%x,id=0x%x\n", p->from, p->to, p->id);
// Update the time on this record to now
if (withUpdate)
diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp
index 018ab6d3c..8869a8222 100644
--- a/src/mesh/PhoneAPI.cpp
+++ b/src/mesh/PhoneAPI.cpp
@@ -27,6 +27,7 @@ PhoneAPI::~PhoneAPI()
void PhoneAPI::handleStartConfig()
{
+ // Must be before setting state (because state is how we know !connected)
if (!isConnected()) {
onConnectionChanged(true);
observe(&service.fromNumChanged);
@@ -35,7 +36,7 @@ void PhoneAPI::handleStartConfig()
// even if we were already connected - restart our state machine
state = STATE_SEND_MY_INFO;
- DEBUG_MSG("Reset nodeinfo read pointer\n");
+ DEBUG_MSG("Starting API client config\n");
nodeInfoForPhone = NULL; // Don't keep returning old nodeinfos
nodeDB.resetReadPointer(); // FIXME, this read pointer should be moved out of nodeDB and into this class - because
// this will break once we have multiple instances of PhoneAPI running independently
@@ -56,10 +57,9 @@ void PhoneAPI::close()
void PhoneAPI::checkConnectionTimeout()
{
if (isConnected()) {
- uint32_t now = millis();
- bool newContact = (now - lastContactMsec) < getPref_phone_timeout_secs() * 1000UL;
+ bool newContact = checkIsConnected();
if (!newContact) {
- DEBUG_MSG("Timed out on phone contact, dropping phone connection\n");
+ DEBUG_MSG("Lost phone connection\n");
close();
}
}
@@ -93,7 +93,8 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength)
break;
default:
- DEBUG_MSG("Error: unexpected ToRadio variant\n");
+ // Ignore nop messages
+ // DEBUG_MSG("Error: unexpected ToRadio variant\n");
break;
}
} else {
diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h
index 02165aae3..90a8c4d18 100644
--- a/src/mesh/PhoneAPI.h
+++ b/src/mesh/PhoneAPI.h
@@ -50,9 +50,6 @@ class PhoneAPI
/// Use to ensure that clients don't get confused about old messages from the radio
uint32_t config_nonce = 0;
- /** the last msec we heard from the client on the other side of this link */
- uint32_t lastContactMsec = 0;
-
public:
PhoneAPI();
@@ -88,12 +85,18 @@ class PhoneAPI
/// Our fromradio packet while it is being assembled
FromRadio fromRadioScratch;
+ /** the last msec we heard from the client on the other side of this link */
+ uint32_t lastContactMsec = 0;
+
/// Hookable to find out when connection changes
virtual void onConnectionChanged(bool connected) {}
/// If we haven't heard from the other side in a while then say not connected
void checkConnectionTimeout();
+ /// Check the current underlying physical link to see if the client is currently connected
+ virtual bool checkIsConnected() = 0;
+
/**
* Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies)
*/
diff --git a/src/mesh/RF95Interface.cpp b/src/mesh/RF95Interface.cpp
index e99ec2e36..ea3fd0f70 100644
--- a/src/mesh/RF95Interface.cpp
+++ b/src/mesh/RF95Interface.cpp
@@ -94,15 +94,15 @@ bool RF95Interface::reconfigure()
// configure publicly accessible settings
int err = lora->setSpreadingFactor(sf);
if (err != ERR_NONE)
- recordCriticalError(CriticalErrorCode_InvalidRadioSetting);
+ RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
err = lora->setBandwidth(bw);
if (err != ERR_NONE)
- recordCriticalError(CriticalErrorCode_InvalidRadioSetting);
+ RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
err = lora->setCodingRate(cr);
if (err != ERR_NONE)
- recordCriticalError(CriticalErrorCode_InvalidRadioSetting);
+ RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
err = lora->setSyncWord(syncWord);
assert(err == ERR_NONE);
@@ -115,13 +115,13 @@ bool RF95Interface::reconfigure()
err = lora->setFrequency(freq);
if (err != ERR_NONE)
- recordCriticalError(CriticalErrorCode_InvalidRadioSetting);
+ RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
if (power > MAX_POWER) // This chip has lower power limits than some
power = MAX_POWER;
err = lora->setOutputPower(power);
if (err != ERR_NONE)
- recordCriticalError(CriticalErrorCode_InvalidRadioSetting);
+ RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
startReceive(); // restart receiving
diff --git a/src/mesh/RF95Interface.h b/src/mesh/RF95Interface.h
index ebebe3c79..59930adbd 100644
--- a/src/mesh/RF95Interface.h
+++ b/src/mesh/RF95Interface.h
@@ -14,7 +14,6 @@ class RF95Interface : public RadioLibInterface
public:
RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass &spi);
- /// Some boards (Pinetab Lora module) have broken IRQ wires, so we need to poll via i2c registers
bool isIRQPending() { return lora->getPendingIRQ(); }
/// Initialise the Driver transport hardware and software.
diff --git a/src/mesh/RadioInterface.h b/src/mesh/RadioInterface.h
index d263e012d..c0d7ec2d1 100644
--- a/src/mesh/RadioInterface.h
+++ b/src/mesh/RadioInterface.h
@@ -151,6 +151,9 @@ class RadioInterface
*/
float getFreq();
+ /// Some boards (1st gen Pinetab Lora module) have broken IRQ wires, so we need to poll via i2c registers
+ virtual bool isIRQPending() { return false; }
+
protected:
int8_t power = 17; // Set by applyModemConfig()
diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp
index f7a2bc415..e8c15fbe9 100644
--- a/src/mesh/RadioLibInterface.cpp
+++ b/src/mesh/RadioLibInterface.cpp
@@ -75,7 +75,7 @@ bool RadioLibInterface::canSendImmediately()
// TX IRQ from the radio, the radio is probably broken.
if (busyTx && (millis() - lastTxStart > 60000)) {
DEBUG_MSG("Hardware Failure! busyTx for more than 60s\n");
- recordCriticalError(CriticalErrorCode_TransmitFailed);
+ RECORD_CRITICALERROR(CriticalErrorCode_TransmitFailed);
#ifndef NO_ESP32
if (busyTx && (millis() - lastTxStart > 65000)) // After 5s more, reboot
ESP.restart();
@@ -312,7 +312,13 @@ void RadioLibInterface::startSend(MeshPacket *txp)
size_t numbytes = beginSending(txp);
int res = iface->startTransmit(radiobuf, numbytes);
- assert(res == ERR_NONE);
+ if(res != ERR_NONE) {
+ RECORD_CRITICALERROR(CriticalErrorCode_RadioSpiBug);
+
+ // This send failed, but make sure to 'complete' it properly
+ completeSending();
+ startReceive(); // Restart receive mode (because startTransmit failed to put us in xmit mode)
+ }
// Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register bits
enableInterrupt(isrTxLevel0);
diff --git a/src/mesh/ReliableRouter.cpp b/src/mesh/ReliableRouter.cpp
index 131d5bb97..7570ab654 100644
--- a/src/mesh/ReliableRouter.cpp
+++ b/src/mesh/ReliableRouter.cpp
@@ -49,6 +49,9 @@ bool ReliableRouter::shouldFilterReceived(const MeshPacket *p)
stopRetransmission(key);
}
+ else {
+ DEBUG_MSG("didn't find pending packet\n");
+ }
}
return FloodingRouter::shouldFilterReceived(p);
diff --git a/src/mesh/SX1262Interface.cpp b/src/mesh/SX1262Interface.cpp
index 2a68bca30..0a0f92b5f 100644
--- a/src/mesh/SX1262Interface.cpp
+++ b/src/mesh/SX1262Interface.cpp
@@ -59,6 +59,30 @@ bool SX1262Interface::init()
res = lora.setDio2AsRfSwitch(false);
#endif
+#if 0
+ // Read/write a register we are not using (only used for FSK mode) to test SPI comms
+ uint8_t crcLSB = 0;
+ int err = lora.readRegister(SX126X_REG_CRC_POLYNOMIAL_LSB, &crcLSB, 1);
+ if(err != ERR_NONE)
+ RECORD_CRITICALERROR(CriticalErrorCode_SX1262Failure);
+
+ //if(crcLSB != 0x0f)
+ // RECORD_CRITICALERROR(CriticalErrorCode_SX1262Failure);
+
+ crcLSB = 0x5a;
+ err = lora.writeRegister(SX126X_REG_CRC_POLYNOMIAL_LSB, &crcLSB, 1);
+ if(err != ERR_NONE)
+ RECORD_CRITICALERROR(CriticalErrorCode_SX1262Failure);
+
+ err = lora.readRegister(SX126X_REG_CRC_POLYNOMIAL_LSB, &crcLSB, 1);
+ if(err != ERR_NONE)
+ RECORD_CRITICALERROR(CriticalErrorCode_SX1262Failure);
+
+ if(crcLSB != 0x5a)
+ RECORD_CRITICALERROR(CriticalErrorCode_SX1262Failure);
+ // If we got this far register accesses (and therefore SPI comms) are good
+#endif
+
if (res == ERR_NONE)
res = lora.setCRC(SX126X_LORA_CRC_ON);
@@ -78,15 +102,15 @@ bool SX1262Interface::reconfigure()
// configure publicly accessible settings
int err = lora.setSpreadingFactor(sf);
if (err != ERR_NONE)
- recordCriticalError(CriticalErrorCode_InvalidRadioSetting);
+ RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
err = lora.setBandwidth(bw);
if (err != ERR_NONE)
- recordCriticalError(CriticalErrorCode_InvalidRadioSetting);
+ RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
err = lora.setCodingRate(cr);
if (err != ERR_NONE)
- recordCriticalError(CriticalErrorCode_InvalidRadioSetting);
+ RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
// Hmm - seems to lower SNR when the signal levels are high. Leaving off for now...
err = lora.setRxGain(true);
@@ -103,7 +127,7 @@ bool SX1262Interface::reconfigure()
err = lora.setFrequency(freq);
if (err != ERR_NONE)
- recordCriticalError(CriticalErrorCode_InvalidRadioSetting);
+ RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
if (power > 22) // This chip has lower power limits than some
power = 22;
diff --git a/src/mesh/SX1262Interface.h b/src/mesh/SX1262Interface.h
index 30167bc2d..05a93a333 100644
--- a/src/mesh/SX1262Interface.h
+++ b/src/mesh/SX1262Interface.h
@@ -25,6 +25,8 @@ class SX1262Interface : public RadioLibInterface
/// Prepare hardware for sleep. Call this _only_ for deep sleep, not needed for light sleep.
virtual bool sleep();
+ bool isIRQPending() { return lora.getIrqStatus() != 0; }
+
protected:
/**
* Glue functions called from ISR land
diff --git a/src/mesh/StreamAPI.cpp b/src/mesh/StreamAPI.cpp
index 2bc82b084..3785e5028 100644
--- a/src/mesh/StreamAPI.cpp
+++ b/src/mesh/StreamAPI.cpp
@@ -1,4 +1,5 @@
#include "StreamAPI.h"
+#include "PowerFSM.h"
#include "configuration.h"
#define START1 0x94
@@ -28,37 +29,42 @@ int32_t StreamAPI::readStream()
uint8_t c = stream->read();
// Use the read pointer for a little state machine, first look for framing, then length bytes, then payload
- size_t ptr = rxPtr++; // assume we will probably advance the rxPtr
+ size_t ptr = rxPtr;
+ rxPtr++; // assume we will probably advance the rxPtr
rxBuf[ptr] = c; // store all bytes (including framing)
+ // console->printf("rxPtr %d ptr=%d c=0x%x\n", rxPtr, ptr, c);
+
if (ptr == 0) { // looking for START1
if (c != START1)
rxPtr = 0; // failed to find framing
} else if (ptr == 1) { // looking for START2
if (c != START2)
rxPtr = 0; // failed to find framing
- } else if (ptr >= HEADER_LEN) { // we have at least read our 4 byte framing
+ } else if (ptr >= HEADER_LEN - 1) { // we have at least read our 4 byte framing
uint32_t len = (rxBuf[2] << 8) + rxBuf[3]; // big endian 16 bit length follows framing
- if (ptr == HEADER_LEN) {
+ console->printf("len %d\n", len);
+
+ if (ptr == HEADER_LEN - 1) {
// we _just_ finished our 4 byte header, validate length now (note: a length of zero is a valid
// protobuf also)
if (len > MAX_TO_FROM_RADIO_SIZE)
rxPtr = 0; // length is bogus, restart search for framing
}
- if (rxPtr != 0 && ptr + 1 == len + HEADER_LEN) {
- rxPtr = 0; // start over again on the next packet
+ if (rxPtr != 0) // Is packet still considered 'good'?
+ if (ptr + 1 >= len + HEADER_LEN) { // have we received all of the payload?
+ rxPtr = 0; // start over again on the next packet
- // If we didn't just fail the packet and we now have the right # of bytes, parse it
- if (handleToRadio(rxBuf + HEADER_LEN, len))
- return 0; // we want to be called again ASAP because we still have more work to do
- }
+ // If we didn't just fail the packet and we now have the right # of bytes, parse it
+ handleToRadio(rxBuf + HEADER_LEN, len);
+ }
}
}
- // we had packets available this time, so assume we might have them next time also
+ // we had bytes available this time, so assume we might have them next time also
lastRxMsec = now;
return 0;
}
@@ -109,4 +115,18 @@ void StreamAPI::emitRebooted()
// DEBUG_MSG("Emitting reboot packet for serial shell\n");
emitTxBuffer(pb_encode_to_bytes(txBuf + HEADER_LEN, FromRadio_size, FromRadio_fields, &fromRadioScratch));
+}
+
+/// Hookable to find out when connection changes
+void StreamAPI::onConnectionChanged(bool connected)
+{
+ // FIXME do reference counting instead
+
+ if (connected) { // To prevent user confusion, turn off bluetooth while using the serial port api
+ powerFSM.trigger(EVENT_SERIAL_CONNECTED);
+ } else {
+ // FIXME, we get no notice of serial going away, we should instead automatically generate this event if we haven't
+ // received a packet in a while
+ powerFSM.trigger(EVENT_SERIAL_DISCONNECTED);
+ }
}
\ No newline at end of file
diff --git a/src/mesh/StreamAPI.h b/src/mesh/StreamAPI.h
index 6180a95d8..b33e73eac 100644
--- a/src/mesh/StreamAPI.h
+++ b/src/mesh/StreamAPI.h
@@ -67,6 +67,11 @@ class StreamAPI : public PhoneAPI, protected concurrency::OSThread
*/
void emitRebooted();
+ virtual void onConnectionChanged(bool connected);
+
+ /// Check the current underlying physical link to see if the client is currently connected
+ virtual bool checkIsConnected() = 0;
+
/**
* Send the current txBuffer over our stream
*/
diff --git a/src/mesh/generated/mesh.pb.h b/src/mesh/generated/mesh.pb.h
index faa915dbd..fda4c5d90 100644
--- a/src/mesh/generated/mesh.pb.h
+++ b/src/mesh/generated/mesh.pb.h
@@ -46,7 +46,9 @@ typedef enum _CriticalErrorCode {
CriticalErrorCode_NoAXP192 = 6,
CriticalErrorCode_InvalidRadioSetting = 7,
CriticalErrorCode_TransmitFailed = 8,
- CriticalErrorCode_Brownout = 9
+ CriticalErrorCode_Brownout = 9,
+ CriticalErrorCode_SX1262Failure = 10,
+ CriticalErrorCode_RadioSpiBug = 11
} CriticalErrorCode;
typedef enum _Routing_Error {
@@ -216,8 +218,8 @@ typedef struct _ToRadio {
#define _Constants_ARRAYSIZE ((Constants)(Constants_DATA_PAYLOAD_LEN+1))
#define _CriticalErrorCode_MIN CriticalErrorCode_None
-#define _CriticalErrorCode_MAX CriticalErrorCode_Brownout
-#define _CriticalErrorCode_ARRAYSIZE ((CriticalErrorCode)(CriticalErrorCode_Brownout+1))
+#define _CriticalErrorCode_MAX CriticalErrorCode_RadioSpiBug
+#define _CriticalErrorCode_ARRAYSIZE ((CriticalErrorCode)(CriticalErrorCode_RadioSpiBug+1))
#define _Routing_Error_MIN Routing_Error_NONE
#define _Routing_Error_MAX Routing_Error_NOT_AUTHORIZED
diff --git a/src/mesh/http/ContentHandler.h b/src/mesh/http/ContentHandler.h
index 8e22faefc..fc091eff9 100644
--- a/src/mesh/http/ContentHandler.h
+++ b/src/mesh/http/ContentHandler.h
@@ -40,7 +40,9 @@ class HttpAPI : public PhoneAPI
// Nothing here yet
protected:
- // Nothing here yet
+
+ /// Check the current underlying physical link to see if the client is currently connected
+ virtual bool checkIsConnected() { return true; } // FIXME, be smarter about this
};
diff --git a/src/mesh/wifi/WiFiServerAPI.cpp b/src/mesh/wifi/WiFiServerAPI.cpp
index c0be8bc4a..79c749af5 100644
--- a/src/mesh/wifi/WiFiServerAPI.cpp
+++ b/src/mesh/wifi/WiFiServerAPI.cpp
@@ -1,5 +1,4 @@
#include "WiFiServerAPI.h"
-#include "PowerFSM.h"
#include "configuration.h"
#include
@@ -26,18 +25,7 @@ WiFiServerAPI::~WiFiServerAPI()
// FIXME - delete this if the client dropps the connection!
}
-/// Hookable to find out when connection changes
-void WiFiServerAPI::onConnectionChanged(bool connected)
-{
- // FIXME - we really should be doing global reference counting to see if anyone is currently using serial or wifi and if so,
- // block sleep
- if (connected) { // To prevent user confusion, turn off bluetooth while using the serial port api
- powerFSM.trigger(EVENT_SERIAL_CONNECTED);
- } else {
- powerFSM.trigger(EVENT_SERIAL_DISCONNECTED);
- }
-}
/// override close to also shutdown the TCP link
void WiFiServerAPI::close()
@@ -46,6 +34,12 @@ void WiFiServerAPI::close()
StreamAPI::close();
}
+/// Check the current underlying physical link to see if the client is currently connected
+bool WiFiServerAPI::checkIsConnected()
+{
+ return client.connected();
+}
+
int32_t WiFiServerAPI::runOnce()
{
if (client.connected()) {
diff --git a/src/mesh/wifi/WiFiServerAPI.h b/src/mesh/wifi/WiFiServerAPI.h
index 96cfb2bb0..96ff62999 100644
--- a/src/mesh/wifi/WiFiServerAPI.h
+++ b/src/mesh/wifi/WiFiServerAPI.h
@@ -21,10 +21,11 @@ class WiFiServerAPI : public StreamAPI
virtual void close();
protected:
- /// Hookable to find out when connection changes
- virtual void onConnectionChanged(bool connected);
virtual int32_t runOnce(); // Check for dropped client connections
+
+ /// Check the current underlying physical link to see if the client is currently connected
+ virtual bool checkIsConnected();
};
/**
diff --git a/src/nimble/NimbleBluetoothAPI.cpp b/src/nimble/NimbleBluetoothAPI.cpp
index dde9171a3..da2f80ea1 100644
--- a/src/nimble/NimbleBluetoothAPI.cpp
+++ b/src/nimble/NimbleBluetoothAPI.cpp
@@ -31,6 +31,10 @@ void BluetoothPhoneAPI::onNowHasData(uint32_t fromRadioNum)
}
}
+bool BluetoothPhoneAPI::checkIsConnected() {
+ return curConnectionHandle >= 0;
+}
+
int toradio_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
{
auto om = ctxt->om;
diff --git a/src/nimble/NimbleBluetoothAPI.h b/src/nimble/NimbleBluetoothAPI.h
index 5fa66cc24..e2260ba4d 100644
--- a/src/nimble/NimbleBluetoothAPI.h
+++ b/src/nimble/NimbleBluetoothAPI.h
@@ -6,10 +6,14 @@ extern uint16_t fromNumValHandle;
class BluetoothPhoneAPI : public PhoneAPI
{
+protected:
/**
* Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies)
*/
virtual void onNowHasData(uint32_t fromRadioNum);
+
+ /// Check the current underlying physical link to see if the client is currently connected
+ virtual bool checkIsConnected();
};
extern PhoneAPI *bluetoothPhoneAPI;
\ No newline at end of file
diff --git a/src/nrf52/main-nrf52.cpp b/src/nrf52/main-nrf52.cpp
index abb99042c..802c8f9d7 100644
--- a/src/nrf52/main-nrf52.cpp
+++ b/src/nrf52/main-nrf52.cpp
@@ -19,6 +19,10 @@ static inline void debugger_break(void)
"mov pc, lr\n\t");
}
+bool loopCanSleep() {
+ return !tud_cdc_connected();
+}
+
// handle standard gcc assert failures
void __attribute__((noreturn)) __assert_func(const char *file, int line, const char *func, const char *failedexpr)
{
@@ -104,7 +108,7 @@ void checkSDEvents()
while (NRF_SUCCESS == sd_evt_get(&evt)) {
switch (evt) {
case NRF_EVT_POWER_FAILURE_WARNING:
- recordCriticalError(CriticalErrorCode_Brownout);
+ RECORD_CRITICALERROR(CriticalErrorCode_Brownout);
break;
default:
@@ -114,7 +118,7 @@ void checkSDEvents()
}
} else {
if (NRF_POWER->EVENTS_POFWARN)
- recordCriticalError(CriticalErrorCode_Brownout);
+ RECORD_CRITICALERROR(CriticalErrorCode_Brownout);
}
}
diff --git a/src/plugins/AdminPlugin.cpp b/src/plugins/AdminPlugin.cpp
index 9ec305ec7..9c560fdb1 100644
--- a/src/plugins/AdminPlugin.cpp
+++ b/src/plugins/AdminPlugin.cpp
@@ -30,10 +30,11 @@ void AdminPlugin::handleGetRadio(const MeshPacket &req)
AdminMessage r = AdminMessage_init_default;
r.get_radio_response = radioConfig;
- // NOTE: The phone app needs to know the ls_secs value so it can properly expect sleep behavior.
+ // NOTE: The phone app needs to know the ls_secs & phone_timeout value so it can properly expect sleep behavior.
// So even if we internally use 0 to represent 'use default' we still need to send the value we are
// using to the app (so that even old phone apps work with new device loads).
r.get_radio_response.preferences.ls_secs = getPref_ls_secs();
+ r.get_radio_response.preferences.phone_timeout_secs = getPref_phone_timeout_secs();
r.which_variant = AdminMessage_get_radio_response_tag;
myReply = allocDataProtobuf(r);
diff --git a/src/plugins/ExternalNotificationPlugin.cpp b/src/plugins/ExternalNotificationPlugin.cpp
index e48b7beda..d5ad167b6 100644
--- a/src/plugins/ExternalNotificationPlugin.cpp
+++ b/src/plugins/ExternalNotificationPlugin.cpp
@@ -176,5 +176,5 @@ bool ExternalNotificationPlugin::handleReceived(const MeshPacket &mp)
#endif
- return true; // Let others look at this message also if they want
+ return false; // Very important to never return TRUE here. TRUE means we handled the packet and we will stop letting other plugins see it
}
diff --git a/src/portduino/PortduinoGlue.cpp b/src/portduino/PortduinoGlue.cpp
index 876168891..294dc87a4 100644
--- a/src/portduino/PortduinoGlue.cpp
+++ b/src/portduino/PortduinoGlue.cpp
@@ -6,6 +6,7 @@
#include
#include
+#include
// FIXME - move setBluetoothEnable into a HALPlatform class
@@ -21,33 +22,14 @@ void cpuDeepSleep(uint64_t msecs)
void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel");
-/** Dear pinetab hardware geeks!
- *
- * The current pinetab lora module has a slight bug. The ch341 part only provides ISR assertions on edges.
- * This makes sense because USB interrupts happen through fast/repeated special irq urbs that are constantly
- * chattering on the USB bus.
- *
- * But this isn't sufficient for level triggered ISR sources like the sx127x radios. The common way that seems to
- * be addressed by cs341 users is to **always** connect the INT# (pin 26 on the ch341f) signal to one of the GPIO signals
- * on the part. I'd recommend connecting that LORA_DIO0/INT# line to pin 19 (data 4) on the pinetab board. This would
- * provide an efficent mechanism so that the (kernel) code in the cs341 driver that I've slightly hacked up to see the
- * current state of LORA_DIO0. Without that access, I can't know if the interrupt is still pending - which would create
- * race conditions in packet handling.
- *
- * My workaround is to poll the status register internally to the sx127x. Which is expensive because it involves a number of
- * i2c transactions and many trips back and forth between kernel and my userspace app. I think shipping the current version
- * of the pinetab lora device would be fine because I can poll slowly (because lora is slow). But if you ever have cause to
- * rev this board. I highly encourage this small change.
- *
- * Btw - your little "USB lora dongle" is really neat. I encourage you to sell it, because even non pinetab customers could
- * use it to easily add lora to rasberry pi, desktop pcs etc...
- *
+
+/** a simulated pin for busted IRQ hardware
* Porduino helper class to do this i2c based polling:
*/
-class R595PolledIrqPin : public GPIOPin
+class PolledIrqPin : public GPIOPin
{
public:
- R595PolledIrqPin() : GPIOPin(LORA_DIO0, "LORA_DIO0") {}
+ PolledIrqPin() : GPIOPin(LORA_DIO1, "loraIRQ") {}
/// Read the low level hardware for this pin
virtual PinStatus readPinHardware()
@@ -58,14 +40,16 @@ class R595PolledIrqPin : public GPIOPin
extern RadioInterface *rIf; // FIXME, temporary hack until we know if we need to keep this
assert(rIf);
- RF95Interface *rIf95 = static_cast(rIf);
+ RadioLibInterface *rIf95 = static_cast(rIf);
bool p = rIf95->isIRQPending();
- // log(SysGPIO, LogDebug, "R595PolledIrqPin::readPinHardware(%s, %d, %d)", getName(), getPinNum(), p);
+ log(SysGPIO, LogDebug, "PolledIrqPin::readPinHardware(%s, %d, %d)", getName(), getPinNum(), p);
return p ? HIGH : LOW;
}
}
};
+GPIOPin *loraIrq;
+
/** apps run under portduino can optionally define a portduinoSetup() to
* use portduino specific init code (such as gpioBind) to setup portduino on their host machine,
* before running 'arduino' code.
@@ -74,8 +58,26 @@ void portduinoSetup()
{
printf("Setting up Meshtastic on Porduino...\n");
- // FIXME: disable while not testing with real hardware
- // gpioBind(new R595PolledIrqPin());
+ // FIXME: remove this hack once interrupts are confirmed to work on new pine64 board
+ // loraIrq = new PolledIrqPin();
+ loraIrq = new LinuxGPIOPin(LORA_DIO1, "ch341", "int", "loraIrq"); // or "err"?
+ loraIrq->setSilent();
+ gpioBind(loraIrq);
+
+ // BUSY hw was busted on current board - just use the simulated pin (which will read low)
+ auto busy = new LinuxGPIOPin(SX1262_BUSY, "ch341", "slct", "loraBusy");
+ busy->setSilent();
+ gpioBind(busy);
+ //auto fakeBusy = new SimGPIOPin(SX1262_BUSY, "fakeBusy");
+ //fakeBusy->writePin(LOW);
+ //fakeBusy->setSilent(true);
+ //gpioBind(fakeBusy);
+
+ gpioBind(new LinuxGPIOPin(SX1262_RESET, "ch341", "ini", "loraReset"));
+
+ auto loraCs = new LinuxGPIOPin(SX1262_CS, "ch341", "cs0", "loraCs");
+ loraCs->setSilent();
+ gpioBind(loraCs);
// gpioBind((new SimGPIOPin(LORA_RESET, "LORA_RESET")));
// gpioBind((new SimGPIOPin(RF95_NSS, "RF95_NSS"))->setSilent());
diff --git a/src/sleep.cpp b/src/sleep.cpp
index ae175eed2..1021041a2 100644
--- a/src/sleep.cpp
+++ b/src/sleep.cpp
@@ -127,7 +127,7 @@ static void waitEnterSleep()
delay(100); // Kinda yucky - wait until radio says say we can shutdown (finished in process sends/receives)
if (millis() - now > 30 * 1000) { // If we wait too long just report an error and go to sleep
- recordCriticalError(CriticalErrorCode_SleepEnterWait);
+ RECORD_CRITICALERROR(CriticalErrorCode_SleepEnterWait);
assert(0); // FIXME - for now we just restart, need to fix bug #167
break;
}
diff --git a/variants/eink/variant.cpp b/variants/t-echo/variant.cpp
similarity index 100%
rename from variants/eink/variant.cpp
rename to variants/t-echo/variant.cpp
diff --git a/variants/eink/variant.h b/variants/t-echo/variant.h
similarity index 99%
rename from variants/eink/variant.h
rename to variants/t-echo/variant.h
index 66a42421f..3e2317f73 100644
--- a/variants/eink/variant.h
+++ b/variants/t-echo/variant.h
@@ -92,6 +92,8 @@ Note: Turning off EINK PWR_ON produces no noticeable power savings over just put
extern "C" {
#endif // __cplusplus
+#define TTGO_T_ECHO
+
// Number of pins defined in PinDescription array
#define PINS_COUNT (48)
#define NUM_DIGITAL_PINS (48)
@@ -231,8 +233,6 @@ External serial flash WP25R1635FZUIL0
#define PIN_GPS_TX (32 + 9) // This is for bits going TOWARDS the CPU
#define PIN_GPS_RX (32 + 8) // This is for bits going TOWARDS the GPS
-#define HAS_AIR530_GPS
-
#define PIN_SERIAL1_RX PIN_GPS_TX
#define PIN_SERIAL1_TX PIN_GPS_RX
diff --git a/version.properties b/version.properties
index e0d2b5841..e7da90cfe 100644
--- a/version.properties
+++ b/version.properties
@@ -1,4 +1,4 @@
[VERSION]
major = 1
minor = 2
-build = 29
+build = 30