From f69ddf168b6914685720649e6e26ea5622c4f80c Mon Sep 17 00:00:00 2001 From: geeksville Date: Wed, 29 Apr 2020 18:46:32 -0700 Subject: [PATCH] we now hopefully apply the same radio settings as we did for the RF95 --- src/main.cpp | 6 +++ src/mesh/MeshRadio.cpp | 41 ++++++--------- src/mesh/MeshRadio.h | 5 ++ src/rf95/CustomRF95.cpp | 29 +++++++++++ src/rf95/CustomRF95.h | 2 + src/rf95/RadioInterface.cpp | 3 +- src/rf95/RadioInterface.h | 91 +++------------------------------- src/rf95/RadioLibInterface.cpp | 31 ++++++++++++ src/rf95/RadioLibInterface.h | 67 ++++++------------------- src/rf95/SX1262Interface.cpp | 39 +++++++++++++++ src/rf95/SX1262Interface.h | 5 ++ 11 files changed, 156 insertions(+), 163 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 22187b40e..8d95b9609 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -191,6 +191,12 @@ void setup() realRouter.setup(); // required for our periodic task (kinda skanky FIXME) +#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 + // MUST BE AFTER service.init, so we have our radio config settings (from nodedb init) RadioInterface *rIf = #if defined(RF95_IRQ_GPIO) diff --git a/src/mesh/MeshRadio.cpp b/src/mesh/MeshRadio.cpp index 9c21937cc..0437c3f36 100644 --- a/src/mesh/MeshRadio.cpp +++ b/src/mesh/MeshRadio.cpp @@ -57,16 +57,15 @@ bool MeshRadio::init() radioIf.setThisAddress( nodeDB.getNodeNum()); // Note: we must do this here, because the nodenum isn't inited at constructor time. + applySettings(); + if (!radioIf.init()) { DEBUG_MSG("LoRa radio init failed\n"); DEBUG_MSG("Uncomment '#define SERIAL_DEBUG' in RH_RF95.cpp for detailed debug info\n"); return false; } - // not needed - defaults on - // rf95.setPayloadCRC(true); - - reloadConfig(); + // No need to call this now, init is supposed to do same. reloadConfig(); return true; } @@ -87,38 +86,28 @@ unsigned long hash(char *str) return hash; } -int MeshRadio::reloadConfig(void *unused) +/** + * Pull our channel settings etc... from protobufs to the dumb interface settings + */ +void MeshRadio::applySettings() { - radioIf.setModeIdle(); // Need to be idle before doing init - // Set up default configuration // No Sync Words in LORA mode. - radioIf.setModemConfig( - (RH_RF95::ModemConfigChoice)channelSettings.modem_config); // Radio default - // setModemConfig(Bw125Cr48Sf4096); // slow and reliable? - // rf95.setPreambleLength(8); // Default is 8 + radioIf.modemConfig = (RH_RF95::ModemConfigChoice)channelSettings.modem_config; // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM int channel_num = hash(channelSettings.name) % NUM_CHANNELS; - float center_freq = CH0 + CH_SPACING * channel_num; - if (!radioIf.setFrequency(center_freq)) { - DEBUG_MSG("setFrequency failed\n"); - assert(0); // fixme panic - } - - // Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on - - // The default transmitter power is 13dBm, using PA_BOOST. - // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then - // you can set transmitter powers from 5 to 23 dBm: - // FIXME - can we do this? It seems to be in the Heltec board. - radioIf.setTxPower(channelSettings.tx_power, false); + radioIf.freq = CH0 + CH_SPACING * channel_num; + radioIf.power = channelSettings.tx_power; DEBUG_MSG("Set radio: name=%s, config=%u, ch=%d, txpower=%d\n", channelSettings.name, channelSettings.modem_config, channel_num, channelSettings.tx_power); +} - // Done with init tell radio to start receiving - radioIf.setModeRx(); +int MeshRadio::reloadConfig(void *unused) +{ + applySettings(); + radioIf.reconfigure(); return 0; } diff --git a/src/mesh/MeshRadio.h b/src/mesh/MeshRadio.h index da19eebb8..1580cea47 100644 --- a/src/mesh/MeshRadio.h +++ b/src/mesh/MeshRadio.h @@ -100,4 +100,9 @@ class MeshRadio radioIf.sleep(); return 0; } + + /** + * Pull our channel settings etc... from protobufs to the dumb interface settings + */ + void applySettings(); }; diff --git a/src/rf95/CustomRF95.cpp b/src/rf95/CustomRF95.cpp index eba19006a..59eb38a78 100644 --- a/src/rf95/CustomRF95.cpp +++ b/src/rf95/CustomRF95.cpp @@ -38,6 +38,9 @@ bool CustomRF95::init() { bool ok = RH_RF95::init(); + if (ok) + reconfigure(); // Finish our device setup + return ok; } @@ -205,4 +208,30 @@ void CustomRF95::loop() } } +bool CustomRF95::reconfigure() +{ + radioIf.setModeIdle(); // Need to be idle before doing init + + // Set up default configuration + // No Sync Words in LORA mode. + setModemConfig(modemConfig); // Radio default + // setModemConfig(Bw125Cr48Sf4096); // slow and reliable? + // rf95.setPreambleLength(8); // Default is 8 + + if (!setFrequency(freq)) { + DEBUG_MSG("setFrequency failed\n"); + assert(0); // fixme panic + } + + // Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on + + // The default transmitter power is 13dBm, using PA_BOOST. + // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then + // you can set transmitter powers from 5 to 23 dBm: + // FIXME - can we do this? It seems to be in the Heltec board. + radioIf.setTxPower(tx_power, false); + + // Done with init tell radio to start receiving + radioIf.setModeRx(); +} #endif \ No newline at end of file diff --git a/src/rf95/CustomRF95.h b/src/rf95/CustomRF95.h index ad7996480..5582ab830 100644 --- a/src/rf95/CustomRF95.h +++ b/src/rf95/CustomRF95.h @@ -40,6 +40,8 @@ class CustomRF95 : public RH_RF95, public RadioInterface bool init(); + bool reconfigure(); + void loop(); // Idle processing protected: diff --git a/src/rf95/RadioInterface.cpp b/src/rf95/RadioInterface.cpp index d43922ffb..c2f555c32 100644 --- a/src/rf95/RadioInterface.cpp +++ b/src/rf95/RadioInterface.cpp @@ -19,4 +19,5 @@ void RadioInterface::deliverToReceiver(MeshPacket *p) { assert(rxDest); assert(rxDest->enqueue(p, 0)); // NOWAIT - fixme, if queue is full, delete older messages -} \ No newline at end of file +} + diff --git a/src/rf95/RadioInterface.h b/src/rf95/RadioInterface.h index 59f64cdf7..612c25a65 100644 --- a/src/rf95/RadioInterface.h +++ b/src/rf95/RadioInterface.h @@ -27,6 +27,10 @@ class RadioInterface void deliverToReceiver(MeshPacket *p); public: + float freq = 915.0; // FIXME, init all these params from user setings + int8_t power = 17; + RH_RF95::ModemConfigChoice modemConfig; + /** pool is the pool we will alloc our rx packets from * rxDest is where we will send any rx packets, it becomes receivers responsibility to return packet to the pool */ @@ -74,53 +78,10 @@ class RadioInterface /// \return true if initialisation succeeded. virtual bool init() = 0; - /// Sets the transmitter and receiver - /// centre frequency. - /// \param[in] centre Frequency in MHz. 137.0 to 1020.0. Caution: RFM95/96/97/98 comes in several - /// different frequency ranges, and setting a frequency outside that range of your radio will probably not work - /// \return true if the selected frquency centre is within range - virtual bool setFrequency(float centre) = 0; - - /// Select one of the predefined modem configurations. If you need a modem configuration not provided - /// here, use setModemRegisters() with your own ModemConfig. - /// Caution: the slowest protocols may require a radio module with TCXO temperature controlled oscillator - /// for reliable operation. - /// \param[in] index The configuration choice. - /// \return true if index is a valid choice. - virtual bool setModemConfig(RH_RF95::ModemConfigChoice index) = 0; - - /// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running, - /// disables them. - virtual void setModeIdle() = 0; - - /// If current mode is Tx or Idle, changes it to Rx. - /// Starts the receiver in the RF95/96/97/98. - virtual void setModeRx() = 0; - - /// Returns the operating mode of the library. - /// \return the current mode, one of RF69_MODE_* - virtual RHGenericDriver::RHMode mode() = 0; - - /// Sets the transmitter power output level, and configures the transmitter pin. - /// Be a good neighbour and set the lowest power level you need. - /// Some SX1276/77/78/79 and compatible modules (such as RFM95/96/97/98) - /// use the PA_BOOST transmitter pin for high power output (and optionally the PA_DAC) - /// while some (such as the Modtronix inAir4 and inAir9) - /// use the RFO transmitter pin for lower power but higher efficiency. - /// You must set the appropriate power level and useRFO argument for your module. - /// Check with your module manufacturer which transmtter pin is used on your module - /// to ensure you are setting useRFO correctly. - /// Failure to do so will result in very low - /// transmitter power output. - /// Caution: legal power limits may apply in certain countries. - /// After init(), the power will be set to 13dBm, with useRFO false (ie PA_BOOST enabled). - /// \param[in] power Transmitter power level in dBm. For RFM95/96/97/98 LORA with useRFO false, - /// valid values are from +5 to +23. - /// For Modtronix inAir4 and inAir9 with useRFO true (ie RFO pins in use), - /// valid values are from -1 to 14. - /// \param[in] useRFO If true, enables the use of the RFO transmitter pins instead of - /// the PA_BOOST pin (false). Choose the correct setting for your module. - void setTxPower(int8_t power, bool useRFO = false) {} + /// Apply any radio provisioning changes + /// Make sure the Driver is properly configured before calling init(). + /// \return true if initialisation succeeded. + virtual bool reconfigure() = 0; }; class SimRadio : public RadioInterface @@ -146,21 +107,6 @@ class SimRadio : public RadioInterface /// \return true if initialisation succeeded. virtual bool init() { return true; } - /// Sets the transmitter and receiver - /// centre frequency. - /// \param[in] centre Frequency in MHz. 137.0 to 1020.0. Caution: RFM95/96/97/98 comes in several - /// different frequency ranges, and setting a frequency outside that range of your radio will probably not work - /// \return true if the selected frquency centre is within range - bool setFrequency(float centre) { return true; } - - /// Select one of the predefined modem configurations. If you need a modem configuration not provided - /// here, use setModemRegisters() with your own ModemConfig. - /// Caution: the slowest protocols may require a radio module with TCXO temperature controlled oscillator - /// for reliable operation. - /// \param[in] index The configuration choice. - /// \return true if index is a valid choice. - bool setModemConfig(RH_RF95::ModemConfigChoice index) { return true; } - /// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running, /// disables them. void setModeIdle() {} @@ -172,25 +118,4 @@ class SimRadio : public RadioInterface /// Returns the operating mode of the library. /// \return the current mode, one of RF69_MODE_* virtual RHGenericDriver::RHMode mode() { return RHGenericDriver::RHModeIdle; } - - /// Sets the transmitter power output level, and configures the transmitter pin. - /// Be a good neighbour and set the lowest power level you need. - /// Some SX1276/77/78/79 and compatible modules (such as RFM95/96/97/98) - /// use the PA_BOOST transmitter pin for high power output (and optionally the PA_DAC) - /// while some (such as the Modtronix inAir4 and inAir9) - /// use the RFO transmitter pin for lower power but higher efficiency. - /// You must set the appropriate power level and useRFO argument for your module. - /// Check with your module manufacturer which transmtter pin is used on your module - /// to ensure you are setting useRFO correctly. - /// Failure to do so will result in very low - /// transmitter power output. - /// Caution: legal power limits may apply in certain countries. - /// After init(), the power will be set to 13dBm, with useRFO false (ie PA_BOOST enabled). - /// \param[in] power Transmitter power level in dBm. For RFM95/96/97/98 LORA with useRFO false, - /// valid values are from +5 to +23. - /// For Modtronix inAir4 and inAir9 with useRFO true (ie RFO pins in use), - /// valid values are from -1 to 14. - /// \param[in] useRFO If true, enables the use of the RFO transmitter pins instead of - /// the PA_BOOST pin (false). Choose the correct setting for your module. - void setTxPower(int8_t power, bool useRFO = false) {} }; diff --git a/src/rf95/RadioLibInterface.cpp b/src/rf95/RadioLibInterface.cpp index 9f5858e06..c9f59b05d 100644 --- a/src/rf95/RadioLibInterface.cpp +++ b/src/rf95/RadioLibInterface.cpp @@ -10,6 +10,37 @@ RadioLibInterface::RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq { } +/** + * Convert our modemConfig enum into wf, sf, etc... + */ +void RadioLibInterface::applyModemConfig() +{ + switch (modemConfig) { + case RH_RF95::Bw125Cr45Sf128: ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range + bw = 125; + cr = 5; + sf = 7; + break; + case RH_RF95::Bw500Cr45Sf128: ///< Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Fast+short range + bw = 500; + cr = 5; + sf = 7; + break; + case RH_RF95::Bw31_25Cr48Sf512: ///< Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long range + bw = 31.25; + cr = 8; + sf = 9; + break; + case RH_RF95::Bw125Cr48Sf4096: + bw = 125; + cr = 8; + sf = 12; + break; + default: + assert(0); // Unknown enum + } +} + ErrorCode RadioLibInterface::send(MeshPacket *p) { return ERR_NONE; diff --git a/src/rf95/RadioLibInterface.h b/src/rf95/RadioLibInterface.h index 6bccd7b2c..9ca0f0de7 100644 --- a/src/rf95/RadioLibInterface.h +++ b/src/rf95/RadioLibInterface.h @@ -7,12 +7,16 @@ class RadioLibInterface : public RadioInterface { protected: - float freq = 915.0; // FIXME, init all these params from suer setings float bw = 125; uint8_t sf = 9; uint8_t cr = 7; - uint8_t syncWord = 0; // FIXME, use a meshtastic sync word, but hashed with the Channel name - int8_t power = 17; + + /** + * FIXME, use a meshtastic sync word, but hashed with the Channel name. Currently picking the same default + * the RF95 used (0x14). Note: do not use 0x34 - that is reserved for lorawan + */ + uint8_t syncWord = SX126X_SYNC_WORD_PRIVATE; + float currentLimit = 100; // FIXME uint16_t preambleLength = 8; @@ -24,9 +28,8 @@ class RadioLibInterface : public RadioInterface PhysicalLayer &iface; public: - RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, - SPIClass &spi, - PhysicalLayer *iface); + RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi, + PhysicalLayer *iface); virtual ErrorCode send(MeshPacket *p); @@ -48,51 +51,9 @@ class RadioLibInterface : public RadioInterface /// \return true if initialisation succeeded. virtual bool init() { return true; } - /// Sets the transmitter and receiver - /// centre frequency. - /// \param[in] centre Frequency in MHz. 137.0 to 1020.0. Caution: RFM95/96/97/98 comes in several - /// different frequency ranges, and setting a frequency outside that range of your radio will probably not work - /// \return true if the selected frquency centre is within range - bool setFrequency(float centre) { return true; } - - /// Select one of the predefined modem configurations. If you need a modem configuration not provided - /// here, use setModemRegisters() with your own ModemConfig. - /// Caution: the slowest protocols may require a radio module with TCXO temperature controlled oscillator - /// for reliable operation. - /// \param[in] index The configuration choice. - /// \return true if index is a valid choice. - bool setModemConfig(RH_RF95::ModemConfigChoice index) { return true; } - - /// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running, - /// disables them. - void setModeIdle() {} - - /// If current mode is Tx or Idle, changes it to Rx. - /// Starts the receiver in the RF95/96/97/98. - void setModeRx() {} - - /// Returns the operating mode of the library. - /// \return the current mode, one of RF69_MODE_* - virtual RHGenericDriver::RHMode mode() { return RHGenericDriver::RHModeIdle; } - - /// Sets the transmitter power output level, and configures the transmitter pin. - /// Be a good neighbour and set the lowest power level you need. - /// Some SX1276/77/78/79 and compatible modules (such as RFM95/96/97/98) - /// use the PA_BOOST transmitter pin for high power output (and optionally the PA_DAC) - /// while some (such as the Modtronix inAir4 and inAir9) - /// use the RFO transmitter pin for lower power but higher efficiency. - /// You must set the appropriate power level and useRFO argument for your module. - /// Check with your module manufacturer which transmtter pin is used on your module - /// to ensure you are setting useRFO correctly. - /// Failure to do so will result in very low - /// transmitter power output. - /// Caution: legal power limits may apply in certain countries. - /// After init(), the power will be set to 13dBm, with useRFO false (ie PA_BOOST enabled). - /// \param[in] power Transmitter power level in dBm. For RFM95/96/97/98 LORA with useRFO false, - /// valid values are from +5 to +23. - /// For Modtronix inAir4 and inAir9 with useRFO true (ie RFO pins in use), - /// valid values are from -1 to 14. - /// \param[in] useRFO If true, enables the use of the RFO transmitter pins instead of - /// the PA_BOOST pin (false). Choose the correct setting for your module. - void setTxPower(int8_t power, bool useRFO = false) {} + protected: + /** + * Convert our modemConfig enum into wf, sf, etc... + */ + void applyModemConfig(); }; \ No newline at end of file diff --git a/src/rf95/SX1262Interface.cpp b/src/rf95/SX1262Interface.cpp index 90604c6c1..73ee2e5ed 100644 --- a/src/rf95/SX1262Interface.cpp +++ b/src/rf95/SX1262Interface.cpp @@ -21,8 +21,47 @@ bool SX1262Interface::init() float tcxoVoltage = 0; // None - we use an XTAL bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC? + applyModemConfig(); int res = lora.begin(freq, bw, sf, cr, syncWord, power, currentLimit, preambleLength, tcxoVoltage, useRegulatorLDO); DEBUG_MSG("LORA init result %d\n", res); return res == ERR_NONE; } + +bool SX1262Interface::reconfigure() +{ + applyModemConfig(); + + // set mode to standby + int err = lora.standby(); + assert(err == ERR_NONE); + + // configure publicly accessible settings + err = lora.setSpreadingFactor(sf); + assert(err == ERR_NONE); + + err = lora.setBandwidth(bw); + assert(err == ERR_NONE); + + err = lora.setCodingRate(cr); + 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); + assert(err == ERR_NONE); + + err = lora.setOutputPower(power); + assert(err == ERR_NONE); + + assert(0); // FIXME - set mode back to receive? + + return true; +} diff --git a/src/rf95/SX1262Interface.h b/src/rf95/SX1262Interface.h index aa577a734..c700145ef 100644 --- a/src/rf95/SX1262Interface.h +++ b/src/rf95/SX1262Interface.h @@ -13,4 +13,9 @@ class SX1262Interface : public RadioLibInterface /// 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(); }; \ No newline at end of file