we now hopefully apply the same radio settings as we did for the RF95

This commit is contained in:
geeksville 2020-04-29 18:46:32 -07:00
parent 8d985cfd37
commit f69ddf168b
11 changed files with 156 additions and 163 deletions

View File

@ -191,6 +191,12 @@ void setup()
realRouter.setup(); // required for our periodic task (kinda skanky FIXME) 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) // MUST BE AFTER service.init, so we have our radio config settings (from nodedb init)
RadioInterface *rIf = RadioInterface *rIf =
#if defined(RF95_IRQ_GPIO) #if defined(RF95_IRQ_GPIO)

View File

@ -57,16 +57,15 @@ bool MeshRadio::init()
radioIf.setThisAddress( radioIf.setThisAddress(
nodeDB.getNodeNum()); // Note: we must do this here, because the nodenum isn't inited at constructor time. nodeDB.getNodeNum()); // Note: we must do this here, because the nodenum isn't inited at constructor time.
applySettings();
if (!radioIf.init()) { if (!radioIf.init()) {
DEBUG_MSG("LoRa radio init failed\n"); DEBUG_MSG("LoRa radio init failed\n");
DEBUG_MSG("Uncomment '#define SERIAL_DEBUG' in RH_RF95.cpp for detailed debug info\n"); DEBUG_MSG("Uncomment '#define SERIAL_DEBUG' in RH_RF95.cpp for detailed debug info\n");
return false; return false;
} }
// not needed - defaults on // No need to call this now, init is supposed to do same. reloadConfig();
// rf95.setPayloadCRC(true);
reloadConfig();
return true; return true;
} }
@ -87,38 +86,28 @@ unsigned long hash(char *str)
return hash; 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 // Set up default configuration
// No Sync Words in LORA mode. // No Sync Words in LORA mode.
radioIf.setModemConfig( radioIf.modemConfig = (RH_RF95::ModemConfigChoice)channelSettings.modem_config;
(RH_RF95::ModemConfigChoice)channelSettings.modem_config); // Radio default
// setModemConfig(Bw125Cr48Sf4096); // slow and reliable?
// rf95.setPreambleLength(8); // Default is 8
// Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
int channel_num = hash(channelSettings.name) % NUM_CHANNELS; int channel_num = hash(channelSettings.name) % NUM_CHANNELS;
float center_freq = CH0 + CH_SPACING * channel_num; radioIf.freq = CH0 + CH_SPACING * channel_num;
if (!radioIf.setFrequency(center_freq)) { radioIf.power = channelSettings.tx_power;
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);
DEBUG_MSG("Set radio: name=%s, config=%u, ch=%d, txpower=%d\n", channelSettings.name, channelSettings.modem_config, DEBUG_MSG("Set radio: name=%s, config=%u, ch=%d, txpower=%d\n", channelSettings.name, channelSettings.modem_config,
channel_num, channelSettings.tx_power); channel_num, channelSettings.tx_power);
}
// Done with init tell radio to start receiving int MeshRadio::reloadConfig(void *unused)
radioIf.setModeRx(); {
applySettings();
radioIf.reconfigure();
return 0; return 0;
} }

View File

@ -100,4 +100,9 @@ class MeshRadio
radioIf.sleep(); radioIf.sleep();
return 0; return 0;
} }
/**
* Pull our channel settings etc... from protobufs to the dumb interface settings
*/
void applySettings();
}; };

View File

@ -38,6 +38,9 @@ bool CustomRF95::init()
{ {
bool ok = RH_RF95::init(); bool ok = RH_RF95::init();
if (ok)
reconfigure(); // Finish our device setup
return ok; 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 #endif

View File

@ -40,6 +40,8 @@ class CustomRF95 : public RH_RF95, public RadioInterface
bool init(); bool init();
bool reconfigure();
void loop(); // Idle processing void loop(); // Idle processing
protected: protected:

View File

@ -20,3 +20,4 @@ void RadioInterface::deliverToReceiver(MeshPacket *p)
assert(rxDest); assert(rxDest);
assert(rxDest->enqueue(p, 0)); // NOWAIT - fixme, if queue is full, delete older messages assert(rxDest->enqueue(p, 0)); // NOWAIT - fixme, if queue is full, delete older messages
} }

View File

@ -27,6 +27,10 @@ class RadioInterface
void deliverToReceiver(MeshPacket *p); void deliverToReceiver(MeshPacket *p);
public: 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 /** 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 * 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. /// \return true if initialisation succeeded.
virtual bool init() = 0; virtual bool init() = 0;
/// Sets the transmitter and receiver /// Apply any radio provisioning changes
/// centre frequency. /// Make sure the Driver is properly configured before calling init().
/// \param[in] centre Frequency in MHz. 137.0 to 1020.0. Caution: RFM95/96/97/98 comes in several /// \return true if initialisation succeeded.
/// different frequency ranges, and setting a frequency outside that range of your radio will probably not work virtual bool reconfigure() = 0;
/// \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) {}
}; };
class SimRadio : public RadioInterface class SimRadio : public RadioInterface
@ -146,21 +107,6 @@ class SimRadio : public RadioInterface
/// \return true if initialisation succeeded. /// \return true if initialisation succeeded.
virtual bool init() { return true; } 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, /// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running,
/// disables them. /// disables them.
void setModeIdle() {} void setModeIdle() {}
@ -172,25 +118,4 @@ class SimRadio : public RadioInterface
/// Returns the operating mode of the library. /// Returns the operating mode of the library.
/// \return the current mode, one of RF69_MODE_* /// \return the current mode, one of RF69_MODE_*
virtual RHGenericDriver::RHMode mode() { return RHGenericDriver::RHModeIdle; } 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) {}
}; };

View File

@ -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) ErrorCode RadioLibInterface::send(MeshPacket *p)
{ {
return ERR_NONE; return ERR_NONE;

View File

@ -7,12 +7,16 @@
class RadioLibInterface : public RadioInterface class RadioLibInterface : public RadioInterface
{ {
protected: protected:
float freq = 915.0; // FIXME, init all these params from suer setings
float bw = 125; float bw = 125;
uint8_t sf = 9; uint8_t sf = 9;
uint8_t cr = 7; 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 float currentLimit = 100; // FIXME
uint16_t preambleLength = 8; uint16_t preambleLength = 8;
@ -24,8 +28,7 @@ class RadioLibInterface : public RadioInterface
PhysicalLayer &iface; PhysicalLayer &iface;
public: public:
RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi,
SPIClass &spi,
PhysicalLayer *iface); PhysicalLayer *iface);
virtual ErrorCode send(MeshPacket *p); virtual ErrorCode send(MeshPacket *p);
@ -48,51 +51,9 @@ class RadioLibInterface : public RadioInterface
/// \return true if initialisation succeeded. /// \return true if initialisation succeeded.
virtual bool init() { return true; } virtual bool init() { return true; }
/// Sets the transmitter and receiver protected:
/// centre frequency. /**
/// \param[in] centre Frequency in MHz. 137.0 to 1020.0. Caution: RFM95/96/97/98 comes in several * Convert our modemConfig enum into wf, sf, etc...
/// 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 void applyModemConfig();
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) {}
}; };

View File

@ -21,8 +21,47 @@ bool SX1262Interface::init()
float tcxoVoltage = 0; // None - we use an XTAL 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? 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); int res = lora.begin(freq, bw, sf, cr, syncWord, power, currentLimit, preambleLength, tcxoVoltage, useRegulatorLDO);
DEBUG_MSG("LORA init result %d\n", res); DEBUG_MSG("LORA init result %d\n", res);
return res == ERR_NONE; 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;
}

View File

@ -13,4 +13,9 @@ class SX1262Interface : public RadioLibInterface
/// Make sure the Driver is properly configured before calling init(). /// Make sure the Driver is properly configured before calling init().
/// \return true if initialisation succeeded. /// \return true if initialisation succeeded.
virtual bool init(); 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();
}; };