From 9da23db59c80b9e9019cabe326d584ca7c64e9de Mon Sep 17 00:00:00 2001
From: jgromes <jan.gromes@gmail.com>
Date: Mon, 14 Jun 2021 21:00:54 +0200
Subject: [PATCH] [SX127x] Added support for direct reception

---
 .../SX127x_Receive_Direct.ino                 | 80 +++++++++++++++++++
 src/modules/SX127x/SX127x.cpp                 |  8 ++
 src/modules/SX127x/SX127x.h                   | 14 ++++
 3 files changed, 102 insertions(+)
 create mode 100644 examples/SX127x/SX127x_Receive_Direct/SX127x_Receive_Direct.ino

diff --git a/examples/SX127x/SX127x_Receive_Direct/SX127x_Receive_Direct.ino b/examples/SX127x/SX127x_Receive_Direct/SX127x_Receive_Direct.ino
new file mode 100644
index 00000000..439dc1bd
--- /dev/null
+++ b/examples/SX127x/SX127x_Receive_Direct/SX127x_Receive_Direct.ino
@@ -0,0 +1,80 @@
+/*
+   RadioLib SX127x Direct Receive Example
+
+   This example shows how to receive FSK packets without using
+   SX127x packet engine.
+
+   For default module settings, see the wiki page
+   https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
+
+   For full API reference, see the GitHub Pages
+   https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include <RadioLib.h>
+
+// SX1278 has the following connections:
+// NSS pin:   10
+// DIO0 pin:  2
+// RESET pin: 9
+// DIO1 pin:  3
+SX1278 radio = new Module(10, 2, 9, 3);
+
+// DIO2 pin:  5
+const int pin = 5;
+
+// or using RadioShield
+// https://github.com/jgromes/RadioShield
+//SX1278 radio = RadioShield.ModuleA;
+
+void setup() {
+  Serial.begin(9600);
+
+  // initialize SX1278 with FSK modem at 9600 bps
+  Serial.print(F("[SX1278] Initializing ... "));
+  int state = radio.beginFSK(434.0, 9.6, 20.0);
+  if (state == ERR_NONE) {
+    Serial.println(F("success!"));
+  } else {
+    Serial.print(F("failed, code "));
+    Serial.println(state);
+    while (true);
+  }
+
+  // set the direct mode sync word
+  // the default RadioLib FSK sync word is 0x12AD
+  // we can add in some preamble bits, to lower the chance
+  // of false detection
+  radio.setDirectSyncWord(0x555512AD, 32);
+
+  // set function that will be called each time a bit is received
+  radio.setDirectAction(readBit);
+
+  // start direct mode reception
+  radio.receiveDirect();
+}
+
+// this function is called when a new bit is received
+void readBit(void) {
+  // read the data bit
+  radio.readBit(pin);
+}
+
+void loop() {
+  // we expect the packet to contain the string "Hello World!",
+  // a length byte and 2 CRC bytes, that's 15 bytes in total
+  if(radio.available() >= 15) {
+    Serial.println("[SX1278] Received packet in direct mode!");
+    while(radio.available()) {
+      // read a byte
+      byte b = radio.read();
+  
+      // print it
+      Serial.print(b, HEX);
+      Serial.print('\t');
+      Serial.write(b);
+      Serial.println();
+    }
+  }
+}
diff --git a/src/modules/SX127x/SX127x.cpp b/src/modules/SX127x/SX127x.cpp
index 160ce048..638f1562 100644
--- a/src/modules/SX127x/SX127x.cpp
+++ b/src/modules/SX127x/SX127x.cpp
@@ -1296,4 +1296,12 @@ int16_t SX127x::invertIQ(bool invertIQ) {
   return(state);
 }
 
+void SX127x::setDirectAction(void (*func)(void)) {
+  setDio1Action(func);
+}
+
+void SX127x::readBit(uint8_t pin) {
+  updateDirectBuffer((uint8_t)digitalRead(pin));
+}
+
 #endif
diff --git a/src/modules/SX127x/SX127x.h b/src/modules/SX127x/SX127x.h
index 6ffcb6b9..68d4605d 100644
--- a/src/modules/SX127x/SX127x.h
+++ b/src/modules/SX127x/SX127x.h
@@ -1026,6 +1026,20 @@ class SX127x: public PhysicalLayer {
     */
     int16_t invertIQ(bool invertIQ);
 
+    /*!
+      \brief Set interrupt service routine function to call when data bit is receveid in direct mode.
+
+      \param func Pointer to interrupt service routine.
+    */
+    void setDirectAction(void (*func)(void));
+
+    /*!
+      \brief Function to read and process data bit in direct reception mode.
+
+      \param pin Pin on which to read.
+    */
+    void readBit(uint8_t pin);
+
 #if !defined(RADIOLIB_GODMODE) && !defined(RADIOLIB_LOW_LEVEL)
   protected:
 #endif