diff --git a/epicardium/drivers/sleep.c b/epicardium/drivers/sleep.c
index 70ded1925d767a36f5e9245fd232ce2e93da87a5..8370d47be7643760a43b8912ca00452fbbeacba3 100644
--- a/epicardium/drivers/sleep.c
+++ b/epicardium/drivers/sleep.c
@@ -210,5 +210,5 @@ void sleep_deepsleep(void)
 
 void epic_sleep(uint32_t ms)
 {
-	vTaskDelay(ms);
+	vTaskDelay(pdMS_TO_TICKS(ms));
 }
diff --git a/pycardium/mphalport.c b/pycardium/mphalport.c
index ab3e0857c7d132f67c4c9b5f08530f06563d9a3d..d7fc93c9a9179a5f945dafaa4b8e172ed4561567 100644
--- a/pycardium/mphalport.c
+++ b/pycardium/mphalport.c
@@ -21,7 +21,8 @@
 #include <string.h>
 
 // Smallest interval which can be reached exactly
-#define SYSTICK_INTERVAL_US 15625ULL
+// * 8 to allow up to 100 ms epic calls
+#define SYSTICK_INTERVAL_US (15625ULL * 8ULL)
 #define SYSTICK_FREQ_HZ (1000000 / SYSTICK_INTERVAL_US)
 
 /*
@@ -225,51 +226,6 @@ static void systick_delay_precise(uint32_t us)
 	}
 }
 
-static void systick_delay_sleep(uint32_t us)
-{
-	uint64_t final_time = systick_get_us() + (uint64_t)us - 2;
-
-	while (1) {
-		uint64_t now = systick_get_us();
-
-		if ((now + SYSTICK_INTERVAL_US) > final_time) {
-			break;
-		}
-
-		/*
-		 * Sleep with WFI if more than SYSTICK_INTERVAL_US of delay
-		 * is remaining.  The SysTick interrupt is guaranteed to
-		 * happen within any timespan of SYSTICK_INTERVAL_US.
-		 *
-		 * Use a critical section encompassing both the check and the
-		 * WFI to prevent a race-condition where the interrupt happens
-		 * just in between the check and WFI.
-		 */
-		uint32_t irqsaved = __get_PRIMASK();
-		__set_PRIMASK(0);
-		if ((now + SYSTICK_INTERVAL_US) < final_time) {
-			__WFI();
-		}
-		__set_PRIMASK(irqsaved);
-
-		/*
-		 * Handle pending MicroPython 'interrupts'.  This call could
-		 * potentially not return here when a handler raises an
-		 * exception.  Those will propagate outwards and thus make the
-		 * delay return early.
-		 *
-		 * One example of this happeing is the KeyboardInterrupt
-		 * (CTRL+C) which will abort the running code and exit to REPL.
-		 */
-		mp_handle_pending(true);
-	}
-
-	uint64_t now = systick_get_us();
-	if (now < final_time) {
-		systick_delay_precise(final_time - now);
-	}
-}
-
 static void systick_delay(uint32_t us)
 {
 	if (us == 0)
@@ -277,15 +233,35 @@ static void systick_delay(uint32_t us)
 
 	/*
 	 * For very short delays, use the systick_delay_precise() function which
-	 * delays with a microsecond accuracy.  For anything >SYSTICK_INTERVAL_US, use
+	 * delays with a microsecond accuracy. For anything > SYSTICK_INTERVAL_US, use
 	 * systick_delay_sleep() which puts the CPU to sleep when nothing is
 	 * happening and also checks for MicroPython interrupts every now and
 	 * then.
 	 */
-	if (us < SYSTICK_INTERVAL_US) {
+	if (us < 1000) {
 		systick_delay_precise(us);
 	} else {
-		systick_delay_sleep(us);
+		uint64_t now        = systick_get_us();
+		uint64_t final_time = now + us;
+
+		while (final_time - systick_get_us() > SYSTICK_INTERVAL_US) {
+			uint32_t sleep_time =
+				(final_time - systick_get_us()) / 1000;
+			if (sleep_time > 100)
+				sleep_time = 100;
+			epic_sleep(sleep_time);
+			mp_handle_pending(true);
+		}
+
+		now = systick_get_us();
+		if (final_time - now > 1000) {
+			epic_sleep((final_time - now) / 1000);
+		}
+
+		now = systick_get_us();
+		if (final_time > now) {
+			systick_delay_precise(final_time - now);
+		}
 	}
 }