diff --git a/src/shared/drivers/WIZ5500/WIZ5500.cpp b/src/shared/drivers/WIZ5500/WIZ5500.cpp index 43dc983def415ad9796306a4b59d02d6f046241c..4f0159743bc43a917a714c73d498321b966bf7c4 100644 --- a/src/shared/drivers/WIZ5500/WIZ5500.cpp +++ b/src/shared/drivers/WIZ5500/WIZ5500.cpp @@ -407,18 +407,15 @@ void Wiz5500::close(int sock_n, int timeout) socket_infos[sock_n].mode = Wiz5500::SocketMode::CLOSED; } -void Wiz5500::waitForINTn(Lock<FastMutex>& l) +TimedWaitResult 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); + return result; } int Wiz5500::waitForSocketIrq(miosix::Lock<miosix::FastMutex>& l, int sock_n, @@ -488,25 +485,34 @@ 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; + for (int j = 0; j < NUM_THREAD_WAIT_INFOS; j++) { - if (wait_infos[j].irq == 0) + if (wait_infos[j].irq == 0 && wait_infos[j].sock_n != -1 && + j != i) { - { - FastInterruptDisableLock il; - interrupt_service_thread = wait_infos[j].thread; - } - - wait_infos[j].thread->wakeup(); + new_interrupt_service_thread = wait_infos[j].thread; break; } } + + { + FastInterruptDisableLock il; + interrupt_service_thread = new_interrupt_service_thread; + } + + if (new_interrupt_service_thread) + new_interrupt_service_thread->wakeup(); } } @@ -521,10 +527,24 @@ 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) + { + // Wait for interrupts and check if we run out of time + if (waitForINTn(l, start + INTN_TIMEOUT) == TimedWaitResult::Timeout) + return TimedWaitResult::Timeout; + } + else + { + // Wait for interrupts and check if we run out of time + if (waitForINTn(l, std::min(start + INTN_TIMEOUT, until)) == + TimedWaitResult::Timeout) + return TimedWaitResult::Timeout; + } // Ok something happened! @@ -584,6 +604,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 728b50916e96847d2affe2e284bdbb4a68d50e8c..c28d1b005e23785bd76336ef5c63684535f9532a 100644 --- a/src/shared/drivers/WIZ5500/WIZ5500.h +++ b/src/shared/drivers/WIZ5500/WIZ5500.h @@ -252,11 +252,13 @@ private: static constexpr int NUM_THREAD_WAIT_INFOS = 16; static constexpr int NUM_SOCKETS = 8; - void waitForINTn(miosix::Lock<miosix::FastMutex>& l); + miosix::TimedWaitResult 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,