From 2ba68c9b6e96e679197087c17fc047fe0fa7e6ba Mon Sep 17 00:00:00 2001
From: Vladislav Osmanov <7123463+osmanovv@users.noreply.github.com>
Date: Fri, 3 Sep 2021 17:15:58 +0300
Subject: [PATCH 01/10] added SX1268 module adapter
---
src/main.cpp | 20 +++
src/mesh/SX1268Interface.cpp | 249 +++++++++++++++++++++++++++++++++++
src/mesh/SX1268Interface.h | 62 +++++++++
3 files changed, 331 insertions(+)
create mode 100644 src/mesh/SX1268Interface.cpp
create mode 100644 src/mesh/SX1268Interface.h
diff --git a/src/main.cpp b/src/main.cpp
index a1de8dc6f..273c7adc8 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -39,6 +39,7 @@
#include "RF95Interface.h"
#include "SX1262Interface.h"
+#include "SX1268Interface.h"
#ifdef NRF52_SERIES
#include "variant.h"
@@ -497,6 +498,12 @@ void setup()
digitalWrite(SX1262_ANT_SW, 1);
#endif
+#ifdef SX1268_ANT_SW
+ // make analog PA vs not PA switch on SX1268 eval board work properly
+ pinMode(SX1268_ANT_SW, OUTPUT);
+ digitalWrite(SX1268_ANT_SW, 1);
+#endif
+
// radio init MUST BE AFTER service.init, so we have our radio config settings (from nodedb init)
#if defined(RF95_IRQ)
@@ -525,6 +532,19 @@ void setup()
}
#endif
+#if defined(SX1268_CS)
+ if (!rIf) {
+ rIf = new SX1268Interface(SX1268_CS, SX1268_DIO1, SX1268_RESET, SX1268_BUSY, SPI);
+ if (!rIf->init()) {
+ DEBUG_MSG("Warning: Failed to find SX1268 radio\n");
+ delete rIf;
+ rIf = NULL;
+ } else {
+ DEBUG_MSG("SX1268 Radio init succeeded, using SX1268 radio\n");
+ }
+ }
+#endif
+
#ifdef USE_SIM_RADIO
if (!rIf) {
rIf = new SimRadio;
diff --git a/src/mesh/SX1268Interface.cpp b/src/mesh/SX1268Interface.cpp
new file mode 100644
index 000000000..9d0df82c6
--- /dev/null
+++ b/src/mesh/SX1268Interface.cpp
@@ -0,0 +1,249 @@
+#include "configuration.h"
+#include "SX1268Interface.h"
+#include "error.h"
+
+// Particular boards might define a different max power based on what their hardware can do
+#ifndef SX1268_MAX_POWER
+#define SX1268_MAX_POWER 22
+#endif
+
+SX1268Interface::SX1268Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
+ SPIClass &spi)
+ : RadioLibInterface(cs, irq, rst, busy, spi, &lora), lora(&module)
+{
+}
+
+/// Initialise the Driver transport hardware and software.
+/// Make sure the Driver is properly configured before calling init().
+/// \return true if initialisation succeeded.
+bool SX1268Interface::init()
+{
+#ifdef SX1268_POWER_EN
+ digitalWrite(SX1268_POWER_EN, HIGH);
+ pinMode(SX1268_POWER_EN, OUTPUT);
+#endif
+
+#ifdef SX1268_RXEN // set not rx or tx mode
+ digitalWrite(SX1268_RXEN, LOW); // Set low before becoming an output
+ pinMode(SX1268_RXEN, OUTPUT);
+#endif
+#ifdef SX1268_TXEN
+ digitalWrite(SX1268_TXEN, LOW);
+ pinMode(SX1268_TXEN, OUTPUT);
+#endif
+
+#ifndef SX1268_E22
+ float tcxoVoltage = 0; // None - we use an XTAL
+#else
+ // Use DIO3 to power tcxo per https://github.com/jgromes/RadioLib/issues/12#issuecomment-520695575
+ float tcxoVoltage = 1.8;
+#endif
+ bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC?
+
+ RadioLibInterface::init();
+
+ if (power == 0)
+ power = SX1268_MAX_POWER;
+
+ if (power > SX1268_MAX_POWER) // This chip has lower power limits than some
+ power = SX1268_MAX_POWER;
+
+ limitPower();
+
+ int res = lora.begin(freq, bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage, useRegulatorLDO);
+ DEBUG_MSG("SX1268 init result %d\n", res);
+
+#ifdef SX1268_TXEN
+ // lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX
+ if (res == ERR_NONE)
+ 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_SX1268Failure);
+
+ //if(crcLSB != 0x0f)
+ // RECORD_CRITICALERROR(CriticalErrorCode_SX1268Failure);
+
+ crcLSB = 0x5a;
+ err = lora.writeRegister(SX126X_REG_CRC_POLYNOMIAL_LSB, &crcLSB, 1);
+ if(err != ERR_NONE)
+ RECORD_CRITICALERROR(CriticalErrorCode_SX1268Failure);
+
+ err = lora.readRegister(SX126X_REG_CRC_POLYNOMIAL_LSB, &crcLSB, 1);
+ if(err != ERR_NONE)
+ RECORD_CRITICALERROR(CriticalErrorCode_SX1268Failure);
+
+ if(crcLSB != 0x5a)
+ RECORD_CRITICALERROR(CriticalErrorCode_SX1268Failure);
+ // 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);
+
+ if (res == ERR_NONE)
+ startReceive(); // start receiving
+
+ return res == ERR_NONE;
+}
+
+bool SX1268Interface::reconfigure()
+{
+ RadioLibInterface::reconfigure();
+
+ // set mode to standby
+ setStandby();
+
+ // configure publicly accessible settings
+ int err = lora.setSpreadingFactor(sf);
+ if (err != ERR_NONE)
+ RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
+
+ err = lora.setBandwidth(bw);
+ if (err != ERR_NONE)
+ RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
+
+ err = lora.setCodingRate(cr);
+ if (err != ERR_NONE)
+ RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
+
+ // Hmm - seems to lower SNR when the signal levels are high. Leaving off for now...
+ err = lora.setRxGain(true);
+ assert(err == ERR_NONE);
+
+ err = lora.setSyncWord(syncWord);
+ assert(err == ERR_NONE);
+
+ err = lora.setCurrentLimit(currentLimit);
+ assert(err == ERR_NONE);
+
+ err = lora.setPreambleLength(preambleLength);
+ assert(err == ERR_NONE);
+
+ err = lora.setFrequency(freq);
+ if (err != ERR_NONE)
+ RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
+
+ if (power > 22) // This chip has lower power limits than some
+ power = 22;
+ err = lora.setOutputPower(power);
+ assert(err == ERR_NONE);
+
+ startReceive(); // restart receiving
+
+ return ERR_NONE;
+}
+
+void INTERRUPT_ATTR SX1268Interface::disableInterrupt()
+{
+ lora.clearDio1Action();
+}
+
+void SX1268Interface::setStandby()
+{
+ int err = lora.standby();
+ assert(err == ERR_NONE);
+
+#ifdef SX1268_RXEN // we have RXEN/TXEN control - turn off RX and TX power
+ digitalWrite(SX1268_RXEN, LOW);
+#endif
+#ifdef SX1268_TXEN
+ digitalWrite(SX1268_TXEN, LOW);
+#endif
+
+ isReceiving = false; // If we were receiving, not any more
+ disableInterrupt();
+ completeSending(); // If we were sending, not anymore
+}
+
+/**
+ * Add SNR data to received messages
+ */
+void SX1268Interface::addReceiveMetadata(MeshPacket *mp)
+{
+ // DEBUG_MSG("PacketStatus %x\n", lora.getPacketStatus());
+ mp->rx_snr = lora.getSNR();
+ mp->rx_rssi = lround(lora.getRSSI());
+}
+
+/** We override to turn on transmitter power as needed.
+ */
+void SX1268Interface::configHardwareForSend()
+{
+#ifdef SX1268_TXEN // we have RXEN/TXEN control - turn on TX power / off RX power
+ digitalWrite(SX1268_TXEN, HIGH);
+#endif
+
+ RadioLibInterface::configHardwareForSend();
+}
+
+// For power draw measurements, helpful to force radio to stay sleeping
+// #define SLEEP_ONLY
+
+void SX1268Interface::startReceive()
+{
+#ifdef SLEEP_ONLY
+ sleep();
+#else
+
+ setStandby();
+
+#ifdef SX1268_RXEN // we have RXEN/TXEN control - turn on RX power / off TX power
+ digitalWrite(SX1268_RXEN, HIGH);
+#endif
+
+ // int err = lora.startReceive();
+ int err = lora.startReceiveDutyCycleAuto(); // We use a 32 bit preamble so this should save some power by letting radio sit in
+ // standby mostly.
+ assert(err == ERR_NONE);
+
+ isReceiving = true;
+
+ // Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register bits
+ enableInterrupt(isrRxLevel0);
+#endif
+}
+
+/** Could we send right now (i.e. either not actively receving or transmitting)? */
+bool SX1268Interface::isActivelyReceiving()
+{
+ // The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet
+ // received and handled the interrupt for reading the packet/handling errors.
+ // FIXME: it would be better to check for preamble, but we currently have our ISR not set to fire for packets that
+ // never even get a valid header, so we don't want preamble to get set and stay set due to noise on the network.
+
+ uint16_t irq = lora.getIrqStatus();
+ bool hasPreamble = (irq & SX126X_IRQ_HEADER_VALID);
+
+ // this is not correct - often always true - need to add an extra conditional
+ // size_t bytesPending = lora.getPacketLength();
+
+ // if (hasPreamble) DEBUG_MSG("rx hasPreamble\n");
+ return hasPreamble;
+}
+
+bool SX1268Interface::sleep()
+{
+ // Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet
+ DEBUG_MSG("SX1268 entering sleep mode (FIXME, don't keep config)\n");
+ setStandby(); // Stop any pending operations
+
+ // turn off TCXO if it was powered
+ // FIXME - this isn't correct
+ // lora.setTCXO(0);
+
+ // put chipset into sleep mode (we've already disabled interrupts by now)
+ bool keepConfig = true;
+ lora.sleep(keepConfig); // Note: we do not keep the config, full reinit will be needed
+
+#ifdef SX1268_POWER_EN
+ digitalWrite(SX1268_POWER_EN, LOW);
+#endif
+
+ return true;
+}
\ No newline at end of file
diff --git a/src/mesh/SX1268Interface.h b/src/mesh/SX1268Interface.h
new file mode 100644
index 000000000..33f696c91
--- /dev/null
+++ b/src/mesh/SX1268Interface.h
@@ -0,0 +1,62 @@
+#pragma once
+
+#include "RadioLibInterface.h"
+
+/**
+ * Our adapter for SX1268 radios
+ */
+class SX1268Interface : public RadioLibInterface
+{
+ SX1268 lora;
+
+ public:
+ SX1268Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
+
+ /// Initialise the Driver transport hardware and software.
+ /// Make sure the Driver is properly configured before calling init().
+ /// \return true if initialisation succeeded.
+ virtual bool init();
+
+ /// Apply any radio provisioning changes
+ /// Make sure the Driver is properly configured before calling init().
+ /// \return true if initialisation succeeded.
+ virtual bool reconfigure();
+
+ /// 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
+ */
+ virtual void disableInterrupt();
+
+ /**
+ * Enable a particular ISR callback glue function
+ */
+ virtual void enableInterrupt(void (*callback)()) { lora.setDio1Action(callback); }
+
+ /** are we actively receiving a packet (only called during receiving state) */
+ virtual bool isActivelyReceiving();
+
+ /**
+ * Start waiting to receive a message
+ */
+ virtual void startReceive();
+
+ /**
+ * We override to turn on transmitter power as needed.
+ */
+ virtual void configHardwareForSend();
+
+ /**
+ * Add SNR data to received messages
+ */
+ virtual void addReceiveMetadata(MeshPacket *mp);
+
+ virtual void setStandby();
+
+ private:
+};
\ No newline at end of file
From 00bf7879af8516ecf835d708c1ef801675172e73 Mon Sep 17 00:00:00 2001
From: Vladislav Osmanov <7123463+osmanovv@users.noreply.github.com>
Date: Sun, 5 Sep 2021 00:46:38 +0300
Subject: [PATCH 02/10] SX1268 frequency initialization regardless of the
region
Otherwise, we get critical error 3 with result code -12 (ERR_INVALID_FREQUENCY):
The supplied frequency value is invalid for this module.
---
src/mesh/SX1268Interface.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/mesh/SX1268Interface.h b/src/mesh/SX1268Interface.h
index 33f696c91..0c43c163b 100644
--- a/src/mesh/SX1268Interface.h
+++ b/src/mesh/SX1268Interface.h
@@ -10,6 +10,9 @@ class SX1268Interface : public RadioLibInterface
SX1268 lora;
public:
+ /// Initializing the frequency of the SX1268 module regardless of the region
+ float freq = 433.0;
+
SX1268Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
/// Initialise the Driver transport hardware and software.
From c442fd3886cf29e1dbd098447736fe9aa94d266b Mon Sep 17 00:00:00 2001
From: a-f-G-U-C <65810997+a-f-G-U-C@users.noreply.github.com>
Date: Fri, 10 Sep 2021 15:12:12 +0000
Subject: [PATCH 03/10] input sanitization - TinyGPS course()
Reduce the impact of issue #863 (and similar issues in the future) by filtering out obvious bogons
---
src/gps/NMEAGPS.cpp | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/gps/NMEAGPS.cpp b/src/gps/NMEAGPS.cpp
index dcb24d617..c652fab63 100644
--- a/src/gps/NMEAGPS.cpp
+++ b/src/gps/NMEAGPS.cpp
@@ -163,7 +163,12 @@ bool NMEAGPS::lookForLocation()
}
if (reader.course.isUpdated() && reader.course.isValid()) {
- heading = reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5
+ if (reader.course.value() < 36000) { // sanity check
+ heading = reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5
+ } else {
+ DEBUG_MSG("BOGUS course.value() REJECTED: %d\n",
+ reader.course.value());
+ }
}
/*
From 098f38fb8319e311bc2c40e7324ae19325a81e63 Mon Sep 17 00:00:00 2001
From: Vladislav Osmanov <7123463+osmanovv@users.noreply.github.com>
Date: Sun, 12 Sep 2021 00:35:16 +0300
Subject: [PATCH 04/10] New base class for SX126x modules. Added new SX1268
module support.
---
src/configuration.h | 20 +-
src/main.cpp | 4 +-
src/mesh/InterfacesTemplates.cpp | 6 +
src/mesh/SX1262Interface.cpp | 250 +--------------------
src/mesh/SX1262Interface.h | 54 +----
src/mesh/SX1268Interface.cpp | 242 +-------------------
src/mesh/SX1268Interface.h | 54 +----
src/mesh/SX126xInterface.cpp | 269 +++++++++++++++++++++++
src/mesh/SX126xInterface.h | 68 ++++++
src/portduino/PortduinoGlue.cpp | 12 +-
variants/WisCore_RAK4631_Board/variant.h | 14 +-
variants/eink0.1/variant.h | 10 +-
variants/lora_isp4520/variant.h | 10 +-
variants/lora_relay_v1/variant.h | 16 +-
variants/lora_relay_v2/variant.h | 16 +-
variants/pca10056-rc-clock/variant.h | 8 +-
variants/ppr/variant.h | 14 +-
variants/ppr1/variant.h | 16 +-
variants/t-echo/variant.h | 12 +-
19 files changed, 425 insertions(+), 670 deletions(-)
create mode 100644 src/mesh/InterfacesTemplates.cpp
create mode 100644 src/mesh/SX126xInterface.cpp
create mode 100644 src/mesh/SX126xInterface.h
diff --git a/src/configuration.h b/src/configuration.h
index 2080e6e31..23eab0bf5 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -188,11 +188,11 @@ along with this program. If not, see .
#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
+#define SX126X_CS RF95_NSS // FIXME - we really should define LORA_CS instead
+#define SX126X_DIO1 LORA_DIO1
+#define SX126X_BUSY LORA_DIO2
+#define SX126X_RESET LORA_RESET
+#define SX126X_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
@@ -462,11 +462,11 @@ along with this program. If not, see .
#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
+#define SX126X_CS 20 // CS0 on pinelora schematic, hooked to gpio D0 on ch341f
+#define SX126X_DIO1 LORA_DIO1
+#define SX126X_BUSY LORA_DIO2
+#define SX126X_RESET LORA_RESET
+// HOPE RFM90 does not have a TCXO therefore not SX126X_E22
#endif
#endif
diff --git a/src/main.cpp b/src/main.cpp
index 273c7adc8..47fbc84eb 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -519,9 +519,9 @@ void setup()
}
#endif
-#if defined(SX1262_CS)
+#if defined(SX126X_CS)
if (!rIf) {
- rIf = new SX1262Interface(SX1262_CS, SX1262_DIO1, SX1262_RESET, SX1262_BUSY, SPI);
+ rIf = new SX1262Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI);
if (!rIf->init()) {
DEBUG_MSG("Warning: Failed to find SX1262 radio\n");
delete rIf;
diff --git a/src/mesh/InterfacesTemplates.cpp b/src/mesh/InterfacesTemplates.cpp
new file mode 100644
index 000000000..a50fbd6b8
--- /dev/null
+++ b/src/mesh/InterfacesTemplates.cpp
@@ -0,0 +1,6 @@
+#include "SX126xInterface.h"
+#include "SX126xInterface.cpp"
+
+// We need this declaration for proper linking in derived classes
+template class SX126xInterface;
+template class SX126xInterface;
\ No newline at end of file
diff --git a/src/mesh/SX1262Interface.cpp b/src/mesh/SX1262Interface.cpp
index 76d44625f..d01372802 100644
--- a/src/mesh/SX1262Interface.cpp
+++ b/src/mesh/SX1262Interface.cpp
@@ -2,256 +2,8 @@
#include "SX1262Interface.h"
#include "error.h"
-// Particular boards might define a different max power based on what their hardware can do
-#ifndef SX1262_MAX_POWER
-#define SX1262_MAX_POWER 22
-#endif
-
SX1262Interface::SX1262Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
SPIClass &spi)
- : RadioLibInterface(cs, irq, rst, busy, spi, &lora), lora(&module)
+ : SX126xInterface(cs, irq, rst, busy, spi)
{
-}
-
-/// Initialise the Driver transport hardware and software.
-/// Make sure the Driver is properly configured before calling init().
-/// \return true if initialisation succeeded.
-bool SX1262Interface::init()
-{
-#ifdef SX1262_POWER_EN
- digitalWrite(SX1262_POWER_EN, HIGH);
- pinMode(SX1262_POWER_EN, OUTPUT);
-#endif
-
-#ifdef SX1262_RXEN // set not rx or tx mode
- digitalWrite(SX1262_RXEN, LOW); // Set low before becoming an output
- pinMode(SX1262_RXEN, OUTPUT);
-#endif
-#ifdef SX1262_TXEN
- digitalWrite(SX1262_TXEN, LOW);
- pinMode(SX1262_TXEN, OUTPUT);
-#endif
-
-#ifndef SX1262_E22
- float tcxoVoltage = 0; // None - we use an XTAL
-#else
- // Use DIO3 to power tcxo per https://github.com/jgromes/RadioLib/issues/12#issuecomment-520695575
- float tcxoVoltage = 1.8;
-#endif
- bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC?
-
- RadioLibInterface::init();
-
- if (power == 0)
- power = SX1262_MAX_POWER;
-
- if (power > SX1262_MAX_POWER) // This chip has lower power limits than some
- power = SX1262_MAX_POWER;
-
- limitPower();
-
- int res = lora.begin(freq, bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage, useRegulatorLDO);
- DEBUG_MSG("SX1262 init result %d\n", res);
-
- // current limit was removed from module' ctor
- // override default value (60 mA)
- res = lora.setCurrentLimit(currentLimit);
- DEBUG_MSG("Current limit set to %f\n", currentLimit);
- DEBUG_MSG("Current limit set result %d\n", res);
-
-#ifdef SX1262_TXEN
- // lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX
- if (res == ERR_NONE)
- 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);
-
- if (res == ERR_NONE)
- startReceive(); // start receiving
-
- return res == ERR_NONE;
-}
-
-bool SX1262Interface::reconfigure()
-{
- RadioLibInterface::reconfigure();
-
- // set mode to standby
- setStandby();
-
- // configure publicly accessible settings
- int err = lora.setSpreadingFactor(sf);
- if (err != ERR_NONE)
- RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
-
- err = lora.setBandwidth(bw);
- if (err != ERR_NONE)
- RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
-
- err = lora.setCodingRate(cr);
- if (err != ERR_NONE)
- RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
-
- // Hmm - seems to lower SNR when the signal levels are high. Leaving off for now...
- err = lora.setRxGain(true);
- assert(err == ERR_NONE);
-
- err = lora.setSyncWord(syncWord);
- assert(err == ERR_NONE);
-
- err = lora.setCurrentLimit(currentLimit);
- assert(err == ERR_NONE);
-
- err = lora.setPreambleLength(preambleLength);
- assert(err == ERR_NONE);
-
- err = lora.setFrequency(freq);
- if (err != ERR_NONE)
- RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
-
- if (power > 22) // This chip has lower power limits than some
- power = 22;
- err = lora.setOutputPower(power);
- assert(err == ERR_NONE);
-
- startReceive(); // restart receiving
-
- return ERR_NONE;
-}
-
-void INTERRUPT_ATTR SX1262Interface::disableInterrupt()
-{
- lora.clearDio1Action();
-}
-
-void SX1262Interface::setStandby()
-{
- checkNotification(); // handle any pending interrupts before we force standby
-
- int err = lora.standby();
- assert(err == ERR_NONE);
-
-#ifdef SX1262_RXEN // we have RXEN/TXEN control - turn off RX and TX power
- digitalWrite(SX1262_RXEN, LOW);
-#endif
-#ifdef SX1262_TXEN
- digitalWrite(SX1262_TXEN, LOW);
-#endif
-
- isReceiving = false; // If we were receiving, not any more
- disableInterrupt();
- completeSending(); // If we were sending, not anymore
-}
-
-/**
- * Add SNR data to received messages
- */
-void SX1262Interface::addReceiveMetadata(MeshPacket *mp)
-{
- // DEBUG_MSG("PacketStatus %x\n", lora.getPacketStatus());
- mp->rx_snr = lora.getSNR();
- mp->rx_rssi = lround(lora.getRSSI());
-}
-
-/** We override to turn on transmitter power as needed.
- */
-void SX1262Interface::configHardwareForSend()
-{
-#ifdef SX1262_TXEN // we have RXEN/TXEN control - turn on TX power / off RX power
- digitalWrite(SX1262_TXEN, HIGH);
-#endif
-
- RadioLibInterface::configHardwareForSend();
-}
-
-// For power draw measurements, helpful to force radio to stay sleeping
-// #define SLEEP_ONLY
-
-void SX1262Interface::startReceive()
-{
-#ifdef SLEEP_ONLY
- sleep();
-#else
-
- setStandby();
-
-#ifdef SX1262_RXEN // we have RXEN/TXEN control - turn on RX power / off TX power
- digitalWrite(SX1262_RXEN, HIGH);
-#endif
-
- // int err = lora.startReceive();
- int err = lora.startReceiveDutyCycleAuto(); // We use a 32 bit preamble so this should save some power by letting radio sit in
- // standby mostly.
- assert(err == ERR_NONE);
-
- isReceiving = true;
-
- // Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register bits
- enableInterrupt(isrRxLevel0);
-#endif
-}
-
-/** Could we send right now (i.e. either not actively receving or transmitting)? */
-bool SX1262Interface::isActivelyReceiving()
-{
- // The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet
- // received and handled the interrupt for reading the packet/handling errors.
- // FIXME: it would be better to check for preamble, but we currently have our ISR not set to fire for packets that
- // never even get a valid header, so we don't want preamble to get set and stay set due to noise on the network.
-
- uint16_t irq = lora.getIrqStatus();
- bool hasPreamble = (irq & SX126X_IRQ_HEADER_VALID);
-
- // this is not correct - often always true - need to add an extra conditional
- // size_t bytesPending = lora.getPacketLength();
-
- // if (hasPreamble) DEBUG_MSG("rx hasPreamble\n");
- return hasPreamble;
-}
-
-bool SX1262Interface::sleep()
-{
- // Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet
- DEBUG_MSG("sx1262 entering sleep mode (FIXME, don't keep config)\n");
- setStandby(); // Stop any pending operations
-
- // turn off TCXO if it was powered
- // FIXME - this isn't correct
- // lora.setTCXO(0);
-
- // put chipset into sleep mode (we've already disabled interrupts by now)
- bool keepConfig = true;
- lora.sleep(keepConfig); // Note: we do not keep the config, full reinit will be needed
-
-#ifdef SX1262_POWER_EN
- digitalWrite(SX1262_POWER_EN, LOW);
-#endif
-
- return true;
}
\ No newline at end of file
diff --git a/src/mesh/SX1262Interface.h b/src/mesh/SX1262Interface.h
index 05a93a333..0f029ada9 100644
--- a/src/mesh/SX1262Interface.h
+++ b/src/mesh/SX1262Interface.h
@@ -1,62 +1,12 @@
#pragma once
-#include "RadioLibInterface.h"
+#include "SX126xInterface.h"
/**
* Our adapter for SX1262 radios
*/
-class SX1262Interface : public RadioLibInterface
+class SX1262Interface : public SX126xInterface
{
- SX1262 lora;
-
public:
SX1262Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
-
- /// Initialise the Driver transport hardware and software.
- /// Make sure the Driver is properly configured before calling init().
- /// \return true if initialisation succeeded.
- virtual bool init();
-
- /// Apply any radio provisioning changes
- /// Make sure the Driver is properly configured before calling init().
- /// \return true if initialisation succeeded.
- virtual bool reconfigure();
-
- /// 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
- */
- virtual void disableInterrupt();
-
- /**
- * Enable a particular ISR callback glue function
- */
- virtual void enableInterrupt(void (*callback)()) { lora.setDio1Action(callback); }
-
- /** are we actively receiving a packet (only called during receiving state) */
- virtual bool isActivelyReceiving();
-
- /**
- * Start waiting to receive a message
- */
- virtual void startReceive();
-
- /**
- * We override to turn on transmitter power as needed.
- */
- virtual void configHardwareForSend();
-
- /**
- * Add SNR data to received messages
- */
- virtual void addReceiveMetadata(MeshPacket *mp);
-
- virtual void setStandby();
-
- private:
};
\ No newline at end of file
diff --git a/src/mesh/SX1268Interface.cpp b/src/mesh/SX1268Interface.cpp
index 9d0df82c6..668943124 100644
--- a/src/mesh/SX1268Interface.cpp
+++ b/src/mesh/SX1268Interface.cpp
@@ -2,248 +2,8 @@
#include "SX1268Interface.h"
#include "error.h"
-// Particular boards might define a different max power based on what their hardware can do
-#ifndef SX1268_MAX_POWER
-#define SX1268_MAX_POWER 22
-#endif
-
SX1268Interface::SX1268Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
SPIClass &spi)
- : RadioLibInterface(cs, irq, rst, busy, spi, &lora), lora(&module)
+ : SX126xInterface(cs, irq, rst, busy, spi)
{
-}
-
-/// Initialise the Driver transport hardware and software.
-/// Make sure the Driver is properly configured before calling init().
-/// \return true if initialisation succeeded.
-bool SX1268Interface::init()
-{
-#ifdef SX1268_POWER_EN
- digitalWrite(SX1268_POWER_EN, HIGH);
- pinMode(SX1268_POWER_EN, OUTPUT);
-#endif
-
-#ifdef SX1268_RXEN // set not rx or tx mode
- digitalWrite(SX1268_RXEN, LOW); // Set low before becoming an output
- pinMode(SX1268_RXEN, OUTPUT);
-#endif
-#ifdef SX1268_TXEN
- digitalWrite(SX1268_TXEN, LOW);
- pinMode(SX1268_TXEN, OUTPUT);
-#endif
-
-#ifndef SX1268_E22
- float tcxoVoltage = 0; // None - we use an XTAL
-#else
- // Use DIO3 to power tcxo per https://github.com/jgromes/RadioLib/issues/12#issuecomment-520695575
- float tcxoVoltage = 1.8;
-#endif
- bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC?
-
- RadioLibInterface::init();
-
- if (power == 0)
- power = SX1268_MAX_POWER;
-
- if (power > SX1268_MAX_POWER) // This chip has lower power limits than some
- power = SX1268_MAX_POWER;
-
- limitPower();
-
- int res = lora.begin(freq, bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage, useRegulatorLDO);
- DEBUG_MSG("SX1268 init result %d\n", res);
-
-#ifdef SX1268_TXEN
- // lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX
- if (res == ERR_NONE)
- 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_SX1268Failure);
-
- //if(crcLSB != 0x0f)
- // RECORD_CRITICALERROR(CriticalErrorCode_SX1268Failure);
-
- crcLSB = 0x5a;
- err = lora.writeRegister(SX126X_REG_CRC_POLYNOMIAL_LSB, &crcLSB, 1);
- if(err != ERR_NONE)
- RECORD_CRITICALERROR(CriticalErrorCode_SX1268Failure);
-
- err = lora.readRegister(SX126X_REG_CRC_POLYNOMIAL_LSB, &crcLSB, 1);
- if(err != ERR_NONE)
- RECORD_CRITICALERROR(CriticalErrorCode_SX1268Failure);
-
- if(crcLSB != 0x5a)
- RECORD_CRITICALERROR(CriticalErrorCode_SX1268Failure);
- // 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);
-
- if (res == ERR_NONE)
- startReceive(); // start receiving
-
- return res == ERR_NONE;
-}
-
-bool SX1268Interface::reconfigure()
-{
- RadioLibInterface::reconfigure();
-
- // set mode to standby
- setStandby();
-
- // configure publicly accessible settings
- int err = lora.setSpreadingFactor(sf);
- if (err != ERR_NONE)
- RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
-
- err = lora.setBandwidth(bw);
- if (err != ERR_NONE)
- RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
-
- err = lora.setCodingRate(cr);
- if (err != ERR_NONE)
- RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
-
- // Hmm - seems to lower SNR when the signal levels are high. Leaving off for now...
- err = lora.setRxGain(true);
- assert(err == ERR_NONE);
-
- err = lora.setSyncWord(syncWord);
- assert(err == ERR_NONE);
-
- err = lora.setCurrentLimit(currentLimit);
- assert(err == ERR_NONE);
-
- err = lora.setPreambleLength(preambleLength);
- assert(err == ERR_NONE);
-
- err = lora.setFrequency(freq);
- if (err != ERR_NONE)
- RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
-
- if (power > 22) // This chip has lower power limits than some
- power = 22;
- err = lora.setOutputPower(power);
- assert(err == ERR_NONE);
-
- startReceive(); // restart receiving
-
- return ERR_NONE;
-}
-
-void INTERRUPT_ATTR SX1268Interface::disableInterrupt()
-{
- lora.clearDio1Action();
-}
-
-void SX1268Interface::setStandby()
-{
- int err = lora.standby();
- assert(err == ERR_NONE);
-
-#ifdef SX1268_RXEN // we have RXEN/TXEN control - turn off RX and TX power
- digitalWrite(SX1268_RXEN, LOW);
-#endif
-#ifdef SX1268_TXEN
- digitalWrite(SX1268_TXEN, LOW);
-#endif
-
- isReceiving = false; // If we were receiving, not any more
- disableInterrupt();
- completeSending(); // If we were sending, not anymore
-}
-
-/**
- * Add SNR data to received messages
- */
-void SX1268Interface::addReceiveMetadata(MeshPacket *mp)
-{
- // DEBUG_MSG("PacketStatus %x\n", lora.getPacketStatus());
- mp->rx_snr = lora.getSNR();
- mp->rx_rssi = lround(lora.getRSSI());
-}
-
-/** We override to turn on transmitter power as needed.
- */
-void SX1268Interface::configHardwareForSend()
-{
-#ifdef SX1268_TXEN // we have RXEN/TXEN control - turn on TX power / off RX power
- digitalWrite(SX1268_TXEN, HIGH);
-#endif
-
- RadioLibInterface::configHardwareForSend();
-}
-
-// For power draw measurements, helpful to force radio to stay sleeping
-// #define SLEEP_ONLY
-
-void SX1268Interface::startReceive()
-{
-#ifdef SLEEP_ONLY
- sleep();
-#else
-
- setStandby();
-
-#ifdef SX1268_RXEN // we have RXEN/TXEN control - turn on RX power / off TX power
- digitalWrite(SX1268_RXEN, HIGH);
-#endif
-
- // int err = lora.startReceive();
- int err = lora.startReceiveDutyCycleAuto(); // We use a 32 bit preamble so this should save some power by letting radio sit in
- // standby mostly.
- assert(err == ERR_NONE);
-
- isReceiving = true;
-
- // Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register bits
- enableInterrupt(isrRxLevel0);
-#endif
-}
-
-/** Could we send right now (i.e. either not actively receving or transmitting)? */
-bool SX1268Interface::isActivelyReceiving()
-{
- // The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet
- // received and handled the interrupt for reading the packet/handling errors.
- // FIXME: it would be better to check for preamble, but we currently have our ISR not set to fire for packets that
- // never even get a valid header, so we don't want preamble to get set and stay set due to noise on the network.
-
- uint16_t irq = lora.getIrqStatus();
- bool hasPreamble = (irq & SX126X_IRQ_HEADER_VALID);
-
- // this is not correct - often always true - need to add an extra conditional
- // size_t bytesPending = lora.getPacketLength();
-
- // if (hasPreamble) DEBUG_MSG("rx hasPreamble\n");
- return hasPreamble;
-}
-
-bool SX1268Interface::sleep()
-{
- // Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet
- DEBUG_MSG("SX1268 entering sleep mode (FIXME, don't keep config)\n");
- setStandby(); // Stop any pending operations
-
- // turn off TCXO if it was powered
- // FIXME - this isn't correct
- // lora.setTCXO(0);
-
- // put chipset into sleep mode (we've already disabled interrupts by now)
- bool keepConfig = true;
- lora.sleep(keepConfig); // Note: we do not keep the config, full reinit will be needed
-
-#ifdef SX1268_POWER_EN
- digitalWrite(SX1268_POWER_EN, LOW);
-#endif
-
- return true;
}
\ No newline at end of file
diff --git a/src/mesh/SX1268Interface.h b/src/mesh/SX1268Interface.h
index 0c43c163b..c4c98da0a 100644
--- a/src/mesh/SX1268Interface.h
+++ b/src/mesh/SX1268Interface.h
@@ -1,65 +1,15 @@
#pragma once
-#include "RadioLibInterface.h"
+#include "SX126xInterface.h"
/**
* Our adapter for SX1268 radios
*/
-class SX1268Interface : public RadioLibInterface
+class SX1268Interface : public SX126xInterface
{
- SX1268 lora;
-
public:
/// Initializing the frequency of the SX1268 module regardless of the region
float freq = 433.0;
SX1268Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
-
- /// Initialise the Driver transport hardware and software.
- /// Make sure the Driver is properly configured before calling init().
- /// \return true if initialisation succeeded.
- virtual bool init();
-
- /// Apply any radio provisioning changes
- /// Make sure the Driver is properly configured before calling init().
- /// \return true if initialisation succeeded.
- virtual bool reconfigure();
-
- /// 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
- */
- virtual void disableInterrupt();
-
- /**
- * Enable a particular ISR callback glue function
- */
- virtual void enableInterrupt(void (*callback)()) { lora.setDio1Action(callback); }
-
- /** are we actively receiving a packet (only called during receiving state) */
- virtual bool isActivelyReceiving();
-
- /**
- * Start waiting to receive a message
- */
- virtual void startReceive();
-
- /**
- * We override to turn on transmitter power as needed.
- */
- virtual void configHardwareForSend();
-
- /**
- * Add SNR data to received messages
- */
- virtual void addReceiveMetadata(MeshPacket *mp);
-
- virtual void setStandby();
-
- private:
};
\ No newline at end of file
diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp
new file mode 100644
index 000000000..d4deef0f1
--- /dev/null
+++ b/src/mesh/SX126xInterface.cpp
@@ -0,0 +1,269 @@
+#include "configuration.h"
+#include "SX126xInterface.h"
+#include "error.h"
+
+// Particular boards might define a different max power based on what their hardware can do
+#ifndef SX126X_MAX_POWER
+#define SX126X_MAX_POWER 22
+#endif
+
+template
+SX126xInterface::SX126xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
+ SPIClass &spi)
+ : RadioLibInterface(cs, irq, rst, busy, spi, &lora), lora(&module)
+{
+}
+
+/// Initialise the Driver transport hardware and software.
+/// Make sure the Driver is properly configured before calling init().
+/// \return true if initialisation succeeded.
+template
+bool SX126xInterface::init()
+{
+#ifdef SX126X_POWER_EN
+ digitalWrite(SX126X_POWER_EN, HIGH);
+ pinMode(SX126X_POWER_EN, OUTPUT);
+#endif
+
+#ifdef SX126X_RXEN // set not rx or tx mode
+ digitalWrite(SX126X_RXEN, LOW); // Set low before becoming an output
+ pinMode(SX126X_RXEN, OUTPUT);
+#endif
+#ifdef SX126X_TXEN
+ digitalWrite(SX126X_TXEN, LOW);
+ pinMode(SX126X_TXEN, OUTPUT);
+#endif
+
+#ifndef SX126X_E22
+ float tcxoVoltage = 0; // None - we use an XTAL
+#else
+ // Use DIO3 to power tcxo per https://github.com/jgromes/RadioLib/issues/12#issuecomment-520695575
+ float tcxoVoltage = 1.8;
+#endif
+ bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC?
+
+ RadioLibInterface::init();
+
+ if (power == 0)
+ power = SX126X_MAX_POWER;
+
+ if (power > SX126X_MAX_POWER) // This chip has lower power limits than some
+ power = SX126X_MAX_POWER;
+
+ limitPower();
+
+ int res = lora.begin(freq, bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage, useRegulatorLDO);
+ // \todo Display actual typename of the adapter, not just `SX126x`
+ DEBUG_MSG("SX126x init result %d\n", res);
+
+ // current limit was removed from module' ctor
+ // override default value (60 mA)
+ res = lora.setCurrentLimit(currentLimit);
+ DEBUG_MSG("Current limit set to %f\n", currentLimit);
+ DEBUG_MSG("Current limit set result %d\n", res);
+
+#ifdef SX126X_TXEN
+ // lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX
+ if (res == ERR_NONE)
+ 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);
+
+ if (res == ERR_NONE)
+ startReceive(); // start receiving
+
+ return res == ERR_NONE;
+}
+
+template
+bool SX126xInterface::reconfigure()
+{
+ RadioLibInterface::reconfigure();
+
+ // set mode to standby
+ setStandby();
+
+ // configure publicly accessible settings
+ int err = lora.setSpreadingFactor(sf);
+ if (err != ERR_NONE)
+ RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
+
+ err = lora.setBandwidth(bw);
+ if (err != ERR_NONE)
+ RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
+
+ err = lora.setCodingRate(cr);
+ if (err != ERR_NONE)
+ RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
+
+ // Hmm - seems to lower SNR when the signal levels are high. Leaving off for now...
+ err = lora.setRxGain(true);
+ assert(err == ERR_NONE);
+
+ err = lora.setSyncWord(syncWord);
+ assert(err == ERR_NONE);
+
+ err = lora.setCurrentLimit(currentLimit);
+ assert(err == ERR_NONE);
+
+ err = lora.setPreambleLength(preambleLength);
+ assert(err == ERR_NONE);
+
+ err = lora.setFrequency(freq);
+ if (err != ERR_NONE)
+ RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
+
+ if (power > 22) // This chip has lower power limits than some
+ power = 22;
+ err = lora.setOutputPower(power);
+ assert(err == ERR_NONE);
+
+ startReceive(); // restart receiving
+
+ return ERR_NONE;
+}
+
+template
+void INTERRUPT_ATTR SX126xInterface::disableInterrupt()
+{
+ lora.clearDio1Action();
+}
+
+template
+void SX126xInterface::setStandby()
+{
+ checkNotification(); // handle any pending interrupts before we force standby
+
+ int err = lora.standby();
+ assert(err == ERR_NONE);
+
+#ifdef SX126X_RXEN // we have RXEN/TXEN control - turn off RX and TX power
+ digitalWrite(SX126X_RXEN, LOW);
+#endif
+#ifdef SX126X_TXEN
+ digitalWrite(SX126X_TXEN, LOW);
+#endif
+
+ isReceiving = false; // If we were receiving, not any more
+ disableInterrupt();
+ completeSending(); // If we were sending, not anymore
+}
+
+/**
+ * Add SNR data to received messages
+ */
+template
+void SX126xInterface::addReceiveMetadata(MeshPacket *mp)
+{
+ // DEBUG_MSG("PacketStatus %x\n", lora.getPacketStatus());
+ mp->rx_snr = lora.getSNR();
+ mp->rx_rssi = lround(lora.getRSSI());
+}
+
+/** We override to turn on transmitter power as needed.
+ */
+template
+void SX126xInterface::configHardwareForSend()
+{
+#ifdef SX126X_TXEN // we have RXEN/TXEN control - turn on TX power / off RX power
+ digitalWrite(SX126X_TXEN, HIGH);
+#endif
+
+ RadioLibInterface::configHardwareForSend();
+}
+
+// For power draw measurements, helpful to force radio to stay sleeping
+// #define SLEEP_ONLY
+
+template
+void SX126xInterface::startReceive()
+{
+#ifdef SLEEP_ONLY
+ sleep();
+#else
+
+ setStandby();
+
+#ifdef SX126X_RXEN // we have RXEN/TXEN control - turn on RX power / off TX power
+ digitalWrite(SX126X_RXEN, HIGH);
+#endif
+
+ // int err = lora.startReceive();
+ int err = lora.startReceiveDutyCycleAuto(); // We use a 32 bit preamble so this should save some power by letting radio sit in
+ // standby mostly.
+ assert(err == ERR_NONE);
+
+ isReceiving = true;
+
+ // Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register bits
+ enableInterrupt(isrRxLevel0);
+#endif
+}
+
+/** Could we send right now (i.e. either not actively receving or transmitting)? */
+template
+bool SX126xInterface::isActivelyReceiving()
+{
+ // The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet
+ // received and handled the interrupt for reading the packet/handling errors.
+ // FIXME: it would be better to check for preamble, but we currently have our ISR not set to fire for packets that
+ // never even get a valid header, so we don't want preamble to get set and stay set due to noise on the network.
+
+ uint16_t irq = lora.getIrqStatus();
+ bool hasPreamble = (irq & SX126X_IRQ_HEADER_VALID);
+
+ // this is not correct - often always true - need to add an extra conditional
+ // size_t bytesPending = lora.getPacketLength();
+
+ // if (hasPreamble) DEBUG_MSG("rx hasPreamble\n");
+ return hasPreamble;
+}
+
+template
+bool SX126xInterface::sleep()
+{
+ // Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet
+ // \todo Display actual typename of the adapter, not just `SX126x`
+ DEBUG_MSG("sx126x entering sleep mode (FIXME, don't keep config)\n");
+ setStandby(); // Stop any pending operations
+
+ // turn off TCXO if it was powered
+ // FIXME - this isn't correct
+ // lora.setTCXO(0);
+
+ // put chipset into sleep mode (we've already disabled interrupts by now)
+ bool keepConfig = true;
+ lora.sleep(keepConfig); // Note: we do not keep the config, full reinit will be needed
+
+#ifdef SX126X_POWER_EN
+ digitalWrite(SX126X_POWER_EN, LOW);
+#endif
+
+ return true;
+}
\ No newline at end of file
diff --git a/src/mesh/SX126xInterface.h b/src/mesh/SX126xInterface.h
new file mode 100644
index 000000000..1b4a10048
--- /dev/null
+++ b/src/mesh/SX126xInterface.h
@@ -0,0 +1,68 @@
+#pragma once
+
+#include "RadioLibInterface.h"
+
+/**
+ * \brief Adapter for SX126x radio family. Implements common logic for child classes.
+ * \tparam T RadioLib module type for SX126x: SX1262, SX1268.
+ */
+template
+class SX126xInterface : public RadioLibInterface
+{
+ public:
+ SX126xInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
+
+ /// Initialise the Driver transport hardware and software.
+ /// Make sure the Driver is properly configured before calling init().
+ /// \return true if initialisation succeeded.
+ virtual bool init();
+
+ /// Apply any radio provisioning changes
+ /// Make sure the Driver is properly configured before calling init().
+ /// \return true if initialisation succeeded.
+ virtual bool reconfigure();
+
+ /// 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:
+
+ /**
+ * Specific module instance
+ */
+ T lora;
+
+ /**
+ * Glue functions called from ISR land
+ */
+ virtual void disableInterrupt();
+
+ /**
+ * Enable a particular ISR callback glue function
+ */
+ virtual void enableInterrupt(void (*callback)()) { lora.setDio1Action(callback); }
+
+ /** are we actively receiving a packet (only called during receiving state) */
+ virtual bool isActivelyReceiving();
+
+ /**
+ * Start waiting to receive a message
+ */
+ virtual void startReceive();
+
+ /**
+ * We override to turn on transmitter power as needed.
+ */
+ virtual void configHardwareForSend();
+
+ /**
+ * Add SNR data to received messages
+ */
+ virtual void addReceiveMetadata(MeshPacket *mp);
+
+ virtual void setStandby();
+
+ private:
+};
\ No newline at end of file
diff --git a/src/portduino/PortduinoGlue.cpp b/src/portduino/PortduinoGlue.cpp
index d2caf695c..46abd6b85 100644
--- a/src/portduino/PortduinoGlue.cpp
+++ b/src/portduino/PortduinoGlue.cpp
@@ -72,13 +72,13 @@ void portduinoSetup()
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");
+ auto busy = new LinuxGPIOPin(SX126X_BUSY, "ch341", "slct", "loraBusy");
busy->setSilent();
gpioBind(busy);
- gpioBind(new LinuxGPIOPin(SX1262_RESET, "ch341", "ini", "loraReset"));
+ gpioBind(new LinuxGPIOPin(SX126X_RESET, "ch341", "ini", "loraReset"));
- auto loraCs = new LinuxGPIOPin(SX1262_CS, "ch341", "cs0", "loraCs");
+ auto loraCs = new LinuxGPIOPin(SX126X_CS, "ch341", "cs0", "loraCs");
loraCs->setSilent();
gpioBind(loraCs);
}
@@ -86,16 +86,16 @@ void portduinoSetup()
#endif
{
- auto fakeBusy = new SimGPIOPin(SX1262_BUSY, "fakeBusy");
+ auto fakeBusy = new SimGPIOPin(SX126X_BUSY, "fakeBusy");
fakeBusy->writePin(LOW);
fakeBusy->setSilent(true);
gpioBind(fakeBusy);
- auto cs = new SimGPIOPin(SX1262_CS, "fakeLoraCS");
+ auto cs = new SimGPIOPin(SX126X_CS, "fakeLoraCS");
cs->setSilent(true);
gpioBind(cs);
- gpioBind(new SimGPIOPin(SX1262_RESET, "fakeLoraReset"));
+ gpioBind(new SimGPIOPin(SX126X_RESET, "fakeLoraReset"));
gpioBind(new SimGPIOPin(LORA_DIO1, "fakeLoraIrq"));
}
diff --git a/variants/WisCore_RAK4631_Board/variant.h b/variants/WisCore_RAK4631_Board/variant.h
index e9e28dc19..8598dc1be 100644
--- a/variants/WisCore_RAK4631_Board/variant.h
+++ b/variants/WisCore_RAK4631_Board/variant.h
@@ -151,13 +151,13 @@ static const uint8_t SCK = PIN_SPI_SCK;
*/
// RAK4630 LoRa module
-#define SX1262_CS (42)
-#define SX1262_DIO1 (47)
-#define SX1262_BUSY (46)
-#define SX1262_RESET (38)
-#define SX1262_TXEN (39)
-#define SX1262_RXEN (37)
-#define SX1262_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
+#define SX126X_CS (42)
+#define SX126X_DIO1 (47)
+#define SX126X_BUSY (46)
+#define SX126X_RESET (38)
+#define SX126X_TXEN (39)
+#define SX126X_RXEN (37)
+#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
// RAK1910 GPS module
// If using the wisblock GPS module and pluged into Port A on WisBlock base
diff --git a/variants/eink0.1/variant.h b/variants/eink0.1/variant.h
index 1b30ca21c..d07597a21 100644
--- a/variants/eink0.1/variant.h
+++ b/variants/eink0.1/variant.h
@@ -178,15 +178,15 @@ External serial flash WP25R1635FZUIL0
* Lora radio
*/
-#define SX1262_CS (0 + 24) // FIXME - we really should define LORA_CS instead
-#define SX1262_DIO1 (0 + 20)
+#define SX126X_CS (0 + 24) // FIXME - we really should define LORA_CS instead
+#define SX126X_DIO1 (0 + 20)
// Note DIO2 is attached internally to the module to an analog switch for TX/RX switching
#define SX1262_DIO3 \
(0 + 21) // This is used as an *output* from the sx1262 and connected internally to power the tcxo, do not drive from the main
// CPU?
-#define SX1262_BUSY (0 + 17)
-#define SX1262_RESET (0 + 25)
-#define SX1262_E22 // Not really an E22 but TTGO seems to be trying to clone that
+#define SX126X_BUSY (0 + 17)
+#define SX126X_RESET (0 + 25)
+#define SX126X_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)
diff --git a/variants/lora_isp4520/variant.h b/variants/lora_isp4520/variant.h
index 9bf5cd502..d23a20a0e 100644
--- a/variants/lora_isp4520/variant.h
+++ b/variants/lora_isp4520/variant.h
@@ -57,10 +57,10 @@
#define WIRE_INTERFACES_COUNT 0
// GPIOs the SX1262 is connected
-#define SX1262_CS 1 // aka SPI_NSS
-#define SX1262_DIO1 (4)
-#define SX1262_BUSY (5)
-#define SX1262_RESET (6)
+#define SX126X_CS 1 // aka SPI_NSS
+#define SX126X_DIO1 (4)
+#define SX126X_BUSY (5)
+#define SX126X_RESET (6)
/*
* Serial interfaces
@@ -91,7 +91,7 @@
#define BATTERY_PIN 3
#define ADC_MULTIPLIER 1.436
-#define SX1262_E22 // Not really an E22 but this board clones using DIO3 for tcxo control
+#define SX126X_E22 // Not really an E22 but this board clones using DIO3 for tcxo control
#define NO_WIRE
#define NO_GPS
diff --git a/variants/lora_relay_v1/variant.h b/variants/lora_relay_v1/variant.h
index f7ade9586..59a52f44a 100644
--- a/variants/lora_relay_v1/variant.h
+++ b/variants/lora_relay_v1/variant.h
@@ -117,21 +117,21 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define I2C_ADDR_BQ27441 0x55 // Battery gauge
// CUSTOM GPIOs the SX1262
-#define SX1262_CS (32)
+#define SX126X_CS (32)
// If you would prefer to get console debug output over the JTAG ICE connection rather than the CDC-ACM USB serial device, just
// define this. #define USE_SEGGER
-#define SX1262_DIO1 (29)
+#define SX126X_DIO1 (29)
#define SX1262_DIO2 (30)
-#define SX1262_BUSY (33) // Supposed to be P0.18 but because of reworks, now on P0.31 (18)
-#define SX1262_RESET (34)
+#define SX126X_BUSY (33) // Supposed to be P0.18 but because of reworks, now on P0.31 (18)
+#define SX126X_RESET (34)
// #define SX1262_ANT_SW (32 + 10)
-#define SX1262_RXEN (14)
-#define SX1262_TXEN (31)
-#define SX1262_POWER_EN \
+#define SX126X_RXEN (14)
+#define SX126X_TXEN (31)
+#define SX126X_POWER_EN \
(15) // FIXME, see warning hre https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay/blob/master/LORA_RELAY_NRF52840.ino
-#define SX1262_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that
+#define SX126X_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that
#define ST7735_RESET (11) // Output
#define ST7735_CS (12)
diff --git a/variants/lora_relay_v2/variant.h b/variants/lora_relay_v2/variant.h
index 6814fdb3c..04a436739 100644
--- a/variants/lora_relay_v2/variant.h
+++ b/variants/lora_relay_v2/variant.h
@@ -137,21 +137,21 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define I2C_ADDR_BQ27441 0x55 // Battery gauge
// CUSTOM GPIOs the SX1262
-#define SX1262_CS (32)
+#define SX126X_CS (32)
// If you would prefer to get console debug output over the JTAG ICE connection rather than the CDC-ACM USB serial device, just
// define this. #define USE_SEGGER
-#define SX1262_DIO1 (29)
+#define SX126X_DIO1 (29)
#define SX1262_DIO2 (30)
-#define SX1262_BUSY (33) // Supposed to be P0.18 but because of reworks, now on P0.31 (18)
-#define SX1262_RESET (34)
+#define SX126X_BUSY (33) // Supposed to be P0.18 but because of reworks, now on P0.31 (18)
+#define SX126X_RESET (34)
// #define SX1262_ANT_SW (32 + 10)
-#define SX1262_RXEN (14)
-#define SX1262_TXEN (31)
-#define SX1262_POWER_EN \
+#define SX126X_RXEN (14)
+#define SX126X_TXEN (31)
+#define SX126X_POWER_EN \
(15) // FIXME, see warning hre https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay/blob/master/LORA_RELAY_NRF52840.ino
-#define SX1262_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that
+#define SX126X_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that
// ST7565 SPI
#define ST7735_RESET (11) // Output
diff --git a/variants/pca10056-rc-clock/variant.h b/variants/pca10056-rc-clock/variant.h
index 9d35325c8..185faead8 100644
--- a/variants/pca10056-rc-clock/variant.h
+++ b/variants/pca10056-rc-clock/variant.h
@@ -140,10 +140,10 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define EXTERNAL_FLASH_USE_QSPI
// CUSTOM GPIOs the SX1262MB2CAS shield when installed on the NRF52840-DK development board
-#define SX1262_CS (32 + 8) // P1.08
-#define SX1262_DIO1 (32 + 6) // P1.06
-#define SX1262_BUSY (32 + 4) // P1.04
-#define SX1262_RESET (0 + 3) // P0.03
+#define SX126X_CS (32 + 8) // P1.08
+#define SX126X_DIO1 (32 + 6) // P1.06
+#define SX126X_BUSY (32 + 4) // P1.04
+#define SX126X_RESET (0 + 3) // P0.03
#define SX1262_ANT_SW (32 + 10) // P1.10
// To debug via the segger JLINK console rather than the CDC-ACM serial device
diff --git a/variants/ppr/variant.h b/variants/ppr/variant.h
index bbdda3065..d2a72f879 100644
--- a/variants/ppr/variant.h
+++ b/variants/ppr/variant.h
@@ -129,15 +129,15 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define PIN_WIRE_SCL (32)
// CUSTOM GPIOs the SX1262
-#define SX1262_CS (10)
-#define SX1262_DIO1 (20)
+#define SX126X_CS (10)
+#define SX126X_DIO1 (20)
#define SX1262_DIO2 (26)
-#define SX1262_BUSY (31) // Supposed to be P0.18 but because of reworks, now on P0.31 (18)
-#define SX1262_RESET (17)
+#define SX126X_BUSY (31) // Supposed to be P0.18 but because of reworks, now on P0.31 (18)
+#define SX126X_RESET (17)
// #define SX1262_ANT_SW (32 + 10)
-#define SX1262_RXEN (22)
-#define SX1262_TXEN (24)
-#define SX1262_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that
+#define SX126X_RXEN (22)
+#define SX126X_TXEN (24)
+#define SX126X_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that
// ERC12864-10 LCD
#define ERC12864_CS (32 + 4)
diff --git a/variants/ppr1/variant.h b/variants/ppr1/variant.h
index 04a6e3c06..b5d398c36 100644
--- a/variants/ppr1/variant.h
+++ b/variants/ppr1/variant.h
@@ -152,18 +152,18 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define PIN_WIRE_SCL (32)
// CUSTOM GPIOs the SX1262
-#define SX1262_CS (0 + 10) // FIXME - we really should define LORA_CS instead
-#define SX1262_DIO1 (0 + 20)
+#define SX126X_CS (0 + 10) // FIXME - we really should define LORA_CS instead
+#define SX126X_DIO1 (0 + 20)
#define SX1262_DIO2 (0 + 26)
-#define SX1262_BUSY (0 + 19)
-#define SX1262_RESET (0 + 17)
-#define SX1262_TXEN (0 + 24)
-#define SX1262_RXEN (0 + 22)
-#define SX1262_E22 // Not really an E22 but this board clones using DIO3 for tcxo control
+#define SX126X_BUSY (0 + 19)
+#define SX126X_RESET (0 + 17)
+#define SX126X_TXEN (0 + 24)
+#define SX126X_RXEN (0 + 22)
+#define SX126X_E22 // Not really an E22 but this board clones using DIO3 for tcxo control
// FIXME, to prevent burning out parts I've set the power level super low, because I don't have
// an antenna wired up
-#define SX1262_MAX_POWER 1
+#define SX126X_MAX_POWER 1
#define LORA_DISABLE_SENDING // Define this to disable transmission for testing (power testing etc...)
diff --git a/variants/t-echo/variant.h b/variants/t-echo/variant.h
index 400218912..beb9e5506 100644
--- a/variants/t-echo/variant.h
+++ b/variants/t-echo/variant.h
@@ -180,21 +180,21 @@ External serial flash WP25R1635FZUIL0
* Lora radio
*/
-#define SX1262_CS (0 + 24) // FIXME - we really should define LORA_CS instead
-#define SX1262_DIO1 (0 + 20)
+#define SX126X_CS (0 + 24) // FIXME - we really should define LORA_CS instead
+#define SX126X_DIO1 (0 + 20)
// Note DIO2 is attached internally to the module to an analog switch for TX/RX switching
#define SX1262_DIO3 \
(0 + 21) // This is used as an *output* from the sx1262 and connected internally to power the tcxo, do not drive from the main
// CPU?
-#define SX1262_BUSY (0 + 17)
-#define SX1262_RESET (0 + 25)
-#define SX1262_E22 // Not really an E22 but TTGO seems to be trying to clone that
+#define SX126X_BUSY (0 + 17)
+#define SX126X_RESET (0 + 25)
+#define SX126X_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)
// #define LORA_DISABLE_SENDING // Define this to disable transmission for testing (power testing etc...)
-// #undef SX1262_CS
+// #undef SX126X_CS
// #define USE_SIM_RADIO // define to not use the lora radio hardware at all
/*
From da61090dc53cf200e2a13bb66e1485045f0a5c92 Mon Sep 17 00:00:00 2001
From: Vladislav Osmanov <7123463+osmanovv@users.noreply.github.com>
Date: Sun, 12 Sep 2021 13:58:56 +0300
Subject: [PATCH 05/10] fix: need to check `USE_SX1262` and `USE_SX1268` as
they are using the same pinouts
---
src/main.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/main.cpp b/src/main.cpp
index 47fbc84eb..e494f9f20 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -519,7 +519,7 @@ void setup()
}
#endif
-#if defined(SX126X_CS)
+#if defined(USE_SX1262)
if (!rIf) {
rIf = new SX1262Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI);
if (!rIf->init()) {
@@ -532,9 +532,9 @@ void setup()
}
#endif
-#if defined(SX1268_CS)
+#if defined(USE_SX1268)
if (!rIf) {
- rIf = new SX1268Interface(SX1268_CS, SX1268_DIO1, SX1268_RESET, SX1268_BUSY, SPI);
+ rIf = new SX1268Interface(SX126X_CS, SX126X_DIO1, SX126X_RESET, SX126X_BUSY, SPI);
if (!rIf->init()) {
DEBUG_MSG("Warning: Failed to find SX1268 radio\n");
delete rIf;
From cb42440963bd4c443eebbca3e3d28d99699e19d7 Mon Sep 17 00:00:00 2001
From: Vladislav Osmanov <7123463+osmanovv@users.noreply.github.com>
Date: Mon, 13 Sep 2021 22:13:51 +0300
Subject: [PATCH 06/10] fix module frequency overriding
The `RadioInterface::freq` member was encapsulated with the `RadioInterface::getFreq()` function,
which could be overridden in child classes for some LoRa-modules.
---
src/mesh/RF95Interface.cpp | 4 ++--
src/mesh/RadioInterface.cpp | 4 ++--
src/mesh/RadioInterface.h | 4 +---
src/mesh/SX1268Interface.h | 4 ++--
src/mesh/SX126xInterface.cpp | 4 ++--
5 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/src/mesh/RF95Interface.cpp b/src/mesh/RF95Interface.cpp
index 8b7d9f112..5a1cce32a 100644
--- a/src/mesh/RF95Interface.cpp
+++ b/src/mesh/RF95Interface.cpp
@@ -67,7 +67,7 @@ bool RF95Interface::init()
#endif
setTransmitEnable(false);
- int res = lora->begin(freq, bw, sf, cr, syncWord, power, currentLimit, preambleLength);
+ int res = lora->begin(getFreq(), bw, sf, cr, syncWord, power, currentLimit, preambleLength);
DEBUG_MSG("RF95 init result %d\n", res);
// current limit was removed from module' ctor
@@ -119,7 +119,7 @@ bool RF95Interface::reconfigure()
err = lora->setPreambleLength(preambleLength);
assert(err == ERR_NONE);
- err = lora->setFrequency(freq);
+ err = lora->setFrequency(getFreq());
if (err != ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp
index 7551473c8..4bd352559 100644
--- a/src/mesh/RadioInterface.cpp
+++ b/src/mesh/RadioInterface.cpp
@@ -318,14 +318,14 @@ void RadioInterface::applyModemConfig()
// If user has manually specified a channel num, then use that, otherwise generate one by hashing the name
const char *channelName = channels.getName(channels.getPrimaryIndex());
int channel_num = channelSettings.channel_num ? channelSettings.channel_num - 1 : hash(channelName) % myRegion->numChannels;
- freq = myRegion->freq + radioConfig.preferences.frequency_offset + myRegion->spacing * channel_num;
+ float freq = myRegion->freq + radioConfig.preferences.frequency_offset + myRegion->spacing * channel_num;
DEBUG_MSG("Set radio: name=%s, config=%u, ch=%d, power=%d\n", channelName, channelSettings.modem_config, channel_num, power);
DEBUG_MSG("Radio myRegion->freq: %f\n", myRegion->freq);
DEBUG_MSG("Radio myRegion->spacing: %f\n", myRegion->spacing);
DEBUG_MSG("Radio myRegion->numChannels: %d\n", myRegion->numChannels);
DEBUG_MSG("Radio channel_num: %d\n", channel_num);
- DEBUG_MSG("Radio frequency: %f\n", freq);
+ DEBUG_MSG("Radio frequency: %f\n", getFreq()); // the frequency could be overridden in RadioInterface::getFreq() for some modules
DEBUG_MSG("Short packet time: %u msec\n", shortPacketMsec);
saveChannelNum(channel_num);
diff --git a/src/mesh/RadioInterface.h b/src/mesh/RadioInterface.h
index c0d7ec2d1..542b575da 100644
--- a/src/mesh/RadioInterface.h
+++ b/src/mesh/RadioInterface.h
@@ -78,8 +78,6 @@ class RadioInterface
void deliverToReceiver(MeshPacket *p);
public:
- float freq = 915.0;
-
/** pool is the pool we will alloc our rx packets from
*/
RadioInterface();
@@ -149,7 +147,7 @@ class RadioInterface
/**
* Get the frequency we saved.
*/
- float getFreq();
+ virtual 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; }
diff --git a/src/mesh/SX1268Interface.h b/src/mesh/SX1268Interface.h
index c4c98da0a..fb2239041 100644
--- a/src/mesh/SX1268Interface.h
+++ b/src/mesh/SX1268Interface.h
@@ -8,8 +8,8 @@
class SX1268Interface : public SX126xInterface
{
public:
- /// Initializing the frequency of the SX1268 module regardless of the region
- float freq = 433.0;
+ /// override frequency of the SX1268 module regardless of the region
+ virtual float getFreq() { return 433.0; }
SX1268Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
};
\ No newline at end of file
diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp
index d4deef0f1..b0c48d55a 100644
--- a/src/mesh/SX126xInterface.cpp
+++ b/src/mesh/SX126xInterface.cpp
@@ -52,7 +52,7 @@ bool SX126xInterface::init()
limitPower();
- int res = lora.begin(freq, bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage, useRegulatorLDO);
+ int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage, useRegulatorLDO);
// \todo Display actual typename of the adapter, not just `SX126x`
DEBUG_MSG("SX126x init result %d\n", res);
@@ -135,7 +135,7 @@ bool SX126xInterface::reconfigure()
err = lora.setPreambleLength(preambleLength);
assert(err == ERR_NONE);
- err = lora.setFrequency(freq);
+ err = lora.setFrequency(getFreq());
if (err != ERR_NONE)
RECORD_CRITICALERROR(CriticalErrorCode_InvalidRadioSetting);
From 56dd3eab23ae26e867b415c01fa1f3a69346315b Mon Sep 17 00:00:00 2001
From: Vladislav Osmanov <7123463+osmanovv@users.noreply.github.com>
Date: Tue, 14 Sep 2021 12:25:25 +0300
Subject: [PATCH 07/10] use common param name `SX126X_ANT_SW` instead of the
`SX1262_ANT_SW`
---
src/main.cpp | 14 ++++----------
variants/lora_relay_v1/variant.h | 2 +-
variants/lora_relay_v2/variant.h | 2 +-
variants/pca10056-rc-clock/variant.h | 2 +-
variants/ppr/variant.h | 2 +-
5 files changed, 8 insertions(+), 14 deletions(-)
diff --git a/src/main.cpp b/src/main.cpp
index e494f9f20..0171631e7 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -492,16 +492,10 @@ void setup()
}
}
-#ifdef SX1262_ANT_SW
- // make analog PA vs not PA switch on SX1262 eval board work properly
- pinMode(SX1262_ANT_SW, OUTPUT);
- digitalWrite(SX1262_ANT_SW, 1);
-#endif
-
-#ifdef SX1268_ANT_SW
- // make analog PA vs not PA switch on SX1268 eval board work properly
- pinMode(SX1268_ANT_SW, OUTPUT);
- digitalWrite(SX1268_ANT_SW, 1);
+#ifdef SX126X_ANT_SW
+ // make analog PA vs not PA switch on SX126x eval board work properly
+ pinMode(SX126X_ANT_SW, OUTPUT);
+ digitalWrite(SX126X_ANT_SW, 1);
#endif
// radio init MUST BE AFTER service.init, so we have our radio config settings (from nodedb init)
diff --git a/variants/lora_relay_v1/variant.h b/variants/lora_relay_v1/variant.h
index 59a52f44a..74f3c5a68 100644
--- a/variants/lora_relay_v1/variant.h
+++ b/variants/lora_relay_v1/variant.h
@@ -126,7 +126,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define SX1262_DIO2 (30)
#define SX126X_BUSY (33) // Supposed to be P0.18 but because of reworks, now on P0.31 (18)
#define SX126X_RESET (34)
-// #define SX1262_ANT_SW (32 + 10)
+// #define SX126X_ANT_SW (32 + 10)
#define SX126X_RXEN (14)
#define SX126X_TXEN (31)
#define SX126X_POWER_EN \
diff --git a/variants/lora_relay_v2/variant.h b/variants/lora_relay_v2/variant.h
index 04a436739..ec3e7e904 100644
--- a/variants/lora_relay_v2/variant.h
+++ b/variants/lora_relay_v2/variant.h
@@ -146,7 +146,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define SX1262_DIO2 (30)
#define SX126X_BUSY (33) // Supposed to be P0.18 but because of reworks, now on P0.31 (18)
#define SX126X_RESET (34)
-// #define SX1262_ANT_SW (32 + 10)
+// #define SX126X_ANT_SW (32 + 10)
#define SX126X_RXEN (14)
#define SX126X_TXEN (31)
#define SX126X_POWER_EN \
diff --git a/variants/pca10056-rc-clock/variant.h b/variants/pca10056-rc-clock/variant.h
index 185faead8..b9c4f9bfd 100644
--- a/variants/pca10056-rc-clock/variant.h
+++ b/variants/pca10056-rc-clock/variant.h
@@ -144,7 +144,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define SX126X_DIO1 (32 + 6) // P1.06
#define SX126X_BUSY (32 + 4) // P1.04
#define SX126X_RESET (0 + 3) // P0.03
-#define SX1262_ANT_SW (32 + 10) // P1.10
+#define SX126X_ANT_SW (32 + 10) // P1.10
// To debug via the segger JLINK console rather than the CDC-ACM serial device
// #define USE_SEGGER
diff --git a/variants/ppr/variant.h b/variants/ppr/variant.h
index d2a72f879..b055c3d84 100644
--- a/variants/ppr/variant.h
+++ b/variants/ppr/variant.h
@@ -134,7 +134,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define SX1262_DIO2 (26)
#define SX126X_BUSY (31) // Supposed to be P0.18 but because of reworks, now on P0.31 (18)
#define SX126X_RESET (17)
-// #define SX1262_ANT_SW (32 + 10)
+// #define SX126X_ANT_SW (32 + 10)
#define SX126X_RXEN (22)
#define SX126X_TXEN (24)
#define SX126X_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that
From bd9bf585d3750998161eeb8f2371ad7bec3330b9 Mon Sep 17 00:00:00 2001
From: Vladislav Osmanov <7123463+osmanovv@users.noreply.github.com>
Date: Wed, 15 Sep 2021 12:09:11 +0300
Subject: [PATCH 08/10] save channel & freq before outputting them for
debugging
The frequency could be overridden in `RadioInterface::getFreq()` for some modules.
---
src/mesh/RadioInterface.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp
index 4bd352559..cf86ae01c 100644
--- a/src/mesh/RadioInterface.cpp
+++ b/src/mesh/RadioInterface.cpp
@@ -320,6 +320,9 @@ void RadioInterface::applyModemConfig()
int channel_num = channelSettings.channel_num ? channelSettings.channel_num - 1 : hash(channelName) % myRegion->numChannels;
float freq = myRegion->freq + radioConfig.preferences.frequency_offset + myRegion->spacing * channel_num;
+ saveChannelNum(channel_num);
+ saveFreq(freq);
+
DEBUG_MSG("Set radio: name=%s, config=%u, ch=%d, power=%d\n", channelName, channelSettings.modem_config, channel_num, power);
DEBUG_MSG("Radio myRegion->freq: %f\n", myRegion->freq);
DEBUG_MSG("Radio myRegion->spacing: %f\n", myRegion->spacing);
@@ -327,9 +330,6 @@ void RadioInterface::applyModemConfig()
DEBUG_MSG("Radio channel_num: %d\n", channel_num);
DEBUG_MSG("Radio frequency: %f\n", getFreq()); // the frequency could be overridden in RadioInterface::getFreq() for some modules
DEBUG_MSG("Short packet time: %u msec\n", shortPacketMsec);
-
- saveChannelNum(channel_num);
- saveFreq(freq);
}
/**
From a74f038cba6666bbbff2c9a65a3cbad6e1724408 Mon Sep 17 00:00:00 2001
From: Sam <35611307+syund@users.noreply.github.com>
Date: Wed, 15 Sep 2021 18:58:09 -0400
Subject: [PATCH 09/10] [866] Show fixed coordinates on screen and indicate
when using fixed coordinates.
---
src/GPSStatus.h | 34 +++++++++++++++++++++++++++++++---
src/graphics/Screen.cpp | 13 +++++++++----
2 files changed, 40 insertions(+), 7 deletions(-)
diff --git a/src/GPSStatus.h b/src/GPSStatus.h
index 237964eb0..3d1e5a6c7 100644
--- a/src/GPSStatus.h
+++ b/src/GPSStatus.h
@@ -1,8 +1,11 @@
#pragma once
#include "Status.h"
#include "configuration.h"
+#include "NodeDB.h"
#include
+extern NodeDB nodeDB;
+
namespace meshtastic
{
@@ -47,11 +50,36 @@ class GPSStatus : public Status
bool getIsConnected() const { return isConnected; }
- int32_t getLatitude() const { return latitude; }
+ int32_t getLatitude() const {
+ if (radioConfig.preferences.fixed_position){
+ DEBUG_MSG("WARNING: Using fixed latitude\n");
+ NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
+ return node->position.latitude_i;
+ } else {
+ return latitude;
+ }
+ }
- int32_t getLongitude() const { return longitude; }
+ int32_t getLongitude() const {
+ if (radioConfig.preferences.fixed_position){
+ DEBUG_MSG("WARNING: Using fixed longitude\n");
+ NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
+ return node->position.longitude_i;
+ } else {
+ return longitude;
+ }
+ }
+
+ int32_t getAltitude() const {
+ if (radioConfig.preferences.fixed_position){
+ DEBUG_MSG("WARNING: Using fixed altitude\n");
+ NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
+ return node->position.altitude;
+ } else {
+ return altitude;
+ }
+ }
- int32_t getAltitude() const { return altitude; }
uint32_t getDOP() const { return dop; }
diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp
index fd3671fb9..f889cf95b 100644
--- a/src/graphics/Screen.cpp
+++ b/src/graphics/Screen.cpp
@@ -333,6 +333,11 @@ static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, NodeStatus *no
// Draw GPS status summary
static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
{
+ if (radioConfig.preferences.fixed_position) {
+ // GPS coordinates are currently fixed
+ display->drawString(x - 1, y - 2, "Fixed GPS");
+ return;
+ }
if (!gps->getIsConnected()) {
display->drawString(x, y - 2, "No GPS");
return;
@@ -367,10 +372,10 @@ static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus
static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
{
String displayLine = "";
- if (!gps->getIsConnected()) {
+ if (!gps->getIsConnected() && !radioConfig.preferences.fixed_position) {
// displayLine = "No GPS Module";
// display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
- } else if (!gps->getHasLock()) {
+ } else if (!gps->getHasLock() && !radioConfig.preferences.fixed_position) {
// displayLine = "No GPS Lock";
// display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
} else {
@@ -743,10 +748,10 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const
auto gpsFormat = radioConfig.preferences.gps_format;
String displayLine = "";
- if (!gps->getIsConnected()) {
+ if (!gps->getIsConnected() && !radioConfig.preferences.fixed_position) {
displayLine = "No GPS Module";
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
- } else if (!gps->getHasLock()) {
+ } else if (!gps->getHasLock() && !radioConfig.preferences.fixed_position) {
displayLine = "No GPS Lock";
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
} else {
From 16d2c565e878fefd9bc426efe9782a2199af2252 Mon Sep 17 00:00:00 2001
From: Vladislav Osmanov
Date: Sat, 18 Sep 2021 21:39:29 +0300
Subject: [PATCH 10/10] Use EU433 frequency value as default for SX1268
---
src/mesh/SX1268Interface.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/mesh/SX1268Interface.h b/src/mesh/SX1268Interface.h
index fb2239041..c5b56171b 100644
--- a/src/mesh/SX1268Interface.h
+++ b/src/mesh/SX1268Interface.h
@@ -8,8 +8,8 @@
class SX1268Interface : public SX126xInterface
{
public:
- /// override frequency of the SX1268 module regardless of the region
- virtual float getFreq() { return 433.0; }
+ /// override frequency of the SX1268 module regardless of the region (use EU433 value)
+ virtual float getFreq() { return 433.175f; }
SX1268Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
};
\ No newline at end of file