mirror of
https://github.com/meshtastic/firmware.git
synced 2025-08-04 12:44:40 +00:00
Merge branch 'master' into master
This commit is contained in:
commit
42f51f33a8
@ -9,7 +9,7 @@
|
|||||||
; https://docs.platformio.org/page/projectconf.html
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
[platformio]
|
[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
|
;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]
|
[common]
|
||||||
@ -65,7 +65,7 @@ lib_deps =
|
|||||||
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
|
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/arduino-fsm.git#2f106146071fc7bc620e1e8d4b88dc4e0266ce39
|
||||||
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad
|
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/TinyGPSPlus.git#9c1d584d2469523381e077b0b9c1bf868d6c0206
|
||||||
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
|
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
|
||||||
Wire ; explicitly needed here because the AXP202 library forgets to add it
|
Wire ; explicitly needed here because the AXP202 library forgets to add it
|
||||||
@ -314,3 +314,10 @@ src_filter = ${env.src_filter} -<esp32/> -<nimble/> -<nrf52/> -<meshwifi/>
|
|||||||
build_flags = ${arduino_base.build_flags} -O0
|
build_flags = ${arduino_base.build_flags} -O0
|
||||||
framework = arduino
|
framework = arduino
|
||||||
board = linux_x86_64
|
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
|
||||||
|
@ -338,6 +338,35 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define LORA_DIO1 35 // Not really used
|
#define LORA_DIO1 35 // Not really used
|
||||||
#define LORA_DIO2 34 // 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
|
#endif
|
||||||
|
|
||||||
#ifdef ARDUINO_NRF52840_PCA10056
|
#ifdef ARDUINO_NRF52840_PCA10056
|
||||||
@ -365,7 +394,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#define USE_RF95
|
#define USE_RF95
|
||||||
#define LORA_DIO0 26 // a No connect on the SX1262 module
|
#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_DIO1 33 // Not really used
|
||||||
#define LORA_DIO2 32 // Not really used
|
#define LORA_DIO2 32 // Not really used
|
||||||
|
|
||||||
|
@ -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()) {
|
if (client.connected()) {
|
||||||
StreamAPI::loop();
|
StreamAPI::loop();
|
||||||
} else if(isConnected) {
|
return true;
|
||||||
// If our API link was up, shut it down
|
} else {
|
||||||
|
return false;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,15 +59,25 @@ int32_t WiFiServerPort::runOnce()
|
|||||||
auto client = available();
|
auto client = available();
|
||||||
if (client) {
|
if (client) {
|
||||||
// Close any previous connection (see FIXME in header file)
|
// Close any previous connection (see FIXME in header file)
|
||||||
if (openAPI)
|
if (openAPI) {
|
||||||
|
DEBUG_MSG("Force closing previous TCP connection\n");
|
||||||
delete openAPI;
|
delete openAPI;
|
||||||
|
}
|
||||||
|
|
||||||
openAPI = new WiFiServerAPI(client);
|
openAPI = new WiFiServerAPI(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (openAPI) {
|
if (openAPI) {
|
||||||
// Allow idle processing so the API can read from its incoming stream
|
// 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
|
return 0; // run fast while our API server is running
|
||||||
} else
|
} else
|
||||||
return 100; // only check occasionally for incoming connections
|
return 100; // only check occasionally for incoming connections
|
||||||
|
@ -18,7 +18,11 @@ class WiFiServerAPI : public StreamAPI
|
|||||||
|
|
||||||
virtual ~WiFiServerAPI();
|
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:
|
protected:
|
||||||
/// Hookable to find out when connection changes
|
/// Hookable to find out when connection changes
|
||||||
|
@ -36,6 +36,7 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
|
|||||||
|
|
||||||
bool shouldSet;
|
bool shouldSet;
|
||||||
if (q > currentQuality) {
|
if (q > currentQuality) {
|
||||||
|
currentQuality = q;
|
||||||
shouldSet = true;
|
shouldSet = true;
|
||||||
DEBUG_MSG("Upgrading time to RTC %ld secs (quality %d)\n", tv->tv_sec, q);
|
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)) {
|
} else if(q == RTCQualityGPS && (now - lastSetMsec) > (12 * 60 * 60 * 1000L)) {
|
||||||
|
@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
#include "fonts.h"
|
||||||
#include "graphics/images.h"
|
#include "graphics/images.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "mesh-pb-constants.h"
|
#include "mesh-pb-constants.h"
|
||||||
@ -34,7 +35,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include "plugins/TextMessagePlugin.h"
|
#include "plugins/TextMessagePlugin.h"
|
||||||
#include "target_specific.h"
|
#include "target_specific.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "fonts.h"
|
|
||||||
|
|
||||||
using namespace meshtastic; /** @todo remove */
|
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)
|
// 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
|
#define COMPASS_DIAM 44
|
||||||
|
|
||||||
// DEBUG
|
// 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");
|
display->drawString(0 + x, FONT_HEIGHT_MEDIUM + y, "For help, please post on\nmeshtastic.discourse.group");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Draw the last text message we received
|
/// Draw the last text message we received
|
||||||
static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
{
|
{
|
||||||
@ -316,7 +315,7 @@ static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus
|
|||||||
display->drawFastImage(x + 24, y, 8, 8, imgSatellite);
|
display->drawFastImage(x + 24, y, 8, 8, imgSatellite);
|
||||||
|
|
||||||
// Draw the number of satellites
|
// Draw the number of satellites
|
||||||
sprintf(satsString, "%lu", gps->getNumSatellites());
|
sprintf(satsString, "%u", gps->getNumSatellites());
|
||||||
display->drawString(x + 34, y - 2, satsString);
|
display->drawString(x + 34, y - 2, satsString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -569,11 +568,11 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
|||||||
uint32_t agoSecs = sinceLastSeen(node);
|
uint32_t agoSecs = sinceLastSeen(node);
|
||||||
static char lastStr[20];
|
static char lastStr[20];
|
||||||
if (agoSecs < 120) // last 2 mins?
|
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
|
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
|
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];
|
static char distStr[20];
|
||||||
strcpy(distStr, "? km"); // might not have location data
|
strcpy(distStr, "? km"); // might not have location data
|
||||||
@ -924,20 +923,21 @@ void Screen::handleStartBluetoothPinScreen(uint32_t pin)
|
|||||||
setFastFramerate();
|
setFastFramerate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::blink() {
|
void Screen::blink()
|
||||||
|
{
|
||||||
setFastFramerate();
|
setFastFramerate();
|
||||||
uint8_t count = 10;
|
uint8_t count = 10;
|
||||||
dispdev.setBrightness(254);
|
dispdev.setBrightness(254);
|
||||||
while(count>0) {
|
while (count > 0) {
|
||||||
dispdev.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
dispdev.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||||
dispdev.display();
|
dispdev.display();
|
||||||
delay(50);
|
delay(50);
|
||||||
dispdev.clear();
|
dispdev.clear();
|
||||||
dispdev.display();
|
dispdev.display();
|
||||||
delay(50);
|
delay(50);
|
||||||
count = count -1;
|
count = count - 1;
|
||||||
}
|
}
|
||||||
dispdev.setBrightness(brightness);
|
dispdev.setBrightness(brightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::handlePrint(const char *text)
|
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 (WiFi.status() == WL_CONNECTED || isSoftAPForced() || radioConfig.preferences.wifi_ap_mode) {
|
||||||
if (radioConfig.preferences.wifi_ap_mode || isSoftAPForced()) {
|
if (radioConfig.preferences.wifi_ap_mode || isSoftAPForced()) {
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.softAPIP().toString().c_str()));
|
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 {
|
} else {
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.localIP().toString().c_str()));
|
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) {
|
} else if (WiFi.status() == WL_NO_SSID_AVAIL) {
|
||||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "SSID Not Found");
|
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "SSID Not Found");
|
||||||
|
13
src/main.cpp
13
src/main.cpp
@ -389,6 +389,19 @@ void setup()
|
|||||||
|
|
||||||
readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time)
|
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
|
// If we don't have bidirectional comms, we can't even try talking to UBLOX
|
||||||
UBloxGPS *ublox = NULL;
|
UBloxGPS *ublox = NULL;
|
||||||
#ifdef GPS_TX_PIN
|
#ifdef GPS_TX_PIN
|
||||||
|
@ -21,11 +21,17 @@ void PhoneAPI::init()
|
|||||||
observe(&service.fromNumChanged);
|
observe(&service.fromNumChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PhoneAPI::~PhoneAPI() {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
void PhoneAPI::close() {
|
void PhoneAPI::close() {
|
||||||
unobserve();
|
unobserve();
|
||||||
state = STATE_SEND_NOTHING;
|
state = STATE_SEND_NOTHING;
|
||||||
|
bool oldConnected = isConnected;
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
onConnectionChanged(isConnected);
|
if(oldConnected != isConnected)
|
||||||
|
onConnectionChanged(isConnected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhoneAPI::checkConnectionTimeout()
|
void PhoneAPI::checkConnectionTimeout()
|
||||||
|
@ -55,12 +55,15 @@ class PhoneAPI
|
|||||||
public:
|
public:
|
||||||
PhoneAPI();
|
PhoneAPI();
|
||||||
|
|
||||||
|
/// Destructor - calls close()
|
||||||
|
virtual ~PhoneAPI();
|
||||||
|
|
||||||
/// Do late init that can't happen at constructor time
|
/// Do late init that can't happen at constructor time
|
||||||
virtual void init();
|
virtual void init();
|
||||||
|
|
||||||
// Call this when the client drops the connection, resets the state to STATE_SEND_NOTHING
|
// Call this when the client drops the connection, resets the state to STATE_SEND_NOTHING
|
||||||
// Unregisters our observer
|
// Unregisters our observer. A closed connection **can** be reopened by calling init again.
|
||||||
void close();
|
virtual void close();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle a ToRadio protobuf
|
* Handle a ToRadio protobuf
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#define POWER_DEFAULT 17 // How much power to use if the user hasn't set a power level
|
#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)
|
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
|
// FIXME - we assume devices never get destroyed
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,9 @@ class RF95Interface : public RadioLibInterface
|
|||||||
public:
|
public:
|
||||||
RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass &spi);
|
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.
|
/// Initialise the Driver transport hardware and software.
|
||||||
/// Make sure the Driver is properly configured before calling init().
|
/// Make sure the Driver is properly configured before calling init().
|
||||||
/// \return true if initialisation succeeded.
|
/// \return true if initialisation succeeded.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "CryptoEngine.h"
|
#include "CryptoEngine.h"
|
||||||
#include "target_specific.h"
|
#include "target_specific.h"
|
||||||
|
#include "PortduinoGPIO.h"
|
||||||
#include <Utility.h>
|
#include <Utility.h>
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
|
|
||||||
@ -34,4 +35,63 @@ void cpuDeepSleep(uint64_t msecs) {
|
|||||||
// FIXME - implement real crypto for linux
|
// FIXME - implement real crypto for linux
|
||||||
CryptoEngine *crypto = new CryptoEngine();
|
CryptoEngine *crypto = new CryptoEngine();
|
||||||
|
|
||||||
void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel");
|
void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel");
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#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<RF95Interface *>(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
|
||||||
|
* 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 R595PolledIrqPin());
|
||||||
|
// gpioBind((new SimGPIOPin(LORA_RESET, "LORA_RESET")));
|
||||||
|
gpioBind((new SimGPIOPin(RF95_NSS, "RF95_NSS"))->setSilent());
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user