From ca75dcd64dfe087feaa8554e39f2ee3f67b0b54c Mon Sep 17 00:00:00 2001 From: geeksville Date: Thu, 20 Aug 2020 15:42:36 -0700 Subject: [PATCH 1/4] Add support for SX1262 based TBEAMs, see below for more details. We probe dynamically for the SX1262 or RF95 based radios on TBEAM1.0 boards now. If either is present it will be used. --- src/configuration.h | 82 +++++++++++++++++++++++----------- src/main.cpp | 41 +++++++++++++---- src/mesh/RadioLibInterface.cpp | 1 - 3 files changed, 88 insertions(+), 36 deletions(-) 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/main.cpp b/src/main.cpp index 3cc4097d6..0a75798b4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -271,17 +271,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; } From 6a359e212452caebf704599d0c6e50bdb56abfd3 Mon Sep 17 00:00:00 2001 From: geeksville Date: Fri, 21 Aug 2020 09:37:41 -0700 Subject: [PATCH 2/4] don't keep uf2 files in source control --- release/.gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 From d7a1cef0464df2d06e77f56cc70cc69da2795f98 Mon Sep 17 00:00:00 2001 From: geeksville Date: Fri, 21 Aug 2020 10:14:03 -0700 Subject: [PATCH 3/4] fix #327 always factory reset the GPS once --- src/gps/UBloxGPS.cpp | 82 ++++++++++++++++++++++++++------------------ src/gps/UBloxGPS.h | 14 ++++++-- src/main.cpp | 17 +++++++-- src/mesh/mesh.pb.h | 11 +++--- 4 files changed, 83 insertions(+), 41 deletions(-) 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..d87b3fa32 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); 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 From 9c90de0f6ffffbbc0ee19a8aca4b1daffbe65f1b Mon Sep 17 00:00:00 2001 From: geeksville Date: Fri, 21 Aug 2020 10:25:34 -0700 Subject: [PATCH 4/4] 0.9.2 --- bin/version.sh | 2 +- proto | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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