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 1/8] 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 a1de8dc6..273c7adc 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 00000000..9d0df82c --- /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 00000000..33f696c9 --- /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 2/8] 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 33f696c9..0c43c163 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 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 3/8] 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 2080e6e3..23eab0bf 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 273c7adc..47fbc84e 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 00000000..a50fbd6b --- /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 76d44625..d0137280 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 05a93a33..0f029ada 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 9d0df82c..66894312 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 0c43c163..c4c98da0 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 00000000..d4deef0f --- /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 00000000..1b4a1004 --- /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 d2caf695..46abd6b8 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 e9e28dc1..8598dc1b 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 1b30ca21..d07597a2 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 9bf5cd50..d23a20a0 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 f7ade958..59a52f44 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 6814fdb3..04a43673 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 9d35325c..185faead 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 bbdda306..d2a72f87 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 04a6e3c0..b5d398c3 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 40021891..beb9e550 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 4/8] 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 47fbc84e..e494f9f2 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 5/8] 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 8b7d9f11..5a1cce32 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 7551473c..4bd35255 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 c0d7ec2d..542b575d 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 c4c98da0..fb223904 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 d4deef0f..b0c48d55 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 6/8] 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 e494f9f2..0171631e 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 59a52f44..74f3c5a6 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 04a43673..ec3e7e90 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 185faead..b9c4f9bf 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 d2a72f87..b055c3d8 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 7/8] 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 4bd35255..cf86ae01 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 16d2c565e878fefd9bc426efe9782a2199af2252 Mon Sep 17 00:00:00 2001 From: Vladislav Osmanov Date: Sat, 18 Sep 2021 21:39:29 +0300 Subject: [PATCH 8/8] 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 fb223904..c5b56171 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