diff --git a/boards/ppr.json b/boards/ppr.json
index 5283fdc4e..5050758f7 100644
--- a/boards/ppr.json
+++ b/boards/ppr.json
@@ -10,7 +10,7 @@
"hwids": [["0x239A", "0x4403"]],
"usb_product": "PPR",
"mcu": "nrf52840",
- "variant": "ppr",
+ "variant": "pca10056-rc-clock",
"variants_dir": "variants",
"bsp": {
"name": "adafruit"
diff --git a/docs/software/nrf52-TODO.md b/docs/software/nrf52-TODO.md
index bf1d71b32..6e6555083 100644
--- a/docs/software/nrf52-TODO.md
+++ b/docs/software/nrf52-TODO.md
@@ -11,6 +11,7 @@ Minimum items needed to make sure hardware is good.
- switch to RadioLab? test it with current radio. https://github.com/jgromes/RadioLib
- use "variants" to get all gpio bindings
- plug in correct variants for the real board
+- remove unused sx1262 lib from github
- Use the PMU driver on real hardware
- add a NEMA based GPS driver to test GPS
- Use new radio driver on real hardware - possibly start with https://os.mbed.com/teams/Semtech/code/SX126xLib/
diff --git a/platformio.ini b/platformio.ini
index ceb57fbc6..d570b1190 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -73,7 +73,7 @@ lib_deps =
Wire ; explicitly needed here because the AXP202 library forgets to add it
https://github.com/meshtastic/arduino-fsm.git
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git
- https://github.com/jgromes/RadioLib.git
+ https://github.com/meshtastic/RadioLib.git
; Common settings for ESP targes, mixin with extends = esp32_base
[esp32_base]
diff --git a/src/configuration.h b/src/configuration.h
index 8f443904e..b02a1a00f 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -217,10 +217,12 @@ along with this program. If not, see .
#define LED_INVERTED 1
// Temporarily testing if we can build the RF95 driver for NRF52
+#if 0
#define RESET_GPIO 14 // If defined, this pin will be used to reset the LORA radio
#define RF95_IRQ_GPIO 26 // IRQ line for the LORA radio
#define DIO1_GPIO 35 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number
#define DIO2_GPIO 34 // DIO1 & DIO2 are not currently used, but they must be assigned to a pin number
+#endif
#endif
diff --git a/src/main.cpp b/src/main.cpp
index d0e8ddd7f..f79c9e016 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -118,6 +118,9 @@ static uint32_t ledBlinker()
Periodic ledPeriodic(ledBlinker);
+#include "RadioLibInterface.h"
+#include "variant.h"
+
void setup()
{
#ifdef USE_SEGGER
@@ -189,7 +192,15 @@ void setup()
realRouter.setup(); // required for our periodic task (kinda skanky FIXME)
// MUST BE AFTER service.init, so we have our radio config settings (from nodedb init)
- radio = new MeshRadio();
+ RadioInterface *rIf =
+#if defined(RF95_IRQ_GPIO)
+ new CustomRF95();
+#elif defined(SX1262_CS)
+ new RadioLibInterface(SX1262_CS, SX1262_DIO1, SX1262_RESET, SX1262_BUSY, SPI);
+#else
+ new SimRadio();
+#endif
+ radio = new MeshRadio(rIf);
router.addInterface(&radio->radioIf);
if (radio && !radio->init())
diff --git a/src/mesh/MeshRadio.cpp b/src/mesh/MeshRadio.cpp
index 4242a94a2..9c21937cc 100644
--- a/src/mesh/MeshRadio.cpp
+++ b/src/mesh/MeshRadio.cpp
@@ -24,7 +24,7 @@ separated by 2.16 MHz with respect to the adjacent channels. Channel zero starts
/// Sometimes while debugging it is useful to set this false, to disable rf95 accesses
bool useHardware = true;
-MeshRadio::MeshRadio() // , manager(radioIf)
+MeshRadio::MeshRadio(RadioInterface *rIf) : radioIf(*rIf) // , manager(radioIf)
{
myNodeInfo.num_channels = NUM_CHANNELS;
@@ -122,4 +122,3 @@ int MeshRadio::reloadConfig(void *unused)
return 0;
}
-
diff --git a/src/mesh/MeshRadio.h b/src/mesh/MeshRadio.h
index 186af9f5e..da19eebb8 100644
--- a/src/mesh/MeshRadio.h
+++ b/src/mesh/MeshRadio.h
@@ -63,23 +63,19 @@
/**
* A raw low level interface to our mesh. Only understands nodenums and bytes (not protobufs or node ids)
+ * FIXME - REMOVE THIS CLASS
*/
class MeshRadio
{
public:
// Kinda ugly way of selecting different radio implementations, but soon this MeshRadio class will be going away
// entirely. At that point we can make things pretty.
-#ifdef RF95_IRQ_GPIO
- CustomRF95
- radioIf; // the raw radio interface - for now I'm leaving public - because this class is shrinking to be almost nothing
-#else
- SimRadio radioIf;
-#endif
+ RadioInterface &radioIf;
/** 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
*/
- MeshRadio();
+ MeshRadio(RadioInterface *rIf);
bool init();
diff --git a/src/rf95/CustomRF95.cpp b/src/rf95/CustomRF95.cpp
index 7005a9ce1..eba19006a 100644
--- a/src/rf95/CustomRF95.cpp
+++ b/src/rf95/CustomRF95.cpp
@@ -149,7 +149,7 @@ void CustomRF95::handleIdleISR()
startSend(txp);
else {
// Nothing to send, let's switch back to receive mode
- setModeRx();
+ RH_RF95::setModeRx();
}
}
@@ -193,9 +193,9 @@ void CustomRF95::loop()
// It should never take us more than 30 secs to send a packet, if it does, we have a bug, FIXME, move most of this
// into CustomRF95
uint32_t now = millis();
- if (lastTxStart != 0 && (now - lastTxStart) > TX_WATCHDOG_TIMEOUT && mode() == RHGenericDriver::RHModeTx) {
+ if (lastTxStart != 0 && (now - lastTxStart) > TX_WATCHDOG_TIMEOUT && RH_RF95::mode() == RHGenericDriver::RHModeTx) {
DEBUG_MSG("ERROR! Bug! Tx packet took too long to send, forcing radio into rx mode\n");
- setModeRx();
+ RH_RF95::setModeRx();
if (sendingPacket) { // There was probably a packet we were trying to send, free it
packetPool.release(sendingPacket);
sendingPacket = NULL;
diff --git a/src/rf95/RadioInterface.h b/src/rf95/RadioInterface.h
index bad532a1e..59f64cdf7 100644
--- a/src/rf95/RadioInterface.h
+++ b/src/rf95/RadioInterface.h
@@ -55,6 +55,72 @@ class RadioInterface
* If the txmit queue is full it might return an error
*/
virtual ErrorCode send(MeshPacket *p) = 0;
+
+ // methods from radiohead
+
+ /// Sets the address of this node. Defaults to 0xFF. Subclasses or the user may want to change this.
+ /// This will be used to test the adddress in incoming messages. In non-promiscuous mode,
+ /// only messages with a TO header the same as thisAddress or the broadcast addess (0xFF) will be accepted.
+ /// In promiscuous mode, all messages will be accepted regardless of the TO header.
+ /// In a conventional multinode system, all nodes will have a unique address
+ /// (which you could store in EEPROM).
+ /// You would normally set the header FROM address to be the same as thisAddress (though you dont have to,
+ /// allowing the possibilty of address spoofing).
+ /// \param[in] thisAddress The address of this node.
+ virtual void setThisAddress(uint8_t thisAddress) = 0;
+
+ /// 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() = 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) {}
};
class SimRadio : public RadioInterface
diff --git a/src/rf95/RadioLibInterface.cpp b/src/rf95/RadioLibInterface.cpp
new file mode 100644
index 000000000..b387a253e
--- /dev/null
+++ b/src/rf95/RadioLibInterface.cpp
@@ -0,0 +1,118 @@
+#include "RadioLibInterface.h"
+#include
+
+// FIXME, we default to 4MHz SPI, SPI mode 0, check if the datasheet says it can really do that
+static SPISettings spiSettings;
+
+RadioLibInterface::RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy,
+ SPIClass &spi)
+ : module(cs, irq, rst, busy, spi, spiSettings), lora(&module)
+{
+}
+
+ErrorCode RadioLibInterface::send(MeshPacket *p)
+{
+ return ERR_NONE;
+}
+
+/// Initialise the Driver transport hardware and software.
+/// Make sure the Driver is properly configured before calling init().
+/// \return true if initialisation succeeded.
+bool RadioLibInterface::init()
+{
+ // FIXME, move this to main
+ SPI.begin();
+
+ int res = lora.begin();
+ DEBUG_MSG("LORA init result %d\n", res);
+
+ return res == ERR_NONE;
+}
+
+/**
+ *
+ *
+ *
+// include the library
+
+
+// SX1262 has the following connections:
+// NSS pin: 10
+// DIO1 pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+SX1262 lora = new Module(10, 2, 3, 9);
+
+// or using RadioShield
+// https://github.com/jgromes/RadioShield
+//SX1262 lora = RadioShield.ModuleA;
+
+void setup() {
+ Serial.begin(9600);
+
+ // initialize SX1262 with default settings
+ Serial.print(F("[SX1262] Initializing ... "));
+ // carrier frequency: 434.0 MHz
+ // bandwidth: 125.0 kHz
+ // spreading factor: 9
+ // coding rate: 7
+ // sync word: 0x12 (private network)
+ // output power: 14 dBm
+ // current limit: 60 mA
+ // preamble length: 8 symbols
+ // TCXO voltage: 1.6 V (set to 0 to not use TCXO)
+ // regulator: DC-DC (set to true to use LDO)
+ // CRC: enabled
+ int state = lora.begin();
+ if (state == ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true);
+ }
+}
+
+void loop() {
+ Serial.print(F("[SX1262] Transmitting packet ... "));
+
+ // you can transmit C-string or Arduino string up to
+ // 256 characters long
+ // NOTE: transmit() is a blocking method!
+ // See example SX126x_Transmit_Interrupt for details
+ // on non-blocking transmission method.
+ int state = lora.transmit("Hello World!");
+
+ // you can also transmit byte array up to 256 bytes long
+
+ byte byteArr[] = {0x01, 0x23, 0x45, 0x56, 0x78, 0xAB, 0xCD, 0xEF};
+ int state = lora.transmit(byteArr, 8);
+
+
+if (state == ERR_NONE) {
+ // the packet was successfully transmitted
+ Serial.println(F("success!"));
+
+ // print measured data rate
+ Serial.print(F("[SX1262] Datarate:\t"));
+ Serial.print(lora.getDataRate());
+ Serial.println(F(" bps"));
+
+} else if (state == ERR_PACKET_TOO_LONG) {
+ // the supplied packet was longer than 256 bytes
+ Serial.println(F("too long!"));
+
+} else if (state == ERR_TX_TIMEOUT) {
+ // timeout occured while transmitting packet
+ Serial.println(F("timeout!"));
+
+} else {
+ // some other error occurred
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+}
+
+// wait for a second before transmitting again
+delay(1000);
+}
+ */
\ No newline at end of file
diff --git a/src/rf95/RadioLibInterface.h b/src/rf95/RadioLibInterface.h
new file mode 100644
index 000000000..a4ee06f9f
--- /dev/null
+++ b/src/rf95/RadioLibInterface.h
@@ -0,0 +1,82 @@
+#pragma once
+
+#include "RadioInterface.h"
+
+#include
+
+class RadioLibInterface : public RadioInterface
+{
+ Module module; // The HW interface to the radio
+ SX1262 lora;
+
+ public:
+ RadioLibInterface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy, SPIClass &spi);
+
+ virtual ErrorCode send(MeshPacket *p);
+
+ // methods from radiohead
+
+ /// Sets the address of this node. Defaults to 0xFF. Subclasses or the user may want to change this.
+ /// This will be used to test the adddress in incoming messages. In non-promiscuous mode,
+ /// only messages with a TO header the same as thisAddress or the broadcast addess (0xFF) will be accepted.
+ /// In promiscuous mode, all messages will be accepted regardless of the TO header.
+ /// In a conventional multinode system, all nodes will have a unique address
+ /// (which you could store in EEPROM).
+ /// You would normally set the header FROM address to be the same as thisAddress (though you dont have to,
+ /// allowing the possibilty of address spoofing).
+ /// \param[in] thisAddress The address of this node.
+ virtual void setThisAddress(uint8_t thisAddress) {}
+
+ /// 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();
+
+ /// 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) {}
+};
\ No newline at end of file
diff --git a/variants/pca10056-rc-clock/variant.h b/variants/pca10056-rc-clock/variant.h
index db5c71b67..b7201812a 100644
--- a/variants/pca10056-rc-clock/variant.h
+++ b/variants/pca10056-rc-clock/variant.h
@@ -142,6 +142,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
// 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 SX1262_ANT_SW (32 + 10) // P1.10