]> git.tnoah.ca Git - lora-radio.git/commitdiff
Added support for T3S3 SX1280
authorMark Qvist <mark@unsigned.io>
Fri, 3 Jan 2025 20:23:23 +0000 (21:23 +0100)
committerMark Qvist <mark@unsigned.io>
Fri, 3 Jan 2025 20:23:23 +0000 (21:23 +0100)
sx128x.cpp
sx128x.h

index eceee811114ff488eb1a9056d6b74a2019372fbd..c59752d87f9ace7cb9824a99e71b5904ae1e586c 100644 (file)
@@ -38,6 +38,7 @@
   #define ISR_VECT
 #endif
 
+// SX128x registers
 #define OP_RF_FREQ_8X               0x86
 #define OP_SLEEP_8X                 0x84
 #define OP_STANDBY_8X               0x80
@@ -111,34 +112,52 @@ sx128x::sx128x() :
   setTimeout(0);
 }
 
-void ISR_VECT sx128x::onDio0Rise() { sx128x_modem.handleDio0Rise(); }
-void sx128x::handleDio0Rise() {
+bool ISR_VECT sx128x::getPacketValidity() {
     uint8_t buf[2];
 
     buf[0] = 0x00;
     buf[1] = 0x00;
 
     executeOpcodeRead(OP_GET_IRQ_STATUS_8X, buf, 2);
+
     executeOpcode(OP_CLEAR_IRQ_STATUS_8X, buf, 2);
+
     if ((buf[1] & IRQ_PAYLOAD_CRC_ERROR_MASK_8X) == 0) {
-        // received a packet
-        _packetIndex = 0;
+        return true;
+    } else {
+        return false;
+    }
+}
 
-        uint8_t rxbuf[2] = {0};
-        executeOpcodeRead(OP_RX_BUFFER_STATUS_8X, rxbuf, 2);
+void ISR_VECT sx128x::onDio0Rise() {
+    BaseType_t int_status = taskENTER_CRITICAL_FROM_ISR();
+    if (sx128x_modem.getPacketValidity()) { sx128x_modem.handleDio0Rise(); }
+    // On the SX1280, there is a bug which can cause the busy line
+    // to remain high if a high amount of packets are received when
+    // in continuous RX mode. This is documented as Errata 16.1 in
+    // the SX1280 datasheet v3.2 (page 149)
+    // Therefore, the modem is set into receive mode each time a packet is received.
+    sx128x_modem.receive();
+    taskEXIT_CRITICAL_FROM_ISR(int_status);
+}
 
-        _rxPacketLength = rxbuf[0];
-        _fifo_rx_addr_ptr = rxbuf[1];
-        readBuffer(_packet, _rxPacketLength);
+void sx128x::handleDio0Rise() {
+    // received a packet
+    _packetIndex = 0;
 
-        // On the SX1280, there is a bug which can cause the busy line
-        // to remain high if a high amount of packets are received when
-        // in continuous RX mode. This is documented as Errata 16.1 in
-        // the SX1280 datasheet v3.2 (page 149)
-        // Therefore, the modem is set into receive mode each time a packet is received.
-        receive(0);
+    uint8_t rxbuf[2] = {0};
+    executeOpcodeRead(OP_RX_BUFFER_STATUS_8X, rxbuf, 2);
+
+    // If implicit header mode is enabled, read packet length as payload length instead.
+    // See SX1280 datasheet v3.2, page 92
+    if (_implicitHeaderMode == 0x80) {
+        _rxPacketLength = _payloadLength;
+    } else {
+        _rxPacketLength = rxbuf[0];
+    }
 
-        if (_onReceive) { _onReceive(_rxPacketLength); }
+    if (_onReceive) {
+        _onReceive(_rxPacketLength);
     }
 }
 
@@ -209,14 +228,24 @@ uint8_t ISR_VECT sx128x::singleTransfer(uint8_t opcode, uint16_t address, uint8_
     return response;
 }
 
-void sx128x::rxAntEnable() {
-    if (_txen != -1) { digitalWrite(_txen, LOW); }
-    if (_rxen != -1) { digitalWrite(_rxen, HIGH); }
+void sx128x::rxAntEnable()
+{
+    if (_txen != -1) {
+        digitalWrite(_txen, LOW);
+    }
+    if (_rxen != -1) {
+        digitalWrite(_rxen, HIGH);
+    }
 }
 
-void sx128x::txAntEnable() {
-    if (_txen != -1) { digitalWrite(_txen, HIGH); }
-    if (_rxen != -1) { digitalWrite(_rxen, LOW); }
+void sx128x::txAntEnable()
+{
+    if (_txen != -1) {
+        digitalWrite(_txen, HIGH);
+    }
+    if (_rxen != -1) {
+        digitalWrite(_rxen, LOW);
+    }
 }
 
 void sx128x::loraMode() {
@@ -341,29 +370,23 @@ void sx128x::setPacketParams(uint32_t preamble, uint8_t headermode, uint8_t leng
   // because there is no access to these registers on the sx1280, we have
   // to set all these parameters at once or not at all.
   uint8_t buf[7];
-
   // calculate exponent and mantissa values for modem
-  // uint8_t e = 1;
-  // uint8_t m = 1;
-  // uint32_t preamblelen;
-
-  // while (e <= 15) {
-  //     while (m <= 15) {
-  //         preamblelen = m * (pow(2,e));
-  //         if (preamblelen >= preamble) break;
-  //         m++;
-  //     }
-  //     if (preamblelen >= preamble) break;
-  //     m = 0;
-  //     e++;
-  // }
-
-  // Serial.printf("Calculated preamble: %d\r\n", preamblelen);
-  // Serial.printf("Reg value: %d\r\n", (e << 4) | m);
-
-  // TODO: Remove / clean
-  //buf[0] = (e << 4) | m;
-  buf[0] = 0x1C;
+  uint8_t e = 1;
+  uint8_t m = 1;
+  uint32_t preamblelen;
+
+  while (e <= 15) {
+      while (m <= 15) {
+          preamblelen = m * (pow(2,e));
+          if (preamblelen >= preamble) break;
+          m++;
+      }
+      if (preamblelen >= preamble) break;
+      m = 0;
+      e++;
+  }
+
+  buf[0] = (e << 4) | m;
   buf[1] = headermode;
   buf[2] = length;
   buf[3] = crc;
@@ -402,7 +425,9 @@ int sx128x::begin(unsigned long frequency)
   loraMode();
   rxAntEnable();
 
-  setFrequency(_frequency);
+  Serial.printf("Setting freq to %d\r\n", _frequency);
+  Serial.printf("Should be %d\r\n", frequency);
+  setFrequency(frequency);
 
   // set LNA boost
   // todo: implement this
@@ -537,14 +562,6 @@ uint8_t sx128x::packetRssiRaw() {
     return buf[0];
 }
 
-int ISR_VECT sx128x::packetRssi() {
-    // may need more calculations here
-    uint8_t buf[5] = {0};
-    executeOpcodeRead(OP_PACKET_STATUS_8X, buf, 5);
-    int pkt_rssi = -buf[0] / 2;
-    return pkt_rssi;
-}
-
 int ISR_VECT sx128x::packetRssi(uint8_t pkt_snr_raw) {
     // may need more calculations here
     uint8_t buf[5] = {0};
@@ -561,7 +578,7 @@ uint8_t ISR_VECT sx128x::packetSnrRaw() {
 
 float ISR_VECT sx128x::packetSnr() {
     uint8_t buf[5] = {0};
-    executeOpcodeRead(OP_PACKET_STATUS_8X, buf, 3);
+    executeOpcodeRead(OP_PACKET_STATUS_8X, buf, 5);
     return float(buf[1]) * 0.25;
 }
 
@@ -590,17 +607,41 @@ size_t sx128x::write(const uint8_t *buffer, size_t size)
   return size;
 }
 
-int ISR_VECT sx128x::available() { return _rxPacketLength - _packetIndex; }
+int ISR_VECT sx128x::available()
+{
+    return _rxPacketLength - _packetIndex;
+}
 
 int ISR_VECT sx128x::read()
 {
-  if (!available()) {
-    return -1;
-  }
+    if (!available()) {
+        return -1;
+    }
+
+    // if received new packet
+    if (_packetIndex == 0) {
+        uint8_t rxbuf[2] = {0};
+        executeOpcodeRead(OP_RX_BUFFER_STATUS_8X, rxbuf, 2);
+        int size;
+        // If implicit header mode is enabled, read packet length as payload length instead.
+        // See SX1280 datasheet v3.2, page 92
+        if (_implicitHeaderMode == 0x80) {
+            size = _payloadLength;
+        } else {
+            size = rxbuf[0];
+        }
+        _fifo_rx_addr_ptr = rxbuf[1];
 
-  uint8_t byte = _packet[_packetIndex];
-  _packetIndex++;
-  return byte;
+        if (size > 255) {
+            size = 255;
+        }
+
+        readBuffer(_packet, size);
+    }
+
+    uint8_t byte = _packet[_packetIndex];
+    _packetIndex++;
+    return byte;
 }
 
 int sx128x::peek()
@@ -650,10 +691,9 @@ void sx128x::onReceive(void(*callback)(int)) {
     executeOpcode(OP_SET_IRQ_FLAGS_8X, buf, 8);
 
     #ifdef SPI_HAS_NOTUSINGINTERRUPT
-      _spiModem->usingInterrupt(digitalPinToInterrupt(_dio0));
+        SPI.usingInterrupt(digitalPinToInterrupt(_dio0));
     #endif
 
-    // extern void onDio0Rise();
     attachInterrupt(digitalPinToInterrupt(_dio0), onDio0Rise, RISING);
 
   } else {
@@ -679,13 +719,13 @@ void sx128x::receive(int size)
 
   rxAntEnable();
 
-  // On the SX1280, there is a bug which can cause the busy line
-  // to remain high if a high amount of packets are received when
-  // in continuous RX mode. This is documented as Errata 16.1 in
-  // the SX1280 datasheet v3.2 (page 149)
-  // Therefore, the modem is set to single RX mode below instead.
-  uint8_t mode[3] = {0}; // single RX mode
-  executeOpcode(OP_RX_8X, mode, 3);
+    // On the SX1280, there is a bug which can cause the busy line
+    // to remain high if a high amount of packets are received when
+    // in continuous RX mode. This is documented as Errata 16.1 in
+    // the SX1280 datasheet v3.2 (page 149)
+    // Therefore, the modem is set to single RX mode below instead.
+    uint8_t mode[3] = {0}; // single RX mode
+    executeOpcode(OP_RX_8X, mode, 3);
 }
 
 void sx128x::standby()
@@ -726,7 +766,7 @@ void sx128x::setPins(int ss, int reset, int dio0, int busy, int rxen, int txen)
 
 void sx128x::setTxPower(int level, int outputPin) {
     uint8_t tx_buf[2];
-    #if BOARD_VARIANT == MODEL_13
+    #if BOARD_VARIANT == MODEL_13 || BOARD_VARIANT == MODEL_21
     // RAK4631 with WisBlock SX1280 module (LIBSYS002)
     if (level > 27) {
         level = 27;
@@ -743,73 +783,73 @@ void sx128x::setTxPower(int level, int outputPin) {
             reg_value = -18;
             break;
         case 1:
-            reg_value = -17;
+            reg_value = -16;
             break;
         case 2:
-            reg_value = -16;
+            reg_value = -15;
             break;
         case 3:
-            reg_value = -15;
+            reg_value = -14;
             break;
         case 4:
-            reg_value = -14;
+            reg_value = -13;
             break;
         case 5:
-            reg_value = -13;
+            reg_value = -12;
             break;
         case 6:
-            reg_value = -12;
+            reg_value = -11;
             break;
         case 7:
-            reg_value = -10;
+            reg_value = -9;
             break;
         case 8:
-            reg_value = -9;
+            reg_value = -8;
             break;
         case 9:
-            reg_value = -8;
+            reg_value = -7;
             break;
         case 10:
-            reg_value = -7;
+            reg_value = -6;
             break;
         case 11:
-            reg_value = -6;
+            reg_value = -5;
             break;
         case 12:
-            reg_value = -5;
+            reg_value = -4;
             break;
         case 13:
-            reg_value = -4;
+            reg_value = -3;
             break;
         case 14:
-            reg_value = -3;
+            reg_value = -2;
             break;
         case 15:
-            reg_value = -2;
+            reg_value = -1;
             break;
         case 16:
-            reg_value = -1;
+            reg_value = 0;
             break;
         case 17:
-            reg_value = 0;
+            reg_value = 1;
             break;
         case 18:
-            reg_value = 1;
+            reg_value = 2;
             break;
         case 19:
-            reg_value = 2;
+            reg_value = 3;
             break;
         case 20:
-            reg_value = 3;
+            reg_value = 4;
             break;
         case 21:
-            reg_value = 4;
+            reg_value = 5;
             break;
         case 22:
-            reg_value = 5;
+            reg_value = 6;
             break;
         case 23:
-            reg_value = 6;
+            reg_value = 7;
             break;
         case 24:
             reg_value = 8;
@@ -828,103 +868,103 @@ void sx128x::setTxPower(int level, int outputPin) {
             break;
     }
 
-    tx_buf[0] = reg_value;
+    tx_buf[0] = reg_value + 18;
     tx_buf[1] = 0xE0; // ramping time - 20 microseconds
 
     executeOpcode(OP_TX_PARAMS_8X, tx_buf, 2);
-    
+
+    #elif BOARD_VARIANT == MODEL_AC
     // T3S3 SX1280 PA
-    #elif BOARD_VARIANT == MODEL_AB
-        if (level > 20) { level = 20; }
-        else if (level < 0) { level = 0; }
-
-        _txp = level;
-        int reg_value;
-
-        switch (level) {
-            /*case 0:
-                reg_value = -18;
-                break;
-            case 1:
-                reg_value = -17;
-                break;
-            case 2:
-                reg_value = -16;
-                break;
-            case 3:
-                reg_value = -15;
-                break;
-            case 4:
-                reg_value = -14;
-                break;
-            case 5:
-                reg_value = -13;
-                break;
-            case 6:
-                reg_value = -12;
-                break;
-            case 7:
-                reg_value = -10;
-                break;
-            case 8:
-                reg_value = -9;
-                break;
-            case 9:
-                reg_value = -8;
-                break;
-            case 10:
-                reg_value = -7;
-                break;
-            case 11:
-                reg_value = -6;
-                break;
-            case 12:
-                reg_value = -5;
-                break;
-            case 13:
-                reg_value = -4;
-                break;
-            case 14:
-                reg_value = -3;
-                break;
-            case 15:
-                reg_value = -2;
-                break;
-            case 16:
-                reg_value = -1;
-                break;
-            case 17:
-                reg_value = 0;
-                break;
-            case 18:
-                reg_value = 1;
-                break;
-            case 19:
-                reg_value = 2;
-                break;*/
-            case 20:
-                reg_value = 3;
-                break;
-            default:
-                reg_value = 0;
-                break;
-        }
+      if (level > 20) { level = 20; }
+      else if (level < 0) { level = 0; }
+
+      _txp = level;
+
+      int reg_value;
+
+      switch (level) {
+          /*case 0:
+              reg_value = -18;
+              break;
+          case 1:
+              reg_value = -17;
+              break;
+          case 2:
+              reg_value = -16;
+              break;
+          case 3:
+              reg_value = -15;
+              break;
+          case 4:
+              reg_value = -14;
+              break;
+          case 5:
+              reg_value = -13;
+              break;
+          case 6:
+              reg_value = -12;
+              break;
+          case 7:
+              reg_value = -10;
+              break;
+          case 8:
+              reg_value = -9;
+              break;
+          case 9:
+              reg_value = -8;
+              break;
+          case 10:
+              reg_value = -7;
+              break;
+          case 11:
+              reg_value = -6;
+              break;
+          case 12:
+              reg_value = -5;
+              break;
+          case 13:
+              reg_value = -4;
+              break;
+          case 14:
+              reg_value = -3;
+              break;
+          case 15:
+              reg_value = -2;
+              break;
+          case 16:
+              reg_value = -1;
+              break;
+          case 17:
+              reg_value = 0;
+              break;
+          case 18:
+              reg_value = 1;
+              break;
+          case 19:
+              reg_value = 2;
+              break;*/
+          case 20:
+              reg_value = 3;
+              break;
+          default:
+              reg_value = 0;
+              break;
+      }
 
-        tx_buf[0] = reg_value;
-        tx_buf[1] = 0xE0; // ramping time - 20 microseconds
-    
-    // For SX1280 boards with no specific PA requirements
+      tx_buf[0] = reg_value;
+      tx_buf[1] = 0xE0; // ramping time - 20 microseconds
     #else
-        if (level > 13) {
-            level = 13;
-        } else if (level < -18) {
-            level = -18;
-        }
+    // For SX1280 boards with no specific PA requirements
+      if (level > 13) {
+          level = 13;
+      } else if (level < -18) {
+          level = -18;
+      }
 
-        _txp = level;
+      _txp = level;
 
-        tx_buf[0] = level;
-        tx_buf[1] = 0xE0; // ramping time - 20 microseconds
+      tx_buf[0] = level + 18;
+      tx_buf[1] = 0xE0; // ramping time - 20 microseconds
     #endif
     executeOpcode(OP_TX_PARAMS_8X, tx_buf, 2);
 }
@@ -977,13 +1017,16 @@ uint32_t sx128x::getSignalBandwidth() {
   return 0;
 }
 
-// todo: do i need this??
-void sx128x::handleLowDataRate() { }
+void sx128x::handleLowDataRate(){
+    // todo: do i need this??
+}
 
-// todo: check if there's anything the sx1280 can do here
-void sx128x::optimizeModemSensitivity() { }
+void sx128x::optimizeModemSensitivity(){
+    // todo: check if there's anything the sx1280 can do here
+}
 
-void sx128x::setSignalBandwidth(uint32_t sbw) {
+void sx128x::setSignalBandwidth(uint32_t sbw)
+{
       if (sbw <= 203.125E3) {
           _bw = 0x34;
       } else if (sbw <= 406.25E3) {
@@ -1018,9 +1061,13 @@ void sx128x::setCodingRate4(int denominator)
   setModulationParams(_sf, _bw, _cr);
 }
 
-uint8_t sx128x::getCodingRate4() { return _cr + 4; }
+uint8_t sx128x::getCodingRate4()
+{
+    return _cr + 4;
+}
 
-void sx128x::setPreambleLength(long length) {
+void sx128x::setPreambleLength(long length)
+{
   _preambleLength = length;
   setPacketParams(length, _implicitHeaderMode, _payloadLength, _crcMode);
 }
@@ -1030,21 +1077,21 @@ void sx128x::setSyncWord(int sw)
     // not implemented
 }
 
-void sx128x::enableCrc()
-{
+void sx128x::enableCrc() {
       _crcMode = 0x20;
       setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode);
 }
 
-void sx128x::disableCrc()
-{
+void sx128x::disableCrc() {
     _crcMode = 0;
     setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode);
 }
 
-byte sx128x::random()
-{
+uint8_t sx128x::random() {
     // todo: implement
+    return 0x4; //chosen  by fair die roll
+                //guarenteed to be random
+                //https://xkcd.com/221/
 }
 
 void sx128x::setSPIFrequency(uint32_t frequency)
@@ -1075,15 +1122,4 @@ void sx128x::implicitHeaderMode()
     setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode);
 }
 
-void sx128x::clearIRQStatus() {
-    uint8_t buf[2];
-
-    buf[0] = 0x00;
-    buf[1] = 0x00;
-
-    executeOpcodeRead(OP_GET_IRQ_STATUS_8X, buf, 2);
-
-    executeOpcode(OP_CLEAR_IRQ_STATUS_8X, buf, 2);
-}
-
 sx128x sx128x_modem;
\ No newline at end of file
index 93f287fc88377d77ec950c5e2e8a0da3bd1ff3f7..0652c9112ecdb90d8c75e0e4d00916467008d8b1 100644 (file)
--- a/sx128x.h
+++ b/sx128x.h
@@ -106,6 +106,7 @@ private:
   void explicitHeaderMode();
   void implicitHeaderMode();
 
+  bool getPacketValidity();
   void handleDio0Rise();
 
   uint8_t readRegister(uint16_t address);