From 6aea10c8c5b67e1bd66deb45172612ecafacc1c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=B2=20Caruso?= <niccolo.caruso@skywarder.eu>
Date: Sat, 8 Feb 2025 11:25:42 +0100
Subject: [PATCH] [Wiz5500] Wiz5500 fixes for timeout

The timeout was not considered in all the necessary part. In fact, waitForSocketIrq was not using it in the runInterruptServiceRoutine.
While running the ISR the timeout was not considered but only the hard-limit timeout was taken into consideration.
This is now changed, therefore now while running the ISR routine, the minimum between the custom timeout and the HARD limit is used.
---
 src/shared/drivers/WIZ5500/WIZ5500.cpp | 34 ++++++++++++++++++--------
 src/shared/drivers/WIZ5500/WIZ5500.h   |  5 ++--
 2 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/src/shared/drivers/WIZ5500/WIZ5500.cpp b/src/shared/drivers/WIZ5500/WIZ5500.cpp
index 9af411fdd..721d0fa13 100644
--- a/src/shared/drivers/WIZ5500/WIZ5500.cpp
+++ b/src/shared/drivers/WIZ5500/WIZ5500.cpp
@@ -407,18 +407,14 @@ void Wiz5500::close(int sock_n, int timeout)
     socket_infos[sock_n].mode = Wiz5500::SocketMode::CLOSED;
 }
 
-void Wiz5500::waitForINTn(Lock<FastMutex>& l)
+void Wiz5500::waitForINTn(Lock<FastMutex>& l, long long until)
 {
-    long long start        = Kernel::getOldTick();
     TimedWaitResult result = TimedWaitResult::NoTimeout;
 
     Unlock<FastMutex> ul(l);
     FastInterruptDisableLock il;
     while (intn.value() != 0 && result == TimedWaitResult::NoTimeout)
-    {
-        result = Kernel::Thread::IRQenableIrqAndTimedWaitMs(
-            il, start + INTN_TIMEOUT);
-    }
+        result = Kernel::Thread::IRQenableIrqAndTimedWaitMs(il, until);
 }
 
 int Wiz5500::waitForSocketIrq(miosix::Lock<miosix::FastMutex>& l, int sock_n,
@@ -488,11 +484,14 @@ int Wiz5500::waitForSocketIrq(miosix::Lock<miosix::FastMutex>& l, int sock_n,
     while (interrupt_service_thread == this_thread)
     {
         // Run a single step of the ISR
-        runInterruptServiceRoutine(l);
+        if (timeout == -1)
+            result = runInterruptServiceRoutine(l, -1);
+        else
+            result = runInterruptServiceRoutine(l, start + timeout);
 
         // Check if we woke up ourself, then we need to elect a new interrupt
         // service thread
-        if (wait_infos[i].irq != 0)
+        if (wait_infos[i].irq != 0 || result == TimedWaitResult::Timeout)
         {
             Thread* new_interrupt_service_thread = nullptr;
 
@@ -527,10 +526,23 @@ int Wiz5500::waitForSocketIrq(miosix::Lock<miosix::FastMutex>& l, int sock_n,
     return wait_infos[i].irq;
 }
 
-void Wiz5500::runInterruptServiceRoutine(Lock<FastMutex>& l)
+TimedWaitResult Wiz5500::runInterruptServiceRoutine(Lock<FastMutex>& l,
+                                                    long long until)
 {
     // Other threads might wake us up in order to
-    waitForINTn(l);
+    long long start = Kernel::getOldTick();
+    if (until == -1)
+    {
+        waitForINTn(l, start + INTN_TIMEOUT);
+    }
+    else
+    {
+        waitForINTn(l, std::min(start + INTN_TIMEOUT, until));
+
+        // Did we run out of time?
+        if (Kernel::getOldTick() >= until)
+            return TimedWaitResult::Timeout;
+    }
 
     // Ok something happened!
 
@@ -590,6 +602,8 @@ void Wiz5500::runInterruptServiceRoutine(Lock<FastMutex>& l)
             cb(ip, port);
         }
     }
+
+    return TimedWaitResult::NoTimeout;
 }
 
 void Wiz5500::spiRead(uint8_t block, uint16_t address, uint8_t* data,
diff --git a/src/shared/drivers/WIZ5500/WIZ5500.h b/src/shared/drivers/WIZ5500/WIZ5500.h
index 728b50916..11d627cc2 100644
--- a/src/shared/drivers/WIZ5500/WIZ5500.h
+++ b/src/shared/drivers/WIZ5500/WIZ5500.h
@@ -252,11 +252,12 @@ private:
     static constexpr int NUM_THREAD_WAIT_INFOS = 16;
     static constexpr int NUM_SOCKETS           = 8;
 
-    void waitForINTn(miosix::Lock<miosix::FastMutex>& l);
+    void waitForINTn(miosix::Lock<miosix::FastMutex>& l, long long until);
     int waitForSocketIrq(miosix::Lock<miosix::FastMutex>& l, int sock_n,
                          uint8_t irq_mask, int timeout);
 
-    void runInterruptServiceRoutine(miosix::Lock<miosix::FastMutex>& l);
+    miosix::TimedWaitResult runInterruptServiceRoutine(
+        miosix::Lock<miosix::FastMutex>& l, long long until);
 
     void spiRead(uint8_t block, uint16_t address, uint8_t* data, size_t len);
     void spiWrite(uint8_t block, uint16_t address, const uint8_t* data,
-- 
GitLab