From 069428a9f6ac94647b3e334fd3522ccbe56f45eb Mon Sep 17 00:00:00 2001
From: obones <obones@free.fr>
Date: Wed, 6 Jul 2022 15:29:27 +0200
Subject: [PATCH] Implement setDIOMapping for SX1278 family

---
 src/modules/SX127x/SX1278.cpp | 14 ++++++
 src/modules/SX127x/SX1278.h   | 81 +++++++++++++++++++++++++++++++++++
 2 files changed, 95 insertions(+)

diff --git a/src/modules/SX127x/SX1278.cpp b/src/modules/SX127x/SX1278.cpp
index 685fe175..94518c8e 100644
--- a/src/modules/SX127x/SX1278.cpp
+++ b/src/modules/SX127x/SX1278.cpp
@@ -471,6 +471,20 @@ int16_t SX1278::explicitHeader() {
   return(setHeaderType(RADIOLIB_SX1278_HEADER_EXPL_MODE));
 }
 
+int16_t SX1278::setDIOMapping(RADIOLIB_PIN_TYPE pin, uint8_t value) {
+  if (pin > 5)
+    return RADIOLIB_ERR_INVALID_DIO_PIN;
+
+  if (pin < 4)
+    return(_mod->SPIsetRegValue(RADIOLIB_SX1278_REG_DIO_MAPPING_1, value, 7 - 2 * pin, 6 - 2 * pin));
+  else
+    return(_mod->SPIsetRegValue(RADIOLIB_SX1278_REG_DIO_MAPPING_2, value, 15 - 2 * pin, 14 - 2 * pin));
+}
+
+int16_t SX1278::setDIOPreambleDetect(bool usePreambleDetect) {
+  return _mod->SPIsetRegValue(RADIOLIB_SX1278_REG_DIO_MAPPING_2, (usePreambleDetect) ? RADIOLIB_SX1278_DIO_MAP_PREAMBLE_DETECT : RADIOLIB_SX1278_DIO_MAP_RSSI, 0, 0);
+}
+
 int16_t SX1278::setBandwidthRaw(uint8_t newBandwidth) {
   // set mode to standby
   int16_t state = SX127x::standby();
diff --git a/src/modules/SX127x/SX1278.h b/src/modules/SX127x/SX1278.h
index cffedc81..8ebbfe0a 100644
--- a/src/modules/SX127x/SX1278.h
+++ b/src/modules/SX127x/SX1278.h
@@ -10,6 +10,8 @@
 
 // SX1278 specific register map
 #define RADIOLIB_SX1278_REG_MODEM_CONFIG_3                     0x26
+#define RADIOLIB_SX1278_REG_DIO_MAPPING_1                      0x40
+#define RADIOLIB_SX1278_REG_DIO_MAPPING_2                      0x41
 #define RADIOLIB_SX1278_REG_PLL_HOP                            0x44
 #define RADIOLIB_SX1278_REG_TCXO                               0x4B
 #define RADIOLIB_SX1278_REG_PA_DAC                             0x4D
@@ -95,6 +97,65 @@
 #define RADIOLIB_SX1278_AGC_STEP_4                             0xC0        //  7     4     4th AGC threshold
 #define RADIOLIB_SX1278_AGC_STEP_5                             0x0C        //  4     0     5th AGC threshold
 
+// SX1278_REG_DIO_MAPPING_1
+#define RADIOLIB_SX1278_DIO0_LORA_RX_DONE                        0b00000000  //  7     6
+#define RADIOLIB_SX1278_DIO0_LORA_TX_DONE                        0b01000000  //  7     6
+#define RADIOLIB_SX1278_DIO0_LORA_CAD_DONE                       0b10000000  //  7     6
+#define RADIOLIB_SX1278_DIO0_CONT_MODE_READY                     0b11000000  //  7     6
+#define RADIOLIB_SX1278_DIO0_CONT_SYNC_ADDRESS                   0b00000000  //  7     6
+#define RADIOLIB_SX1278_DIO0_CONT_RSSI_PREAMBLE_DETECT           0b01000000  //  7     6
+#define RADIOLIB_SX1278_DIO0_CONT_RX_READY                       0b10000000  //  7     6
+#define RADIOLIB_SX1278_DIO0_CONT_TX_READY                       0b00000000  //  7     6
+#define RADIOLIB_SX1278_DIO0_PACK_PAYLOAD_READY                  0b00000000  //  7     6
+#define RADIOLIB_SX1278_DIO0_PACK_PACKET_SENT                    0b00000000  //  7     6
+#define RADIOLIB_SX1278_DIO0_PACK_CRC_OK                         0b01000000  //  7     6
+#define RADIOLIB_SX1278_DIO0_PACK_TEMP_CHANGE_LOW_BAT            0b11000000  //  7     6
+#define RADIOLIB_SX1278_DIO1_LORA_RX_TIMEOUT                     0b00000000  //  5     4
+#define RADIOLIB_SX1278_DIO1_LORA_FHSS_CHANGE_CHANNEL            0b01000000  //  5     4
+#define RADIOLIB_SX1278_DIO1_LORA_CAD_DETECTED                   0b10000000  //  5     4
+#define RADIOLIB_SX1278_DIO1_CONT_DCLK                           0b00000000  //  5     4
+#define RADIOLIB_SX1278_DIO1_CONT_RSSI_PREAMBLE_DETECT           0b00010000  //  5     4
+#define RADIOLIB_SX1278_DIO1_PACK_FIFO_LEVEL                     0b00000000  //  5     4
+#define RADIOLIB_SX1278_DIO1_PACK_FIFO_EMPTY                     0b00010000  //  5     4
+#define RADIOLIB_SX1278_DIO1_PACK_FIFO_FULL                      0b00100000  //  5     4
+#define RADIOLIB_SX1278_DIO2_LORA_FHSS_CHANGE_CHANNEL            0b00000000  //  3     2
+#define RADIOLIB_SX1278_DIO2_CONT_DATA                           0b00000000  //  3     2
+#define RADIOLIB_SX1278_DIO2_PACK_FIFO_FULL                      0b00000000  //  3     2
+#define RADIOLIB_SX1278_DIO2_PACK_RX_READY                       0b00000100  //  3     2
+#define RADIOLIB_SX1278_DIO2_PACK_TIMEOUT                        0b00001000  //  3     2
+#define RADIOLIB_SX1278_DIO2_PACK_SYNC_ADDRESS                   0b00011000  //  3     2
+#define RADIOLIB_SX1278_DIO3_LORA_CAD_DONE                       0b00000000  //  0     1
+#define RADIOLIB_SX1278_DIO3_LORA_VALID_HEADER                   0b00000001  //  0     1
+#define RADIOLIB_SX1278_DIO3_LORA_PAYLOAD_CRC_ERROR              0b00000010  //  0     1
+#define RADIOLIB_SX1278_DIO3_CONT_TIMEOUT                        0b00000000  //  0     1
+#define RADIOLIB_SX1278_DIO3_CONT_RSSI_PREAMBLE_DETECT           0b00000001  //  0     1
+#define RADIOLIB_SX1278_DIO3_CONT_TEMP_CHANGE_LOW_BAT            0b00000011  //  0     1
+#define RADIOLIB_SX1278_DIO3_PACK_FIFO_EMPTY                     0b00000000  //  0     1
+#define RADIOLIB_SX1278_DIO3_PACK_TX_READY                       0b00000001  //  0     1
+
+// SX1278_REG_DIO_MAPPING_2
+#define RADIOLIB_SX1278_DIO4_LORA_CAD_DETECTED                   0b10000000  //  7     6
+#define RADIOLIB_SX1278_DIO4_LORA_PLL_LOCK                       0b01000000  //  7     6
+#define RADIOLIB_SX1278_DIO4_CONT_TEMP_CHANGE_LOW_BAT            0b00000000  //  7     6
+#define RADIOLIB_SX1278_DIO4_CONT_PLL_LOCK                       0b01000000  //  7     6
+#define RADIOLIB_SX1278_DIO4_CONT_TIMEOUT                        0b10000000  //  7     6
+#define RADIOLIB_SX1278_DIO4_CONT_MODE_READY                     0b11000000  //  7     6
+#define RADIOLIB_SX1278_DIO4_PACK_TEMP_CHANGE_LOW_BAT            0b00000000  //  7     6
+#define RADIOLIB_SX1278_DIO4_PACK_PLL_LOCK                       0b01000000  //  7     6
+#define RADIOLIB_SX1278_DIO4_PACK_TIMEOUT                        0b10000000  //  7     6
+#define RADIOLIB_SX1278_DIO4_PACK_RSSI_PREAMBLE_DETECT           0b11000000  //  7     6
+#define RADIOLIB_SX1278_DIO5_LORA_MODE_READY                     0b00000000  //  5     4
+#define RADIOLIB_SX1278_DIO5_LORA_CLK_OUT                        0b00010000  //  5     4
+#define RADIOLIB_SX1278_DIO5_CONT_CLK_OUT                        0b00000000  //  5     4
+#define RADIOLIB_SX1278_DIO5_CONT_PLL_LOCK                       0b00010000  //  5     4
+#define RADIOLIB_SX1278_DIO5_CONT_RSSI_PREAMBLE_DETECT           0b00100000  //  5     4
+#define RADIOLIB_SX1278_DIO5_CONT_MODE_READY                     0b00110000  //  5     4
+#define RADIOLIB_SX1278_DIO5_PACK_CLK_OUT                        0b00000000  //  5     4
+#define RADIOLIB_SX1278_DIO5_PACK_PLL_LOCK                       0b00010000  //  5     4
+#define RADIOLIB_SX1278_DIO5_PACK_DATA                           0b00100000  //  5     4
+#define RADIOLIB_SX1278_DIO5_PACK_MODE_READY                     0b00110000  //  5     4
+#define RADIOLIB_SX1278_DIO_MAP_PREAMBLE_DETECT                  0b00000001  //  0     0     
+#define RADIOLIB_SX1278_DIO_MAP_RSSI                             0b00000000  //  0     0     
 /*!
   \class SX1278
 
@@ -302,6 +363,26 @@ class SX1278: public SX127x {
     */
     int16_t explicitHeader();
 
+    /*!
+      \brief Configure DIO pin mapping to get a given signal on a DIO pin (if available).
+
+      \param pin Pin number onto which a signal is to be placed.
+
+      \param value The value that indicates which function to place on that pin. See chip datasheet for details.
+
+      \returns \ref status_codes
+    */
+    int16_t setDIOMapping(RADIOLIB_PIN_TYPE pin, uint8_t value);
+
+    /*!
+      \brief Configure DIO mapping to use RSSI or Preamble Detect for pins that support it.
+
+      \param usePreambleDetect Whether to use PreambleDetect (true) or RSSI (false) on the pins that are mapped to this function.
+
+      \returns \ref status_codes
+    */
+    int16_t setDIOPreambleDetect(bool usePreambleDetect);
+
 #if !defined(RADIOLIB_GODMODE)
   protected:
 #endif