From 0cdd49ca11c135855d93f4b2c7ab13c370423ce6 Mon Sep 17 00:00:00 2001
From: jgromes <jan.gromes@gmail.com>
Date: Sun, 21 Feb 2021 16:54:38 +0100
Subject: [PATCH] [SX127x] Implemented implicit LoRa header (#181)

---
 src/modules/SX127x/SX1272.cpp | 27 +++++++++++++++++++++++++++
 src/modules/SX127x/SX1272.h   | 21 +++++++++++++++++++--
 src/modules/SX127x/SX1278.cpp | 28 ++++++++++++++++++++++++++++
 src/modules/SX127x/SX1278.h   | 21 +++++++++++++++++++--
 src/modules/SX127x/SX127x.cpp |  4 ++--
 src/modules/SX127x/SX127x.h   |  2 +-
 6 files changed, 96 insertions(+), 7 deletions(-)

diff --git a/src/modules/SX127x/SX1272.cpp b/src/modules/SX127x/SX1272.cpp
index 707f15e5..38c76c78 100644
--- a/src/modules/SX127x/SX1272.cpp
+++ b/src/modules/SX127x/SX1272.cpp
@@ -395,6 +395,13 @@ int16_t SX1272::autoLDRO() {
   return(ERR_NONE);
 }
 
+int16_t SX1272::implicitHeader(size_t len) {
+  return(setHeaderType(SX1272_HEADER_IMPL_MODE, len));
+}
+
+int16_t SX1272::explicitHeader() {
+  return(setHeaderType(SX1272_HEADER_EXPL_MODE));
+}
 
 int16_t SX1272::setBandwidthRaw(uint8_t newBandwidth) {
   // set mode to standby
@@ -433,6 +440,26 @@ int16_t SX1272::setCodingRateRaw(uint8_t newCodingRate) {
   return(state);
 }
 
+int16_t SX1272::setHeaderType(uint8_t headerType, size_t len) {
+  // check active modem
+  if(getActiveModem() != SX127X_LORA) {
+    return(ERR_WRONG_MODEM);
+  }
+
+  // set requested packet mode
+  int16_t state = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, headerType, 2, 2);
+  RADIOLIB_ASSERT(state);
+
+  // set length to register
+  state = _mod->SPIsetRegValue(SX127X_REG_PAYLOAD_LENGTH, len);
+  RADIOLIB_ASSERT(state);
+
+  // update cached value
+  _packetLength = len;
+
+  return(state);
+}
+
 int16_t SX1272::configFSK() {
   // configure common registers
   int16_t state = SX127x::configFSK();
diff --git a/src/modules/SX127x/SX1272.h b/src/modules/SX127x/SX1272.h
index 78e009d3..a74e91bc 100644
--- a/src/modules/SX127x/SX1272.h
+++ b/src/modules/SX127x/SX1272.h
@@ -27,7 +27,7 @@
 #define SX1272_FRF_MID                                0xC0        //  7     0         where F(XOSC) = 32 MHz
 #define SX1272_FRF_LSB                                0x00        //  7     0               FRF = 3 byte value of FRF registers
 
-// SX1272_REG_MODEM_CONFIG_1
+// SX127X_REG_MODEM_CONFIG_1
 #define SX1272_BW_125_00_KHZ                          0b00000000  //  7     6     bandwidth:  125 kHz
 #define SX1272_BW_250_00_KHZ                          0b01000000  //  7     6                 250 kHz
 #define SX1272_BW_500_00_KHZ                          0b10000000  //  7     6                 500 kHz
@@ -42,7 +42,7 @@
 #define SX1272_LOW_DATA_RATE_OPT_OFF                  0b00000000  //  0     0     low data rate optimization disabled
 #define SX1272_LOW_DATA_RATE_OPT_ON                   0b00000001  //  0     0     low data rate optimization enabled, mandatory for SF 11 and 12 with BW 125 kHz
 
-// SX1272_REG_MODEM_CONFIG_2
+// SX127X_REG_MODEM_CONFIG_2
 #define SX1272_AGC_AUTO_OFF                           0b00000000  //  2     2     LNA gain set by REG_LNA
 #define SX1272_AGC_AUTO_ON                            0b00000100  //  2     2     LNA gain set by internal AGC loop
 
@@ -271,12 +271,29 @@ class SX1272: public SX127x {
     */
     int16_t autoLDRO();
 
+    /*!
+      \brief Set implicit header mode for future reception/transmission.
+
+      \returns \ref status_codes
+    */
+    int16_t implicitHeader(size_t len);
+
+    /*!
+      \brief Set explicit header mode for future reception/transmission.
+
+      \param len Payload length in bytes.
+
+      \returns \ref status_codes
+    */
+    int16_t explicitHeader();
+
 #ifndef RADIOLIB_GODMODE
   protected:
 #endif
     int16_t setBandwidthRaw(uint8_t newBandwidth);
     int16_t setSpreadingFactorRaw(uint8_t newSpreadingFactor);
     int16_t setCodingRateRaw(uint8_t newCodingRate);
+    int16_t setHeaderType(uint8_t headerType, size_t len = 0xFF);
 
     int16_t configFSK();
 
diff --git a/src/modules/SX127x/SX1278.cpp b/src/modules/SX127x/SX1278.cpp
index 177c049f..f33af33a 100644
--- a/src/modules/SX127x/SX1278.cpp
+++ b/src/modules/SX127x/SX1278.cpp
@@ -473,6 +473,14 @@ int16_t SX1278::autoLDRO() {
   return(ERR_NONE);
 }
 
+int16_t SX1278::implicitHeader(size_t len) {
+  return(setHeaderType(SX1278_HEADER_IMPL_MODE, len));
+}
+
+int16_t SX1278::explicitHeader() {
+  return(setHeaderType(SX1278_HEADER_EXPL_MODE));
+}
+
 int16_t SX1278::setBandwidthRaw(uint8_t newBandwidth) {
   // set mode to standby
   int16_t state = SX127x::standby();
@@ -510,6 +518,26 @@ int16_t SX1278::setCodingRateRaw(uint8_t newCodingRate) {
   return(state);
 }
 
+int16_t SX1278::setHeaderType(uint8_t headerType, size_t len) {
+  // check active modem
+  if(getActiveModem() != SX127X_LORA) {
+    return(ERR_WRONG_MODEM);
+  }
+
+  // set requested packet mode
+  int16_t state = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, headerType, 0, 0);
+  RADIOLIB_ASSERT(state);
+
+  // set length to register
+  state = _mod->SPIsetRegValue(SX127X_REG_PAYLOAD_LENGTH, len);
+  RADIOLIB_ASSERT(state);
+
+  // update cached value
+  _packetLength = len;
+
+  return(state);
+}
+
 int16_t SX1278::configFSK() {
   // configure common registers
   int16_t state = SX127x::configFSK();
diff --git a/src/modules/SX127x/SX1278.h b/src/modules/SX127x/SX1278.h
index cba8c635..438a9c18 100644
--- a/src/modules/SX127x/SX1278.h
+++ b/src/modules/SX127x/SX1278.h
@@ -38,7 +38,7 @@
 // SX1278_REG_LNA
 #define SX1278_LNA_BOOST_LF_OFF                       0b00000000  //  4     3     default LNA current
 
-// SX1278_REG_MODEM_CONFIG_1
+// SX127X_REG_MODEM_CONFIG_1
 #define SX1278_BW_7_80_KHZ                            0b00000000  //  7     4     bandwidth:  7.80 kHz
 #define SX1278_BW_10_40_KHZ                           0b00010000  //  7     4                 10.40 kHz
 #define SX1278_BW_15_60_KHZ                           0b00100000  //  7     4                 15.60 kHz
@@ -56,7 +56,7 @@
 #define SX1278_HEADER_EXPL_MODE                       0b00000000  //  0     0     explicit header mode
 #define SX1278_HEADER_IMPL_MODE                       0b00000001  //  0     0     implicit header mode
 
-// SX1278_REG_MODEM_CONFIG_2
+// SX127X_REG_MODEM_CONFIG_2
 #define SX1278_RX_CRC_MODE_OFF                        0b00000000  //  2     2     CRC disabled
 #define SX1278_RX_CRC_MODE_ON                         0b00000100  //  2     2     CRC enabled
 
@@ -279,12 +279,29 @@ class SX1278: public SX127x {
     */
     int16_t autoLDRO();
 
+    /*!
+      \brief Set implicit header mode for future reception/transmission.
+
+      \returns \ref status_codes
+    */
+    int16_t implicitHeader(size_t len);
+
+    /*!
+      \brief Set explicit header mode for future reception/transmission.
+
+      \param len Payload length in bytes.
+
+      \returns \ref status_codes
+    */
+    int16_t explicitHeader();
+
 #ifndef RADIOLIB_GODMODE
   protected:
 #endif
     int16_t setBandwidthRaw(uint8_t newBandwidth);
     int16_t setSpreadingFactorRaw(uint8_t newSpreadingFactor);
     int16_t setCodingRateRaw(uint8_t newCodingRate);
+    int16_t setHeaderType(uint8_t headerType, size_t len = 0xFF);
 
     int16_t configFSK();
 
diff --git a/src/modules/SX127x/SX127x.cpp b/src/modules/SX127x/SX127x.cpp
index 40605c51..c57f4b56 100644
--- a/src/modules/SX127x/SX127x.cpp
+++ b/src/modules/SX127x/SX127x.cpp
@@ -879,8 +879,8 @@ size_t SX127x::getPacketLength(bool update) {
       return(_mod->SPIreadRegister(SX127X_REG_RX_NB_BYTES));
 
     } else {
-      // return the maximum value for SF6
-      return(SX127X_MAX_PACKET_LENGTH);
+      // return the cached value for SF6
+      return(_packetLength);
     }
 
   } else if(modem == SX127X_FSK_OOK) {
diff --git a/src/modules/SX127x/SX127x.h b/src/modules/SX127x/SX127x.h
index 98906354..831e49a4 100644
--- a/src/modules/SX127x/SX127x.h
+++ b/src/modules/SX127x/SX127x.h
@@ -958,6 +958,7 @@ class SX127x: public PhysicalLayer {
     float _rxBw = 0;
     bool _ook = false;
     bool _crcEnabled = false;
+    size_t _packetLength = 0;
 
     int16_t setFrequencyRaw(float newFreq);
     int16_t config();
@@ -970,7 +971,6 @@ class SX127x: public PhysicalLayer {
   private:
 #endif
     float _dataRate = 0;
-    size_t _packetLength = 0;
     bool _packetLengthQueried = false; // FSK packet length is the first byte in FIFO, length can only be queried once
     uint8_t _packetLengthConfig = SX127X_PACKET_VARIABLE;