diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL.h b/Marlin/src/HAL/HAL_LPC1768/HAL.h
index 5eda2ac72b6e00efea84d50e1fd5f1cc7a12ec86..db14170eac0237cf282fe4ae328f55bf8f11f2fa 100644
--- a/Marlin/src/HAL/HAL_LPC1768/HAL.h
+++ b/Marlin/src/HAL/HAL_LPC1768/HAL.h
@@ -37,7 +37,7 @@ void HAL_init();
 #include <stdarg.h>
 #include <algorithm>
 
-extern "C" volatile uint32_t _millis;
+extern "C" volatile millis_t _millis;
 
 #include <Arduino.h>
 #include <pinmapping.h>
diff --git a/Marlin/src/HAL/HAL_LPC1768/main.cpp b/Marlin/src/HAL/HAL_LPC1768/main.cpp
index 9fe2a040477e2a94f1c5b567f87f493280cc478d..bf858ad49b28c1f6e8abcd110581a136b073e5f7 100644
--- a/Marlin/src/HAL/HAL_LPC1768/main.cpp
+++ b/Marlin/src/HAL/HAL_LPC1768/main.cpp
@@ -71,7 +71,7 @@ void HAL_init() {
   #ifndef USB_SD_DISABLED
     MSC_SD_Init(0);                         // Enable USB SD card access
   #endif
-  const uint32_t usb_timeout = millis() + 2000;
+  const millis_t usb_timeout = millis() + 2000;
   while (!USB_Configuration && PENDING(millis(), usb_timeout)) {
     delay(50);
     HAL_idletask();
diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g/HAL_LCD_I2C_routines.c b/Marlin/src/HAL/HAL_LPC1768/u8g/HAL_LCD_I2C_routines.c
index 80bf5fc633dad80cc67781590cad50b1f3e8b867..d57ed2599de41243a8d1749994b9cad57f0d3b4d 100644
--- a/Marlin/src/HAL/HAL_LPC1768/u8g/HAL_LCD_I2C_routines.c
+++ b/Marlin/src/HAL/HAL_LPC1768/u8g/HAL_LCD_I2C_routines.c
@@ -33,6 +33,8 @@
 #include <lpc17xx_pinsel.h>
 #include <lpc17xx_libcfg_default.h>
 
+#include "../../../core/millis_t.h"
+
 //////////////////////////////////////////////////////////////////////////////////////
 
 // These two routines are exact copies of the lpc17xx_i2c.c routines.  Couldn't link to
@@ -149,13 +151,13 @@ void u8g_i2c_init(uint8_t clock_option) {
   u8g_i2c_start(0); // send slave address and write bit
 }
 
-volatile extern uint32_t _millis;
+volatile extern millis_t _millis;
 uint8_t u8g_i2c_send_byte(uint8_t data) {
   #define I2C_TIMEOUT 3
   LPC_I2C1->I2DAT = data & I2C_I2DAT_BITMASK; // transmit data
   LPC_I2C1->I2CONSET = I2C_I2CONSET_AA;
   LPC_I2C1->I2CONCLR = I2C_I2CONCLR_SIC;
-  uint32_t timeout = _millis + I2C_TIMEOUT;
+  millis_t timeout = _millis + I2C_TIMEOUT;
   while ((I2C_status != I2C_I2STAT_M_TX_DAT_ACK) && (I2C_status != I2C_I2STAT_M_TX_DAT_NACK) && (timeout > _millis));  // wait for xmit to finish
   // had hangs with SH1106 so added time out - have seen temporary screen corruption when this happens
   return 1;
diff --git a/Marlin/src/sd/Sd2Card.cpp b/Marlin/src/sd/Sd2Card.cpp
index 153611d7ad925ee3dda0d93550b7482ef46eaff8..d1116cdb35644355ee77e3a465fe06644d5c0592 100644
--- a/Marlin/src/sd/Sd2Card.cpp
+++ b/Marlin/src/sd/Sd2Card.cpp
@@ -240,7 +240,7 @@ bool Sd2Card::init(uint8_t sckRateID, pin_t chipSelectPin) {
   errorCode_ = type_ = 0;
   chipSelectPin_ = chipSelectPin;
   // 16-bit init start time allows over a minute
-  uint16_t t0 = (uint16_t)millis();
+  const millis_t init_timeout = millis() + SD_INIT_TIMEOUT;
   uint32_t arg;
 
   // If init takes more than 4s it could trigger
@@ -268,7 +268,7 @@ bool Sd2Card::init(uint8_t sckRateID, pin_t chipSelectPin) {
 
   // Command to go idle in SPI mode
   while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) {
-    if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
+    if (ELAPSED(millis(), init_timeout)) {
       error(SD_CARD_ERROR_CMD0);
       goto FAIL;
     }
@@ -297,7 +297,7 @@ bool Sd2Card::init(uint8_t sckRateID, pin_t chipSelectPin) {
       break;
     }
 
-    if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
+    if (ELAPSED(millis(), init_timeout)) {
       error(SD_CARD_ERROR_CMD8);
       goto FAIL;
     }
@@ -312,7 +312,7 @@ bool Sd2Card::init(uint8_t sckRateID, pin_t chipSelectPin) {
   arg = type() == SD_CARD_TYPE_SD2 ? 0x40000000 : 0;
   while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) {
     // check for timeout
-    if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
+    if (ELAPSED(millis(), init_timeout)) {
       error(SD_CARD_ERROR_ACMD41);
       goto FAIL;
     }
@@ -449,9 +449,9 @@ bool Sd2Card::readData(uint8_t* dst) {
 
 bool Sd2Card::readData(uint8_t* dst, uint16_t count) {
   // wait for start block token
-  uint16_t t0 = millis();
+  const millis_t read_timeout = millis() + SD_READ_TIMEOUT;
   while ((status_ = spiRec()) == 0xFF) {
-    if (((uint16_t)millis() - t0) > SD_READ_TIMEOUT) {
+    if (ELAPSED(millis(), read_timeout)) {
       error(SD_CARD_ERROR_READ_TIMEOUT);
       goto FAIL;
     }
@@ -553,10 +553,10 @@ bool Sd2Card::setSckRate(uint8_t sckRateID) {
 }
 
 // wait for card to go not busy
-bool Sd2Card::waitNotBusy(uint16_t timeoutMillis) {
-  uint16_t t0 = millis();
+bool Sd2Card::waitNotBusy(const millis_t timeout_ms) {
+  const millis_t wait_timeout = millis() + timeout_ms;
   while (spiRec() != 0xFF)
-    if (((uint16_t)millis() - t0) >= timeoutMillis) return false;
+    if (ELAPSED(millis(), wait_timeout)) return false;
 
   return true;
 }
diff --git a/Marlin/src/sd/Sd2Card.h b/Marlin/src/sd/Sd2Card.h
index 2d9ebf33e3248e586555085100e687882df9b446..d6d9af18ba3a581c02d89a0900d0c1943156c7bd 100644
--- a/Marlin/src/sd/Sd2Card.h
+++ b/Marlin/src/sd/Sd2Card.h
@@ -199,7 +199,7 @@ class Sd2Card {
   void chipDeselect();
   void chipSelect();
   void type(uint8_t value) { type_ = value; }
-  bool waitNotBusy(uint16_t timeoutMillis);
+  bool waitNotBusy(const millis_t timeout_ms);
   bool writeData(uint8_t token, const uint8_t* src);
 };
 
diff --git a/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp b/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp
index db827344fcbbd3404d73f9386ee8d18c31a45b3a..f4fda4b3c9b30035cd33a92df7efaa6f492abd24 100644
--- a/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp
+++ b/Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp
@@ -50,7 +50,7 @@ void Sd2Card::idle() {
       state = USB_HOST_WAITING;
       break;
     case USB_HOST_WAITING:
-      if (millis() > next_retry) {
+      if (ELAPSED(millis(), next_retry)) {
         next_retry = millis() + 10000;
         state = USB_HOST_UNINITIALIZED;
       }