From 9c44aac3101e0d84ff2561cccd41dcffc8d643f5 Mon Sep 17 00:00:00 2001
From: Davide Mor <davide.mor@skywarder.eu>
Date: Fri, 11 Mar 2022 22:51:01 +0100
Subject: [PATCH] [parafoil-test] Hackily implemented support for packets >
 64bytes

---
 src/shared/drivers/SX1278/SX1278.cpp          | 54 ++++++++++++++-----
 src/shared/drivers/SX1278/SX1278.h            |  3 ++
 src/shared/drivers/SX1278/SX1278Defs.h        |  5 ++
 .../drivers/sx1278/test-sx1278-bench.cpp      | 12 ++---
 4 files changed, 51 insertions(+), 23 deletions(-)

diff --git a/src/shared/drivers/SX1278/SX1278.cpp b/src/shared/drivers/SX1278/SX1278.cpp
index 52a91f3ba..6a7f718f4 100644
--- a/src/shared/drivers/SX1278/SX1278.cpp
+++ b/src/shared/drivers/SX1278/SX1278.cpp
@@ -31,6 +31,8 @@ namespace Boardcore
 
 using namespace SX1278Defs;
 
+long long now() { return miosix::getTick() * 1000 / miosix::TICK_FREQ; }
+
 // Default values for registers
 constexpr uint8_t REG_OP_MODE_DEFAULT = RegOpMode::LONG_RANGE_MODE_FSK |
                                         RegOpMode::MODULATION_TYPE_FSK |
@@ -247,31 +249,55 @@ ssize_t SX1278::receive(uint8_t *pkt, size_t max_len)
 
 bool SX1278::send(uint8_t *pkt, size_t len)
 {
-    // Packets longer than 255 are not supported
-    if (len > 255)
-        return false;
+    // Hacked together larger packets support
+    while (len > 0)
+    {
+        // This shouldn't be needed, but for some reason the device "lies" about
+        // being ready, so lock up if we are going too fast
+        rateLimitTx();
 
-    bus_mgr.lock(SX1278BusManager::Mode::MODE_TX);
+        bus_mgr.lock(SX1278BusManager::Mode::MODE_TX);
 
-    // Wait for TX ready
-    bus_mgr.waitForIrq(RegIrqFlags::TX_READY);
+        // Wait for TX ready
+        bus_mgr.waitForIrq(RegIrqFlags::TX_READY);
 
-    {
-        SPITransaction spi(bus_mgr.getBus(),
-                           SPITransaction::WriteBit::INVERTED);
+        // Segment a packet that is bigger than the MTU (-1 for the length)
+        uint8_t pkt_len = std::min(len, FIFO_LEN - 1);
+
+        {
+            SPITransaction spi(bus_mgr.getBus(),
+                               SPITransaction::WriteBit::INVERTED);
+
+            spi.writeRegister(REG_FIFO, pkt_len);
+            spi.writeRegisters(REG_FIFO, pkt, pkt_len);
+        }
+
+        // Wait for packet sent
+        bus_mgr.waitForIrq(RegIrqFlags::PACKET_SENT);
+
+        pkt += pkt_len;
+        len -= pkt_len;
+        bus_mgr.unlock();
 
-        spi.writeRegister(REG_FIFO, static_cast<uint8_t>(len));
-        spi.writeRegisters(REG_FIFO, pkt, len);
+        last_tx = now();
     }
 
-    // Wait for packet sent
-    bus_mgr.waitForIrq(RegIrqFlags::PACKET_SENT);
-    bus_mgr.unlock();
     return true;
 }
 
 void SX1278::handleDioIRQ() { bus_mgr.handleDioIRQ(); }
 
+void SX1278::rateLimitTx()
+{
+    const long long RATE_LIMIT = 2;
+
+    long long delta = now() - last_tx;
+    if (delta <= RATE_LIMIT)
+    {
+        miosix::Thread::sleep(RATE_LIMIT - delta);
+    }
+}
+
 uint8_t SX1278::getVersion()
 {
     SPITransaction spi(bus_mgr.getBus(), SPITransaction::WriteBit::INVERTED);
diff --git a/src/shared/drivers/SX1278/SX1278.h b/src/shared/drivers/SX1278/SX1278.h
index 6fb4c355d..3d89a9f94 100644
--- a/src/shared/drivers/SX1278/SX1278.h
+++ b/src/shared/drivers/SX1278/SX1278.h
@@ -228,6 +228,8 @@ public:
 public:
     using Mode = SX1278BusManager::Mode;
 
+    void rateLimitTx();
+
     void setBitrate(int bitrate);
     void setFreqDev(int freq_dev);
     void setFreqRF(int freq_rf);
@@ -240,6 +242,7 @@ public:
 
     void waitForIrq(uint16_t mask);
 
+    long long last_tx = 0;
     SX1278BusManager bus_mgr;
     PrintLogger logger = Logging::getLogger("sx1278");
 };
diff --git a/src/shared/drivers/SX1278/SX1278Defs.h b/src/shared/drivers/SX1278/SX1278Defs.h
index cd50d09a8..f38059551 100644
--- a/src/shared/drivers/SX1278/SX1278Defs.h
+++ b/src/shared/drivers/SX1278/SX1278Defs.h
@@ -33,6 +33,11 @@ namespace Boardcore
 namespace SX1278Defs
 {
 
+/**
+ * @brief Length of the fifo.
+ */
+constexpr size_t FIFO_LEN = 64;
+
 /**
  * @brief Main oscillator frequency (Hz)
  */
diff --git a/src/tests/drivers/sx1278/test-sx1278-bench.cpp b/src/tests/drivers/sx1278/test-sx1278-bench.cpp
index 5ddb67f00..3d46b9b46 100644
--- a/src/tests/drivers/sx1278/test-sx1278-bench.cpp
+++ b/src/tests/drivers/sx1278/test-sx1278-bench.cpp
@@ -93,9 +93,6 @@ struct Stats
 
 } stats;
 
-/// Interval between transmissions.
-const int TX_INTERVAL = 1;
-
 SX1278 *sx1278[2] = {nullptr, nullptr};
 
 struct Msg
@@ -115,12 +112,10 @@ void recvLoop(int idx)
     while (1)
     {
         Msg msg;
-        msg.idx     = 0;
-        msg.dummy_1 = 0;
-        msg.dummy_2 = 0;
-        msg.dummy_3 = 0;
+        memset(&msg, 0, sizeof(msg));
 
         int len = sx1278[idx]->receive((uint8_t *)&msg, sizeof(msg));
+
         if (len != sizeof(msg))
         {
             stats.recv_errors++;
@@ -143,8 +138,6 @@ void sendLoop(int idx)
 {
     while (1)
     {
-        miosix::Thread::sleep(TX_INTERVAL);
-
         int next_idx = stats.send_count + 1;
 
         Msg msg;
@@ -269,6 +262,7 @@ int main()
     std::thread recv([]() { recvLoop(0); });
 #endif
 #ifndef DISABLE_TX
+    miosix::Thread::sleep(500);
     std::thread send([]() { sendLoop(1); });
 #endif
 
-- 
GitLab