diff --git a/bin/version.sh b/bin/version.sh
index bf6adf67a..5a11b5c23 100644
--- a/bin/version.sh
+++ b/bin/version.sh
@@ -1,3 +1,3 @@
-export VERSION=0.9.1
\ No newline at end of file
+export VERSION=0.9.2
\ No newline at end of file
diff --git a/proto b/proto
index c715e506d..3caee2e5b 160000
--- a/proto
+++ b/proto
@@ -1 +1 @@
-Subproject commit c715e506df9ab1a76293d1c20dd5c904b009e1ea
+Subproject commit 3caee2e5b92d4429c6cf47a4c88d4615001f300b
diff --git a/release/.gitignore b/release/.gitignore
index cb3628489..82d2caa70 100644
--- a/release/.gitignore
+++ b/release/.gitignore
@@ -1,4 +1,5 @@
*.elf
*.bin
*.map
-*.zip
\ No newline at end of file
+*.zip
+*.uf2
diff --git a/src/configuration.h b/src/configuration.h
index d23a42f84..4b1addbb3 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -158,12 +158,26 @@ along with this program. If not, see .
#define BUTTON_PIN 38 // The middle button GPIO on the T-Beam
#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed
-#ifndef USE_JTAG
-#define RF95_RESET 14
+// TTGO 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
+#define USE_RF95
+#define USE_SX1262
+
+#define LORA_DIO0 26 // a No connect on the SX1262 module
+#define LORA_RESET 23
+#define LORA_DIO1 33 // SX1262 IRQ
+#define LORA_DIO2 32 // SX1262 BUSY
+#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 RF95_NSS // FIXME - we really should define LORA_CS instead
+#define SX1262_DIO1 LORA_DIO1
+#define SX1262_BUSY LORA_DIO2
+#define SX1262_RESET LORA_RESET
+#define SX1262_E22 // Not really an E22 but TTGO seems to be trying to clone that
+// Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface
+// code)
#endif
-#define RF95_IRQ 26
-#define RF95_DIO1 33 // Note: not really used on this board
-#define RF95_DIO2 32 // Note: not really used on this board
// Leave undefined to disable our PMU IRQ handler
#define PMU_IRQ 35
@@ -181,12 +195,13 @@ along with this program. If not, see .
#define BUTTON_PIN 39
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
-#ifndef USE_JTAG
-#define RF95_RESET 23
-#endif
-#define RF95_IRQ 26
-#define RF95_DIO1 33 // Note: not really used on this board
-#define RF95_DIO2 32 // Note: not really used on this board
+#define USE_RF95
+
+#define USE_RF95
+#define LORA_DIO0 26 // a No connect on the SX1262 module
+#define LORA_RESET 23
+#define LORA_DIO1 33 // Not really used
+#define LORA_DIO2 32 // Not really used
// This board has different GPS pins than all other boards
#undef GPS_RX_PIN
@@ -216,12 +231,14 @@ along with this program. If not, see .
#define LED_PIN 25 // If defined we will blink this LED
#define BUTTON_PIN 0 // If defined, this will be used for user button presses
+#define USE_RF95
+#define LORA_DIO0 26 // a No connect on the SX1262 module
#ifndef USE_JTAG
-#define RF95_RESET 14 // If defined, this pin will be used to reset the LORA radio
+#define LORA_RESET 14
#endif
-#define RF95_IRQ 26
-#define RF95_DIO1 35 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number
-#define RF95_DIO2 34 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number
+#define LORA_DIO1 35 // Not really used
+#define LORA_DIO2 34 // Not really used
+
#elif defined(TLORA_V1)
// This string must exactly match the case used in release file names or the android updater won't work
#define HW_VENDOR "tlora-v1"
@@ -239,10 +256,11 @@ along with this program. If not, see .
#define LED_PIN 2 // If defined we will blink this LED
#define BUTTON_PIN 0 // If defined, this will be used for user button presses
-#define RF95_RESET 14 // If defined, this pin will be used to reset the LORA radio
-#define RF95_IRQ 26 // IRQ line for the LORA radio
-#define RF95_DIO1 35 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number
-#define RF95_DIO2 34 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number
+#define USE_RF95
+#define LORA_DIO0 26 // a No connect on the SX1262 module
+#define LORA_RESET 14
+#define LORA_DIO1 35 // Not really used
+#define LORA_DIO2 34 // Not really used
#elif defined(TLORA_V2)
// This string must exactly match the case used in release file names or the android updater won't work
@@ -264,10 +282,11 @@ along with this program. If not, see .
0 // If defined, this will be used for user button presses, if your board doesn't have a physical switch, you can wire one
// between this pin and ground
-#define RESET_GPIO 14 // If defined, this pin will be used to reset the LORA radio
-#define RF95_IRQ_GPIO 26 // IRQ line for the LORA radio
-#define DIO1_GPIO 35 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number
-#define DIO2_GPIO 34 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number
+#define USE_RF95
+#define LORA_DIO0 26 // a No connect on the SX1262 module
+#define LORA_RESET 14
+#define LORA_DIO1 35 // Not really used
+#define LORA_DIO2 34 // Not really used
#elif defined(TLORA_V2_1_16)
// This string must exactly match the case used in release file names or the android updater won't work
@@ -291,10 +310,12 @@ along with this program. If not, see .
12 // If defined, this will be used for user button presses, if your board doesn't have a physical switch, you can wire one
// between this pin and ground
-#define RF95_RESET 14 // If defined, this pin will be used to reset the LORA radio
-#define RF95_IRQ 26 // IRQ line for the LORA radio
-#define RF95_DIO1 35 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number
-#define RF95_DIO2 34 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number
+#define USE_RF95
+#define LORA_DIO0 26 // a No connect on the SX1262 module
+#define LORA_RESET 14
+#define LORA_DIO1 35 // Not really used
+#define LORA_DIO2 34 // Not really used
+
#endif
#ifdef ARDUINO_NRF52840_PCA10056
@@ -316,6 +337,13 @@ along with this program. If not, see .
#endif
+#ifdef USE_RF95
+#define RF95_RESET LORA_RESET
+#define RF95_IRQ LORA_DIO0 // on SX1262 version this is a no connect DIO0
+#define RF95_DIO1 LORA_DIO1 // Note: not really used for RF95
+#define RF95_DIO2 LORA_DIO2 // Note: not really used for RF95
+#endif
+
// -----------------------------------------------------------------------------
// DEBUG
// -----------------------------------------------------------------------------
diff --git a/src/gps/UBloxGPS.cpp b/src/gps/UBloxGPS.cpp
index c7a8501c1..cab1ada4c 100644
--- a/src/gps/UBloxGPS.cpp
+++ b/src/gps/UBloxGPS.cpp
@@ -52,39 +52,7 @@ bool UBloxGPS::setup()
if (isConnected) {
DEBUG_MSG("Connected to UBLOX GPS successfully\n");
- bool factoryReset = false;
- bool ok;
- if (factoryReset) {
- // It is useful to force back into factory defaults (9600baud, NEMA to test the behavior of boards that don't have
- // GPS_TX connected)
- ublox.factoryReset();
- delay(3000);
- tryConnect();
- DEBUG_MSG("Factory reset success=%d\n", isConnected);
- ok = ublox.saveConfiguration(3000);
- assert(ok);
- return false;
- } else {
- if (_serial_gps) {
- ok = ublox.setUART1Output(COM_TYPE_UBX, 500); // Use native API
- assert(ok);
- }
- if (i2cAddress) {
- ok = ublox.setI2COutput(COM_TYPE_UBX, 500);
- assert(ok);
- }
-
- ok = ublox.setNavigationFrequency(1, 500); // Produce 4x/sec to keep the amount of time we stall in getPVT low
- assert(ok);
- // ok = ublox.setAutoPVT(false); // Not implemented on NEO-6M
- // assert(ok);
- // ok = ublox.setDynamicModel(DYN_MODEL_BIKE); // probably PEDESTRIAN but just in case assume bike speeds
- // assert(ok);
- ok = ublox.powerSaveMode(true, 2000); // use power save mode, the default timeout (1100ms seems a bit too tight)
- assert(ok);
- }
- ok = ublox.saveConfiguration(3000);
- if (!ok)
+ if (!setUBXMode())
recordCriticalError(UBloxInitFailed); // Don't halt the boot if saving the config fails, but do report the bug
concurrency::PeriodicTask::setup(); // We don't start our periodic task unless we actually found the device
@@ -95,6 +63,54 @@ bool UBloxGPS::setup()
}
}
+bool UBloxGPS::setUBXMode()
+{
+ if (_serial_gps) {
+ if (!ublox.setUART1Output(COM_TYPE_UBX, 1000)) // Use native API
+ return false;
+ }
+ if (i2cAddress) {
+ if (!ublox.setI2COutput(COM_TYPE_UBX, 1000))
+ return false;
+ }
+
+ if (!ublox.setNavigationFrequency(1, 1000)) // Produce 4x/sec to keep the amount of time we stall in getPVT low
+ return false;
+
+ // ok = ublox.setAutoPVT(false); // Not implemented on NEO-6M
+ // assert(ok);
+ // ok = ublox.setDynamicModel(DYN_MODEL_BIKE); // probably PEDESTRIAN but just in case assume bike speeds
+ // assert(ok);
+ if (!ublox.powerSaveMode(true, 2000)) // use power save mode, the default timeout (1100ms seems a bit too tight)
+ return false;
+
+ if (!ublox.saveConfiguration(3000))
+ return false;
+
+ return true;
+}
+
+/**
+ * Reset our GPS back to factory settings
+ *
+ * @return true for success
+ */
+bool UBloxGPS::factoryReset()
+{
+ bool ok = false;
+
+ // It is useful to force back into factory defaults (9600baud, NEMA to test the behavior of boards that don't have
+ // GPS_TX connected)
+ ublox.factoryReset();
+ delay(3000);
+ tryConnect(); // sets isConnected
+ DEBUG_MSG("GPS Factory reset success=%d\n", isConnected);
+ if (isConnected)
+ ok = setUBXMode();
+
+ return ok;
+}
+
/// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs
int UBloxGPS::prepareSleep(void *unused)
{
diff --git a/src/gps/UBloxGPS.h b/src/gps/UBloxGPS.h
index e0e3d636b..7a2d3cdba 100644
--- a/src/gps/UBloxGPS.h
+++ b/src/gps/UBloxGPS.h
@@ -1,8 +1,8 @@
#pragma once
+#include "../concurrency/PeriodicTask.h"
#include "GPS.h"
#include "Observer.h"
-#include "../concurrency/PeriodicTask.h"
#include "SparkFun_Ublox_Arduino_Library.h"
/**
@@ -33,12 +33,22 @@ class UBloxGPS : public GPS, public concurrency::PeriodicTask
* called after the CPU wakes from light-sleep state */
virtual void startLock();
- private:
+ /**
+ * Reset our GPS back to factory settings
+ *
+ * @return true for success
+ */
+ bool factoryReset();
+ private:
/// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs
/// always returns 0 to indicate okay to sleep
int prepareSleep(void *unused);
/// Attempt to connect to our GPS, returns false if no gps is present
bool tryConnect();
+
+ /// Switch to our desired operating mode and save the settings to flash
+ /// returns true for success
+ bool setUBXMode();
};
diff --git a/src/main.cpp b/src/main.cpp
index 3cc4097d6..ce9e3d46b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -231,15 +231,18 @@ void setup()
// If we know we have a L80 GPS, don't try UBLOX
#ifndef L80_RESET
// Init GPS - first try ublox
- gps = new UBloxGPS();
+ auto ublox = new UBloxGPS();
+ gps = ublox;
if (!gps->setup()) {
DEBUG_MSG("ERROR: No UBLOX GPS found\n");
+ delete ublox;
+ gps = ublox = NULL;
+
if (GPS::_serial_gps) {
// Some boards might have only the TX line from the GPS connected, in that case, we can't configure it at all. Just
// assume NEMA at 9600 baud.
DEBUG_MSG("Hoping that NEMA might work\n");
- delete gps;
// dumb NEMA access only work for serial GPSes)
gps = new NEMAGPS();
@@ -255,6 +258,16 @@ void setup()
service.init();
+ // We have now loaded our saved preferences from flash
+
+ // ONCE we will factory reset the GPS for bug #327
+ if (ublox && !devicestate.did_gps_reset) {
+ if (ublox->factoryReset()) { // If we don't succeed try again next time
+ devicestate.did_gps_reset = true;
+ nodeDB.saveToDisk();
+ }
+ }
+
#ifdef SX1262_ANT_SW
// make analog PA vs not PA switch on SX1262 eval board work properly
pinMode(SX1262_ANT_SW, OUTPUT);
@@ -271,17 +284,42 @@ void setup()
#endif
// MUST BE AFTER service.init, so we have our radio config settings (from nodedb init)
- RadioInterface *rIf =
+ RadioInterface *rIf = NULL;
+
#if defined(RF95_IRQ)
- // new CustomRF95(); old Radiohead based driver
- new RF95Interface(RF95_NSS, RF95_IRQ, RF95_RESET, SPI);
-#elif defined(SX1262_CS)
- new SX1262Interface(SX1262_CS, SX1262_DIO1, SX1262_RESET, SX1262_BUSY, SPI);
-#else
- new SimRadio();
+ if (!rIf) {
+ rIf = new RF95Interface(RF95_NSS, RF95_IRQ, RF95_RESET, SPI);
+ if (!rIf->init()) {
+ DEBUG_MSG("Warning: Failed to find RF95 radio\n");
+ delete rIf;
+ rIf = NULL;
+ }
+ }
#endif
- if (!rIf || !rIf->init())
+#if defined(SX1262_CS)
+ if (!rIf) {
+ rIf = new SX1262Interface(SX1262_CS, SX1262_DIO1, SX1262_RESET, SX1262_BUSY, SPI);
+ if (!rIf->init()) {
+ DEBUG_MSG("Warning: Failed to find SX1262 radio\n");
+ delete rIf;
+ rIf = NULL;
+ }
+ }
+#endif
+
+#ifdef USE_SIM_RADIO
+ if (!rIf) {
+ rIf = new SimRadio;
+ if (!rIf->init()) {
+ DEBUG_MSG("Warning: Failed to find simulated radio\n");
+ delete rIf;
+ rIf = NULL;
+ }
+ }
+#endif
+
+ if (!rIf)
recordCriticalError(ErrNoRadio);
else
router.addInterface(rIf);
diff --git a/src/mesh/RadioLibInterface.cpp b/src/mesh/RadioLibInterface.cpp
index bfaefb1f2..ae94231d2 100644
--- a/src/mesh/RadioLibInterface.cpp
+++ b/src/mesh/RadioLibInterface.cpp
@@ -13,7 +13,6 @@ RadioLibInterface::RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq
SPIClass &spi, PhysicalLayer *_iface)
: concurrency::PeriodicTask(0), module(cs, irq, rst, busy, spi, spiSettings), iface(_iface)
{
- assert(!instance); // We assume only one for now
instance = this;
}
diff --git a/src/mesh/mesh.pb.h b/src/mesh/mesh.pb.h
index 23ed6b5db..27ff63f9b 100644
--- a/src/mesh/mesh.pb.h
+++ b/src/mesh/mesh.pb.h
@@ -193,6 +193,7 @@ typedef struct _DeviceState {
MeshPacket rx_text_message;
uint32_t version;
bool no_save;
+ bool did_gps_reset;
} DeviceState;
typedef struct _FromRadio {
@@ -250,7 +251,7 @@ typedef struct _ToRadio {
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, {0, 0, 0}}
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0}
#define MyNodeInfo_init_default {0, 0, 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0}
-#define DeviceState_init_default {false, RadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0}
+#define DeviceState_init_default {false, RadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0}
#define DebugString_init_default {""}
#define FromRadio_init_default {0, 0, {MeshPacket_init_default}}
#define ToRadio_init_default {0, {MeshPacket_init_default}}
@@ -266,7 +267,7 @@ typedef struct _ToRadio {
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, {0, 0, 0}}
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0}
#define MyNodeInfo_init_zero {0, 0, 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0}
-#define DeviceState_init_zero {false, RadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0}
+#define DeviceState_init_zero {false, RadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0}
#define DebugString_init_zero {""}
#define FromRadio_init_zero {0, 0, {MeshPacket_init_zero}}
#define ToRadio_init_zero {0, {MeshPacket_init_zero}}
@@ -363,6 +364,7 @@ typedef struct _ToRadio {
#define DeviceState_version_tag 8
#define DeviceState_rx_text_message_tag 7
#define DeviceState_no_save_tag 9
+#define DeviceState_did_gps_reset_tag 10
#define FromRadio_packet_tag 2
#define FromRadio_my_info_tag 3
#define FromRadio_node_info_tag 4
@@ -516,7 +518,8 @@ X(a, STATIC, REPEATED, MESSAGE, node_db, 4) \
X(a, STATIC, REPEATED, MESSAGE, receive_queue, 5) \
X(a, STATIC, OPTIONAL, MESSAGE, rx_text_message, 7) \
X(a, STATIC, SINGULAR, UINT32, version, 8) \
-X(a, STATIC, SINGULAR, BOOL, no_save, 9)
+X(a, STATIC, SINGULAR, BOOL, no_save, 9) \
+X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 10)
#define DeviceState_CALLBACK NULL
#define DeviceState_DEFAULT NULL
#define DeviceState_radio_MSGTYPE RadioConfig
@@ -614,7 +617,7 @@ extern const pb_msgdesc_t ManufacturingData_msg;
#define RadioConfig_UserPreferences_size 188
#define NodeInfo_size 132
#define MyNodeInfo_size 110
-#define DeviceState_size 5427
+#define DeviceState_size 5429
#define DebugString_size 258
#define FromRadio_size 322
#define ToRadio_size 316