diff --git a/src/shared/drivers/SX1278/SX1278.cpp b/src/shared/drivers/SX1278/SX1278.cpp
index 52a91f3ba06520aa4b18974468319a22256b6774..6a7f718f422a9a298e225da2f7773b5b76c14062 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 6fb4c355d36f81331e7299e6a291e58c737e4156..3d89a9f9494a95ddcae4871f84a8c21132571066 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 cd50d09a8c3294659f1c1186f2ad1fd0512937c6..f38059551c2ca51b04393263044abc0abc004715 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 5ddb67f00a8800f77f5597fa3c9538fb8496a6e5..3d46b9b4690516eb6d241ee56a62d0f07e5ffe6e 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