From 5595fb38c1464804c2efbf164755c9172190b1ea Mon Sep 17 00:00:00 2001 From: oztug <76663743+oztug@users.noreply.github.com> Date: Tue, 29 Dec 2020 18:08:11 +0300 Subject: [PATCH 01/12] Genieblocks Lora support --- platformio.ini | 7 +++++++ src/configuration.h | 29 +++++++++++++++++++++++++++++ src/main.cpp | 13 +++++++++++++ 3 files changed, 49 insertions(+) diff --git a/platformio.ini b/platformio.ini index 50d381c8b..d5fbc07f2 100644 --- a/platformio.ini +++ b/platformio.ini @@ -314,3 +314,10 @@ src_filter = ${env.src_filter} - - - - build_flags = ${arduino_base.build_flags} -O0 framework = arduino board = linux_x86_64 + +; The GenieBlocks LORA prototype board +[env:genieblocks_lora] +extends = esp32_base +board = genieblocks_lora +build_flags = + ${esp32_base.build_flags} -D GENIEBLOCKS diff --git a/src/configuration.h b/src/configuration.h index 6fa07ce63..fdc748712 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -336,6 +336,35 @@ along with this program. If not, see . #define LORA_DIO1 35 // Not really used #define LORA_DIO2 34 // Not really used +#elif defined(GENIEBLOCKS) +// This string must exactly match the case used in release file names or the android updater won't work +#define HW_VENDOR "genieblocks" +#undef GPS_RX_PIN +#undef GPS_TX_PIN +#define GPS_RX_PIN 5 +#define GPS_TX_PIN 18 +#define GPS_RESET_N 10 +#define GPS_EXTINT 23 // On MAX-M8 module pin name is EXTINT. On L70 module pin name is STANDBY. + +#define BATTERY_PIN 39 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage +#define BATTERY_EN_PIN 14 // Voltage voltage divider enable pin connected to mosfet + +#define I2C_SDA 4 // I2C pins for this board +#define I2C_SCL 2 + +#define LED_PIN 12 // If defined we will blink this LED +//#define BUTTON_PIN 36 // If defined, this will be used for user button presses (ToDo problem on that line on debug screen --> Long press start!) +//#define BUTTON_NEED_PULLUP //GPIOs 34 to 39 are GPIs – input only pins. These pins don’t have internal pull-ups or pull-down resistors. + +#define USE_RF95 +#define LORA_DIO0 38 // a No connect on the SX1262 module +#define LORA_RESET 9 + +#define RF95_SCK 22 +#define RF95_MISO 19 +#define RF95_MOSI 13 +#define RF95_NSS 21 + #endif #ifdef ARDUINO_NRF52840_PCA10056 diff --git a/src/main.cpp b/src/main.cpp index 648510228..0f4910aae 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -388,6 +388,19 @@ void setup() readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time) +#ifdef GENIEBLOCKS + //gps setup + pinMode (GPS_RESET_N, OUTPUT); + pinMode(GPS_EXTINT, OUTPUT); + digitalWrite(GPS_RESET_N, HIGH); + digitalWrite(GPS_EXTINT, LOW); + //battery setup + // If we want to read battery level, we need to set BATTERY_EN_PIN pin to low. + // ToDo: For low power consumption after read battery level, set that pin to high. + pinMode (BATTERY_EN_PIN, OUTPUT); + digitalWrite(BATTERY_EN_PIN, LOW); +#endif + // If we don't have bidirectional comms, we can't even try talking to UBLOX UBloxGPS *ublox = NULL; #ifdef GPS_TX_PIN From 85ddf3be1bf57fca0539fed38fe1529ac88aee33 Mon Sep 17 00:00:00 2001 From: oztug <76663743+oztug@users.noreply.github.com> Date: Wed, 30 Dec 2020 01:26:12 +0300 Subject: [PATCH 02/12] Update proto --- proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto b/proto index ce422b7c4..323b814f4 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit ce422b7c448906c6fee3eef64bbd41adfbc990f0 +Subproject commit 323b814f4392ae0f9c42a0f14557c6b9333efce3 From 9a3d558f61ac79e102564d186f6a1c157e476655 Mon Sep 17 00:00:00 2001 From: oztug <76663743+oztug@users.noreply.github.com> Date: Wed, 30 Dec 2020 01:27:20 +0300 Subject: [PATCH 03/12] Revert "Update proto" This reverts commit 85ddf3be1bf57fca0539fed38fe1529ac88aee33. --- proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto b/proto index 323b814f4..ce422b7c4 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 323b814f4392ae0f9c42a0f14557c6b9333efce3 +Subproject commit ce422b7c448906c6fee3eef64bbd41adfbc990f0 From cdf416cb730ad4e51d02bdb289691fa5adb2fb2f Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Thu, 31 Dec 2020 09:52:08 +0800 Subject: [PATCH 04/12] partial fix for #608 - when a new TCP API connection arrives, close old one completely --- src/esp32/WiFiServerAPI.cpp | 33 ++++++++++++++++++++++----------- src/esp32/WiFiServerAPI.h | 6 +++++- src/mesh/PhoneAPI.cpp | 8 +++++++- src/mesh/PhoneAPI.h | 7 +++++-- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/esp32/WiFiServerAPI.cpp b/src/esp32/WiFiServerAPI.cpp index 3b11c2ae4..fac955ccc 100644 --- a/src/esp32/WiFiServerAPI.cpp +++ b/src/esp32/WiFiServerAPI.cpp @@ -28,18 +28,19 @@ void WiFiServerAPI::onConnectionChanged(bool connected) } } -void WiFiServerAPI::loop() +/// override close to also shutdown the TCP link +void WiFiServerAPI::close() { + client.stop(); // drop tcp connection + StreamAPI::close(); +} + +bool WiFiServerAPI::loop() { if (client.connected()) { StreamAPI::loop(); - } else if(isConnected) { - // If our API link was up, shut it down - - DEBUG_MSG("Client dropped connection, closing API client\n"); - // Note: we can't call delete here because this object includes other state - // besides the stream API. Instead kill it later when we start a new instance - // delete this; - close(); + return true; + } else { + return false; } } @@ -58,15 +59,25 @@ int32_t WiFiServerPort::runOnce() auto client = available(); if (client) { // Close any previous connection (see FIXME in header file) - if (openAPI) + if (openAPI) { + DEBUG_MSG("Force closing previous TCP connection\n"); delete openAPI; + } openAPI = new WiFiServerAPI(client); } if (openAPI) { // Allow idle processing so the API can read from its incoming stream - openAPI->loop(); + if(!openAPI->loop()) { + // If our API link was up, shut it down + + DEBUG_MSG("Client dropped connection, closing API client\n"); + // Note: we can't call delete here because this object includes other state + // besides the stream API. Instead kill it later when we start a new instance + delete openAPI; + openAPI = NULL; + } return 0; // run fast while our API server is running } else return 100; // only check occasionally for incoming connections diff --git a/src/esp32/WiFiServerAPI.h b/src/esp32/WiFiServerAPI.h index 19f99cbc5..963800203 100644 --- a/src/esp32/WiFiServerAPI.h +++ b/src/esp32/WiFiServerAPI.h @@ -18,7 +18,11 @@ class WiFiServerAPI : public StreamAPI virtual ~WiFiServerAPI(); - virtual void loop(); // Check for dropped client connections + /// @return true if we want to keep running, or false if we are ready to be destroyed + virtual bool loop(); // Check for dropped client connections + + /// override close to also shutdown the TCP link + virtual void close(); protected: /// Hookable to find out when connection changes diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index a0cad4273..545ef2b90 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -21,11 +21,17 @@ void PhoneAPI::init() observe(&service.fromNumChanged); } +PhoneAPI::~PhoneAPI() { + close(); +} + void PhoneAPI::close() { unobserve(); state = STATE_SEND_NOTHING; + bool oldConnected = isConnected; isConnected = false; - onConnectionChanged(isConnected); + if(oldConnected != isConnected) + onConnectionChanged(isConnected); } void PhoneAPI::checkConnectionTimeout() diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h index 202f7fa2d..3cfd97441 100644 --- a/src/mesh/PhoneAPI.h +++ b/src/mesh/PhoneAPI.h @@ -55,12 +55,15 @@ class PhoneAPI public: PhoneAPI(); + /// Destructor - calls close() + virtual ~PhoneAPI(); + /// Do late init that can't happen at constructor time virtual void init(); // Call this when the client drops the connection, resets the state to STATE_SEND_NOTHING - // Unregisters our observer - void close(); + // Unregisters our observer. A closed connection **can** be reopened by calling init again. + virtual void close(); /** * Handle a ToRadio protobuf From 279c89dca361dc450d654eeedff8afd29ec6a581 Mon Sep 17 00:00:00 2001 From: Wei Fang Date: Wed, 30 Dec 2020 21:46:43 -0800 Subject: [PATCH 05/12] Shall upgrade RTC currentQuality if higher q available --- src/gps/RTC.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp index 387f4c0c4..56b51e0af 100644 --- a/src/gps/RTC.cpp +++ b/src/gps/RTC.cpp @@ -36,6 +36,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv) bool shouldSet; if (q > currentQuality) { + currentQuality = q; shouldSet = true; DEBUG_MSG("Upgrading time to RTC %ld secs (quality %d)\n", tv->tv_sec, q); } else if(q == RTCQualityGPS && (now - lastSetMsec) > (12 * 60 * 60 * 1000L)) { From 349701ac14f1cb4547d7cc62f9dd8b5f6c176bf3 Mon Sep 17 00:00:00 2001 From: Jm Date: Thu, 31 Dec 2020 20:17:18 -0800 Subject: [PATCH 06/12] Display AP connection usage only when in AP mode --- platformio.ini | 4 ++-- src/graphics/Screen.cpp | 20 +++++++++++--------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/platformio.ini b/platformio.ini index 50d381c8b..14e6ddbd9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -38,8 +38,8 @@ build_flags = -Wno-missing-field-initializers -Isrc -Isrc/mesh -Isrc/gps -Ilib/n ;upload_port = /dev/ttyUSB0 ;monitor_port = /dev/ttyUSB0 -;upload_port = /dev/cu.SLAB_USBtoUART -;monitor_port = /dev/cu.SLAB_USBtoUART +upload_port = /dev/cu.SLAB_USBtoUART +monitor_port = /dev/cu.SLAB_USBtoUART ; the default is esptool ; upload_protocol = esp-prog diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 6604b0d70..5e03c25f4 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -27,6 +27,7 @@ along with this program. If not, see . #include "NodeDB.h" #include "Screen.h" #include "configuration.h" +#include "fonts.h" #include "graphics/images.h" #include "main.h" #include "mesh-pb-constants.h" @@ -34,7 +35,6 @@ along with this program. If not, see . #include "plugins/TextMessagePlugin.h" #include "target_specific.h" #include "utils.h" -#include "fonts.h" using namespace meshtastic; /** @todo remove */ @@ -42,7 +42,7 @@ namespace graphics { // This means the *visible* area (sh1106 can address 132, but shows 128 for example) -#define IDLE_FRAMERATE 1 // in fps +#define IDLE_FRAMERATE 1 // in fps #define COMPASS_DIAM 44 // DEBUG @@ -177,7 +177,6 @@ static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *sta display->drawString(0 + x, FONT_HEIGHT_MEDIUM + y, "For help, please post on\nmeshtastic.discourse.group"); } - /// Draw the last text message we received static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { @@ -924,20 +923,21 @@ void Screen::handleStartBluetoothPinScreen(uint32_t pin) setFastFramerate(); } -void Screen::blink() { +void Screen::blink() +{ setFastFramerate(); uint8_t count = 10; dispdev.setBrightness(254); - while(count>0) { + while (count > 0) { dispdev.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); dispdev.display(); delay(50); dispdev.clear(); dispdev.display(); delay(50); - count = count -1; + count = count - 1; } - dispdev.setBrightness(brightness); + dispdev.setBrightness(brightness); } void Screen::handlePrint(const char *text) @@ -1060,11 +1060,13 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i if (WiFi.status() == WL_CONNECTED || isSoftAPForced() || radioConfig.preferences.wifi_ap_mode) { if (radioConfig.preferences.wifi_ap_mode || isSoftAPForced()) { display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.softAPIP().toString().c_str())); + + // Number of connections to the AP. Default mmax for the esp32 is 4 + display->drawString(x + SCREEN_WIDTH - display->getStringWidth("(" + String(WiFi.softAPgetStationNum()) + "/4)"), + y + FONT_HEIGHT_SMALL * 1, "(" + String(WiFi.softAPgetStationNum()) + "/4)"); } else { display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.localIP().toString().c_str())); } - display->drawString(x + SCREEN_WIDTH - display->getStringWidth("(" + String(WiFi.softAPgetStationNum()) + "/4)"), - y + FONT_HEIGHT_SMALL * 1, "(" + String(WiFi.softAPgetStationNum()) + "/4)"); } else if (WiFi.status() == WL_NO_SSID_AVAIL) { display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "SSID Not Found"); From d71c7b512f73add5cbe0b8faecd511d9948bb01e Mon Sep 17 00:00:00 2001 From: Jm Date: Thu, 31 Dec 2020 20:44:53 -0800 Subject: [PATCH 07/12] Cleanup some compile time warnings that were driving me crazy. --- src/graphics/Screen.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 5e03c25f4..92e38337e 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -315,7 +315,7 @@ static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus display->drawFastImage(x + 24, y, 8, 8, imgSatellite); // Draw the number of satellites - sprintf(satsString, "%lu", gps->getNumSatellites()); + sprintf(satsString, "%u", gps->getNumSatellites()); display->drawString(x + 34, y - 2, satsString); } } @@ -568,11 +568,11 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_ uint32_t agoSecs = sinceLastSeen(node); static char lastStr[20]; if (agoSecs < 120) // last 2 mins? - snprintf(lastStr, sizeof(lastStr), "%lu seconds ago", agoSecs); + snprintf(lastStr, sizeof(lastStr), "%u seconds ago", agoSecs); else if (agoSecs < 120 * 60) // last 2 hrs - snprintf(lastStr, sizeof(lastStr), "%lu minutes ago", agoSecs / 60); + snprintf(lastStr, sizeof(lastStr), "%u minutes ago", agoSecs / 60); else - snprintf(lastStr, sizeof(lastStr), "%lu hours ago", agoSecs / 60 / 60); + snprintf(lastStr, sizeof(lastStr), "%u hours ago", agoSecs / 60 / 60); static char distStr[20]; strcpy(distStr, "? km"); // might not have location data From 6ec368bf023dc82fa97eebe93f09e8dd16133ae4 Mon Sep 17 00:00:00 2001 From: Jm Date: Thu, 31 Dec 2020 20:50:11 -0800 Subject: [PATCH 08/12] Commenting out upload ports --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 14e6ddbd9..50d381c8b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -38,8 +38,8 @@ build_flags = -Wno-missing-field-initializers -Isrc -Isrc/mesh -Isrc/gps -Ilib/n ;upload_port = /dev/ttyUSB0 ;monitor_port = /dev/ttyUSB0 -upload_port = /dev/cu.SLAB_USBtoUART -monitor_port = /dev/cu.SLAB_USBtoUART +;upload_port = /dev/cu.SLAB_USBtoUART +;monitor_port = /dev/cu.SLAB_USBtoUART ; the default is esptool ; upload_protocol = esp-prog From ebdad76fb2a35dc61559174e58e57ed7b731d5c4 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 2 Jan 2021 11:06:38 +0800 Subject: [PATCH 09/12] portduino: gpios now kinda work on linux --- platformio.ini | 2 +- src/portduino/PortduinoGlue.cpp | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 50d381c8b..78da2c6e1 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ ; https://docs.platformio.org/page/projectconf.html [platformio] -default_envs = tbeam # 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 = linux # 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 = heltec # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here [common] diff --git a/src/portduino/PortduinoGlue.cpp b/src/portduino/PortduinoGlue.cpp index 0862e33f9..c8a7e84c4 100644 --- a/src/portduino/PortduinoGlue.cpp +++ b/src/portduino/PortduinoGlue.cpp @@ -1,5 +1,6 @@ #include "CryptoEngine.h" #include "target_specific.h" +#include "PortduinoGPIO.h" #include #include "sleep.h" @@ -34,4 +35,15 @@ void cpuDeepSleep(uint64_t msecs) { // FIXME - implement real crypto for linux CryptoEngine *crypto = new CryptoEngine(); -void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel"); \ No newline at end of file +void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel"); + + + +/** 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. + */ +void portduinoSetup() { + printf("Setting up Meshtastic on Porduino...\n"); + gpioBind((new SimGPIOPin(RF95_NSS, "RF95_NSS"))->setSilent()); +} From 5ceee50bb5dd81a878910ca8adb085a1395056a1 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 2 Jan 2021 11:23:18 +0800 Subject: [PATCH 10/12] bug: we've always been setting gpio 0 as an input on rf95 based devices found because portduino provides full visibility to all IO operations to the hw simulator. --- src/mesh/RF95Interface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mesh/RF95Interface.cpp b/src/mesh/RF95Interface.cpp index 60596468b..a94a8d129 100644 --- a/src/mesh/RF95Interface.cpp +++ b/src/mesh/RF95Interface.cpp @@ -12,7 +12,7 @@ #define POWER_DEFAULT 17 // How much power to use if the user hasn't set a power level RF95Interface::RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass &spi) - : RadioLibInterface(cs, irq, rst, 0, spi) + : RadioLibInterface(cs, irq, rst, RADIOLIB_NC, spi) { // FIXME - we assume devices never get destroyed } From b0e3a7524f28346f04f39349496aca4d3de4b397 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 2 Jan 2021 11:23:30 +0800 Subject: [PATCH 11/12] assign more portduino pins --- src/portduino/PortduinoGlue.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/portduino/PortduinoGlue.cpp b/src/portduino/PortduinoGlue.cpp index c8a7e84c4..ce63f8dc4 100644 --- a/src/portduino/PortduinoGlue.cpp +++ b/src/portduino/PortduinoGlue.cpp @@ -45,5 +45,7 @@ void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel"); */ void portduinoSetup() { printf("Setting up Meshtastic on Porduino...\n"); + gpioBind((new SimGPIOPin(LORA_DIO0, "LORA_DIO0"))); + gpioBind((new SimGPIOPin(LORA_RESET, "LORA_RESET"))); gpioBind((new SimGPIOPin(RF95_NSS, "RF95_NSS"))->setSilent()); } From aa176b6593c8be4ba462155f1bc4b2170b1042cf Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Sat, 2 Jan 2021 12:38:18 +0800 Subject: [PATCH 12/12] portuino now kinda works with the pinetab lora USB module. still need to add an AEX256 impl for the linux port and optimize a bit --- platformio.ini | 2 +- src/configuration.h | 2 +- src/mesh/RF95Interface.h | 3 ++ src/portduino/PortduinoGlue.cpp | 50 +++++++++++++++++++++++++++++++-- 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/platformio.ini b/platformio.ini index 78da2c6e1..5be5ac571 100644 --- a/platformio.ini +++ b/platformio.ini @@ -65,7 +65,7 @@ lib_deps = 1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib https://github.com/meshtastic/arduino-fsm.git#2f106146071fc7bc620e1e8d4b88dc4e0266ce39 https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad - https://github.com/meshtastic/RadioLib.git#8657380241bce681c33aab46598bbf13b11f876c + https://github.com/meshtastic/RadioLib.git#07de964e929238949035fb0d5887026a3058df1a https://github.com/meshtastic/TinyGPSPlus.git#9c1d584d2469523381e077b0b9c1bf868d6c0206 https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460 Wire ; explicitly needed here because the AXP202 library forgets to add it diff --git a/src/configuration.h b/src/configuration.h index dda2b8d0b..460e1a245 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -365,7 +365,7 @@ along with this program. If not, see . #define USE_RF95 #define LORA_DIO0 26 // a No connect on the SX1262 module -#define LORA_RESET 23 +#define LORA_RESET RADIOLIB_NC #define LORA_DIO1 33 // Not really used #define LORA_DIO2 32 // Not really used diff --git a/src/mesh/RF95Interface.h b/src/mesh/RF95Interface.h index 91f5728c5..ebebe3c79 100644 --- a/src/mesh/RF95Interface.h +++ b/src/mesh/RF95Interface.h @@ -14,6 +14,9 @@ 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. /// Make sure the Driver is properly configured before calling init(). /// \return true if initialisation succeeded. diff --git a/src/portduino/PortduinoGlue.cpp b/src/portduino/PortduinoGlue.cpp index ce63f8dc4..00513843f 100644 --- a/src/portduino/PortduinoGlue.cpp +++ b/src/portduino/PortduinoGlue.cpp @@ -37,6 +37,52 @@ CryptoEngine *crypto = new CryptoEngine(); void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel"); +#include +#include "mesh/RF95Interface.h" + +/** 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... + * + * Porduino helper class to do this i2c based polling: + */ +class R595PolledIrqPin : public GPIOPin { +public: + R595PolledIrqPin() : GPIOPin(LORA_DIO0, "LORA_DIO0") {} + + /// Read the low level hardware for this pin + virtual PinStatus readPinHardware() + { + if(isrPinStatus < 0) + return LOW; // No interrupt handler attached, don't bother polling i2c right now + else { + extern RadioInterface *rIf; // FIXME, temporary hack until we know if we need to keep this + + assert(rIf); + RF95Interface *rIf95 = static_cast(rIf); + bool p = rIf95->isIRQPending(); + // log(SysGPIO, LogDebug, "R595PolledIrqPin::readPinHardware(%s, %d, %d)", getName(), getPinNum(), p); + return p ? HIGH : LOW; + } + } +}; /** apps run under portduino can optionally define a portduinoSetup() to @@ -45,7 +91,7 @@ void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel"); */ void portduinoSetup() { printf("Setting up Meshtastic on Porduino...\n"); - gpioBind((new SimGPIOPin(LORA_DIO0, "LORA_DIO0"))); - gpioBind((new SimGPIOPin(LORA_RESET, "LORA_RESET"))); + gpioBind(new R595PolledIrqPin()); + // gpioBind((new SimGPIOPin(LORA_RESET, "LORA_RESET"))); gpioBind((new SimGPIOPin(RF95_NSS, "RF95_NSS"))->setSilent()); }