From 039302bf4cc604b0a73b521e0c08a1fdfa5a74a0 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <thinkyhead@users.noreply.github.com>
Date: Sat, 12 May 2018 04:22:55 -0500
Subject: [PATCH] Better handling of DELAY_NS and DELAY_US (#10717)

Co-Authored-By: ejtagle <ejtagle@hotmail.com>
---
 Marlin/Conditionals_LCD.h            | 15 +++---
 Marlin/Max7219_Debug_LEDs.cpp        |  3 +-
 Marlin/delay.h                       | 77 ++++++++++++++++++++++++++++
 Marlin/macros.h                      | 61 +++-------------------
 Marlin/pins_ANET_10.h                | 12 ++---
 Marlin/pins_MELZI_CREALITY.h         |  6 +--
 Marlin/pins_MELZI_MALYAN.h           |  6 +--
 Marlin/pins_MELZI_TRONXY.h           |  6 +--
 Marlin/pins_PRINTRBOARD_REVF.h       |  6 +--
 Marlin/pins_SANGUINOLOLU_11.h        |  6 +--
 Marlin/stepper.cpp                   | 15 +++---
 Marlin/temperature.cpp               |  3 +-
 Marlin/ultralcd_st7565_u8glib_VIKI.h | 41 +++++++--------
 Marlin/ultralcd_st7920_u8glib_rrd.h  | 41 +++++++--------
 14 files changed, 166 insertions(+), 132 deletions(-)
 create mode 100644 Marlin/delay.h

diff --git a/Marlin/Conditionals_LCD.h b/Marlin/Conditionals_LCD.h
index 5a858a68cd2..5bab1d51c26 100644
--- a/Marlin/Conditionals_LCD.h
+++ b/Marlin/Conditionals_LCD.h
@@ -111,13 +111,13 @@
 
     #define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
     #ifndef ST7920_DELAY_1
-      #define ST7920_DELAY_1 DELAY_2_NOP
+      #define ST7920_DELAY_1 DELAY_NS(125)
     #endif
     #ifndef ST7920_DELAY_2
-      #define ST7920_DELAY_2 DELAY_2_NOP
+      #define ST7920_DELAY_2 DELAY_NS(125)
     #endif
     #ifndef ST7920_DELAY_3
-      #define ST7920_DELAY_3 DELAY_2_NOP
+      #define ST7920_DELAY_3 DELAY_NS(125)
     #endif
 
   #elif ENABLED(MKS_12864OLED)
@@ -290,6 +290,10 @@
     #endif
   #endif
 
+  #if ENABLED(NO_LCD_MENUS)
+    #undef ULTIPANEL
+  #endif
+
   #if ENABLED(ULTIPANEL)
     #define NEWPANEL  // Disable this if you actually have no click-encoder panel
     #define ULTRA_LCD
@@ -367,11 +371,6 @@
     #endif
   #endif
 
-  #if ENABLED(NO_LCD_MENUS)
-    #undef ULTIPANEL
-    #undef NEWPANEL
-  #endif
-
   // Boot screens
   #if DISABLED(ULTRA_LCD)
     #undef SHOW_BOOTSCREEN
diff --git a/Marlin/Max7219_Debug_LEDs.cpp b/Marlin/Max7219_Debug_LEDs.cpp
index 83b285a08c3..e47796bb555 100644
--- a/Marlin/Max7219_Debug_LEDs.cpp
+++ b/Marlin/Max7219_Debug_LEDs.cpp
@@ -60,11 +60,12 @@
 #include "planner.h"
 #include "stepper.h"
 #include "Marlin.h"
+#include "delay.h"
 
 static uint8_t LEDs[8] = { 0 };
 
 // Delay for 0.1875µs (16MHz AVR) or 0.15µs (20MHz AVR)
-#define SIG_DELAY() DELAY_3_NOP
+#define SIG_DELAY() DELAY_NS(188)
 
 void Max7219_PutByte(uint8_t data) {
   CRITICAL_SECTION_START
diff --git a/Marlin/delay.h b/Marlin/delay.h
new file mode 100644
index 00000000000..5689b2b4c13
--- /dev/null
+++ b/Marlin/delay.h
@@ -0,0 +1,77 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * AVR busy wait delay Cycles routines:
+ *
+ *  DELAY_CYCLES(count): Delay execution in cycles
+ *  DELAY_NS(count): Delay execution in nanoseconds
+ *  DELAY_US(count): Delay execution in microseconds
+ */
+
+#ifndef MARLIN_DELAY_H
+#define MARLIN_DELAY_H
+
+#define nop() __asm__ __volatile__("nop;\n\t":::)
+
+FORCE_INLINE static void __delay_4cycles(uint8_t cy) {
+  __asm__ __volatile__(
+    L("1")
+    A("dec %[cnt]")
+    A("nop")
+    A("brne 1b")
+    : [cnt] "+r"(cy)  // output: +r means input+output
+    :                 // input:
+    : "cc"            // clobbers:
+  );
+}
+
+/* ---------------- Delay in cycles */
+FORCE_INLINE static void DELAY_CYCLES(uint16_t x) {
+
+  if (__builtin_constant_p(x)) {
+    #define MAXNOPS 4
+
+    if (x <= (MAXNOPS)) {
+      switch (x) { case 4: nop(); case 3: nop(); case 2: nop(); case 1: nop(); }
+    }
+    else {
+      const uint32_t rem = (x) % (MAXNOPS);
+      switch (rem) { case 3: nop(); case 2: nop(); case 1: nop(); }
+      if ((x = (x) / (MAXNOPS)))
+        __delay_4cycles(x); // if need more then 4 nop loop is more optimal
+    }
+
+    #undef MAXNOPS
+  }
+  else
+    __delay_4cycles(x / 4);
+}
+#undef nop
+
+/* ---------------- Delay in nanoseconds */
+#define DELAY_NS(x) DELAY_CYCLES( (x) * (F_CPU/1000000L) / 1000L )
+
+/* ---------------- Delay in microseconds */
+#define DELAY_US(x) DELAY_CYCLES( (x) * (F_CPU/1000000L) )
+
+#endif // MARLIN_DELAY_H
diff --git a/Marlin/macros.h b/Marlin/macros.h
index 74dd68ec6b9..ec9e55c0bbb 100644
--- a/Marlin/macros.h
+++ b/Marlin/macros.h
@@ -57,58 +57,8 @@
 #define CYCLES_PER_MICROSECOND (F_CPU / 1000000L) // 16 or 20
 #define INT0_PRESCALER 8
 
-// Processor-level delays for hardware interfaces
-#ifndef _NOP
-  #define _NOP() do { __asm__ volatile ("nop"); } while (0)
-#endif
-#define DELAY_NOPS(X) \
-  switch (X) { \
-    case 20: _NOP(); case 19: _NOP(); case 18: _NOP(); case 17: _NOP(); \
-    case 16: _NOP(); case 15: _NOP(); case 14: _NOP(); case 13: _NOP(); \
-    case 12: _NOP(); case 11: _NOP(); case 10: _NOP(); case  9: _NOP(); \
-    case  8: _NOP(); case  7: _NOP(); case  6: _NOP(); case  5: _NOP(); \
-    case  4: _NOP(); case  3: _NOP(); case  2: _NOP(); case  1: _NOP(); \
-  }
-#define DELAY_0_NOP   NOOP
-#define DELAY_1_NOP   DELAY_NOPS( 1)
-#define DELAY_2_NOP   DELAY_NOPS( 2)
-#define DELAY_3_NOP   DELAY_NOPS( 3)
-#define DELAY_4_NOP   DELAY_NOPS( 4)
-#define DELAY_5_NOP   DELAY_NOPS( 5)
-#define DELAY_10_NOP  DELAY_NOPS(10)
-#define DELAY_20_NOP  DELAY_NOPS(20)
-
-#if CYCLES_PER_MICROSECOND <= 200
-  #define DELAY_100NS DELAY_NOPS((CYCLES_PER_MICROSECOND + 9) / 10)
-#else
-  #define DELAY_100NS DELAY_20_NOP
-#endif
-
-// Microsecond delays for hardware interfaces
-#if CYCLES_PER_MICROSECOND <= 20
-  #define DELAY_1US DELAY_NOPS(CYCLES_PER_MICROSECOND)
-  #define DELAY_US(X) \
-    switch (X) { \
-      case 20: DELAY_1US; case 19: DELAY_1US; case 18: DELAY_1US; case 17: DELAY_1US; \
-      case 16: DELAY_1US; case 15: DELAY_1US; case 14: DELAY_1US; case 13: DELAY_1US; \
-      case 12: DELAY_1US; case 11: DELAY_1US; case 10: DELAY_1US; case  9: DELAY_1US; \
-      case  8: DELAY_1US; case  7: DELAY_1US; case  6: DELAY_1US; case  5: DELAY_1US; \
-      case  4: DELAY_1US; case  3: DELAY_1US; case  2: DELAY_1US; case  1: DELAY_1US; \
-    }
-#else
-  #define DELAY_US(X) delayMicroseconds(X) // May not be usable in CRITICAL_SECTION
-  #define DELAY_1US DELAY_US(1)
-#endif
-#define DELAY_2US  DELAY_US( 2)
-#define DELAY_3US  DELAY_US( 3)
-#define DELAY_4US  DELAY_US( 4)
-#define DELAY_5US  DELAY_US( 5)
-#define DELAY_6US  DELAY_US( 6)
-#define DELAY_7US  DELAY_US( 7)
-#define DELAY_8US  DELAY_US( 8)
-#define DELAY_9US  DELAY_US( 9)
-#define DELAY_10US DELAY_US(10)
-#define DELAY_20US DELAY_US(20)
+// Nanoseconds per cycle
+#define NANOSECONDS_PER_CYCLE (1000000000.0 / F_CPU)
 
 // Remove compiler warning on an unused variable
 #define UNUSED(x) (void) (x)
@@ -122,7 +72,7 @@
 
 // Macros for bit masks
 #undef _BV
-#define _BV(b) (1<<(b))
+#define _BV(b) (1 << (b))
 #define TEST(n,b) !!((n)&_BV(b))
 #define SBI(n,b) (n |= _BV(b))
 #define CBI(n,b) (n &= ~_BV(b))
@@ -152,6 +102,7 @@
 // Macros to contrain values
 #define NOLESS(v,n) do{ if (v < n) v = n; }while(0)
 #define NOMORE(v,n) do{ if (v > n) v = n; }while(0)
+#define LIMIT(v,n1,n2) do{ if (v < n1) v = n1; else if (v > n2) v = n2; }while(0)
 
 // Macros to support option testing
 #define _CAT(a, ...) a ## __VA_ARGS__
@@ -159,9 +110,11 @@
 #define SWITCH_ENABLED_true  1
 #define SWITCH_ENABLED_0     0
 #define SWITCH_ENABLED_1     1
+#define SWITCH_ENABLED_0x0   0
+#define SWITCH_ENABLED_0x1   1
 #define SWITCH_ENABLED_      1
 #define ENABLED(b) _CAT(SWITCH_ENABLED_, b)
-#define DISABLED(b) (!_CAT(SWITCH_ENABLED_, b))
+#define DISABLED(b) !ENABLED(b)
 
 #define WITHIN(V,L,H) ((V) >= (L) && (V) <= (H))
 #define NUMERIC(a) WITHIN(a, '0', '9')
diff --git a/Marlin/pins_ANET_10.h b/Marlin/pins_ANET_10.h
index d7c113d3557..18a52c4e8c9 100644
--- a/Marlin/pins_ANET_10.h
+++ b/Marlin/pins_ANET_10.h
@@ -153,7 +153,7 @@
 #if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL)
   #define LCD_SDSS           28
   #if ENABLED(ADC_KEYPAD)
-    #define SERVO0_PIN       27 // free for BLTouch/3D-Touch
+    #define SERVO0_PIN       27   // free for BLTouch/3D-Touch
     #define LCD_PINS_RS      28
     #define LCD_PINS_ENABLE  29
     #define LCD_PINS_D4      10
@@ -168,7 +168,7 @@
     // Pin definitions for the Anet A6 Full Graphics display and the RepRapDiscount Full Graphics
     // display using an adapter board  // https://go.aisler.net/benlye/anet-lcd-adapter/pcb
     // See below for alternative pin definitions for use with https://www.thingiverse.com/thing:2103748
-    #define SERVO0_PIN       29 // free for BLTouch/3D-Touch
+    #define SERVO0_PIN       29   // free for BLTouch/3D-Touch
     #define BEEPER_PIN       17
     #define LCD_PINS_RS      27
     #define LCD_PINS_ENABLE  28
@@ -177,13 +177,13 @@
     #define BTN_EN2          10
     #define BTN_ENC          16
     #ifndef ST7920_DELAY_1
-      #define ST7920_DELAY_1 DELAY_0_NOP
+      #define ST7920_DELAY_1 DELAY_NS(0)
     #endif
     #ifndef ST7920_DELAY_2
-      #define ST7920_DELAY_2 DELAY_1_NOP
+      #define ST7920_DELAY_2 DELAY_NS(63)
     #endif
     #ifndef ST7920_DELAY_3
-      #define ST7920_DELAY_3 DELAY_2_NOP
+      #define ST7920_DELAY_3 DELAY_NS(125)
     #endif
     #define STD_ENCODER_PULSES_PER_STEP 4
     #define STD_ENCODER_STEPS_PER_MENU_ITEM 1
@@ -201,7 +201,7 @@
  * published by oderwat on Thingiverse at https://www.thingiverse.com/thing:2103748.
  *
  * Using that adapter requires changing the pin definition as follows:
- *   #define SERVO0_PIN        27 // free for BLTouch/3D-Touch
+ *   #define SERVO0_PIN        27   // free for BLTouch/3D-Touch
  *   #define BEEPER_PIN        28
  *   #define LCD_PINS_RS       30
  *   #define LCD_PINS_ENABLE   29
diff --git a/Marlin/pins_MELZI_CREALITY.h b/Marlin/pins_MELZI_CREALITY.h
index b42075b76d8..8bfd3b860a2 100644
--- a/Marlin/pins_MELZI_CREALITY.h
+++ b/Marlin/pins_MELZI_CREALITY.h
@@ -55,13 +55,13 @@
 
 // Alter timing for graphical display
 #ifndef ST7920_DELAY_1
-  #define ST7920_DELAY_1 DELAY_2_NOP
+  #define ST7920_DELAY_1 DELAY_NS(125)
 #endif
 #ifndef ST7920_DELAY_2
-  #define ST7920_DELAY_2 DELAY_2_NOP
+  #define ST7920_DELAY_2 DELAY_NS(125)
 #endif
 #ifndef ST7920_DELAY_3
-  #define ST7920_DELAY_3 DELAY_2_NOP
+  #define ST7920_DELAY_3 DELAY_NS(125)
 #endif
 
 #if ENABLED(MINIPANEL)
diff --git a/Marlin/pins_MELZI_MALYAN.h b/Marlin/pins_MELZI_MALYAN.h
index 3888b537d11..a81526f065d 100644
--- a/Marlin/pins_MELZI_MALYAN.h
+++ b/Marlin/pins_MELZI_MALYAN.h
@@ -44,11 +44,11 @@
 
 // Alter timing for graphical display
 #ifndef ST7920_DELAY_1
-  #define ST7920_DELAY_1 DELAY_2_NOP
+  #define ST7920_DELAY_1 DELAY_NS(125)
 #endif
 #ifndef ST7920_DELAY_2
-  #define ST7920_DELAY_2 DELAY_2_NOP
+  #define ST7920_DELAY_2 DELAY_NS(125)
 #endif
 #ifndef ST7920_DELAY_3
-  #define ST7920_DELAY_3 DELAY_2_NOP
+  #define ST7920_DELAY_3 DELAY_NS(125)
 #endif
diff --git a/Marlin/pins_MELZI_TRONXY.h b/Marlin/pins_MELZI_TRONXY.h
index 7c66c50c600..0da7934302c 100644
--- a/Marlin/pins_MELZI_TRONXY.h
+++ b/Marlin/pins_MELZI_TRONXY.h
@@ -51,11 +51,11 @@
 #define BTN_ENC         26
 
 #ifndef ST7920_DELAY_1
-  #define ST7920_DELAY_1 DELAY_0_NOP
+  #define ST7920_DELAY_1 DELAY_NS(0)
 #endif
 #ifndef ST7920_DELAY_2
-  #define ST7920_DELAY_2 DELAY_2_NOP
+  #define ST7920_DELAY_2 DELAY_NS(125)
 #endif
 #ifndef ST7920_DELAY_3
-  #define ST7920_DELAY_3 DELAY_0_NOP
+  #define ST7920_DELAY_3 DELAY_NS(0)
 #endif
diff --git a/Marlin/pins_PRINTRBOARD_REVF.h b/Marlin/pins_PRINTRBOARD_REVF.h
index bf3a023c4de..359a8b85db3 100644
--- a/Marlin/pins_PRINTRBOARD_REVF.h
+++ b/Marlin/pins_PRINTRBOARD_REVF.h
@@ -244,13 +244,13 @@
 
     // increase delays
     #ifndef ST7920_DELAY_1
-      #define ST7920_DELAY_1 DELAY_5_NOP
+      #define ST7920_DELAY_1 DELAY_NS(313)
     #endif
     #ifndef ST7920_DELAY_2
-      #define ST7920_DELAY_2 DELAY_5_NOP
+      #define ST7920_DELAY_2 DELAY_NS(313)
     #endif
     #ifndef ST7920_DELAY_3
-      #define ST7920_DELAY_3 DELAY_5_NOP
+      #define ST7920_DELAY_3 DELAY_NS(313)
     #endif
 
   #else
diff --git a/Marlin/pins_SANGUINOLOLU_11.h b/Marlin/pins_SANGUINOLOLU_11.h
index c27eab1c8af..ed4a521e7eb 100644
--- a/Marlin/pins_SANGUINOLOLU_11.h
+++ b/Marlin/pins_SANGUINOLOLU_11.h
@@ -239,13 +239,13 @@
     #define BTN_EN2             30
 
     #ifndef ST7920_DELAY_1
-      #define ST7920_DELAY_1 DELAY_0_NOP
+      #define ST7920_DELAY_1 DELAY_NS(0)
     #endif
     #ifndef ST7920_DELAY_2
-      #define ST7920_DELAY_2 DELAY_3_NOP
+      #define ST7920_DELAY_2 DELAY_NS(188)
     #endif
     #ifndef ST7920_DELAY_3
-      #define ST7920_DELAY_3 DELAY_0_NOP
+      #define ST7920_DELAY_3 DELAY_NS(0)
     #endif
 
   #elif ENABLED(ZONESTAR_LCD) // For the Tronxy Melzi boards
diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp
index c5a0c7f183b..75ece5b1101 100644
--- a/Marlin/stepper.cpp
+++ b/Marlin/stepper.cpp
@@ -61,6 +61,7 @@
 #include "language.h"
 #include "cardreader.h"
 #include "speed_lookuptable.h"
+#include "delay.h"
 
 #if HAS_DIGIPOTSS
   #include <SPI.h>
@@ -1455,7 +1456,7 @@ void Stepper::isr() {
       while (EXTRA_CYCLES_XYZE > (uint32_t)(TCNT0 - pulse_start) * (INT0_PRESCALER)) { /* nada */ }
       pulse_start = TCNT0;
     #elif EXTRA_CYCLES_XYZE > 0
-      DELAY_NOPS(EXTRA_CYCLES_XYZE);
+      DELAY_NS(EXTRA_CYCLES_XYZE * NANOSECONDS_PER_CYCLE);
     #endif
 
     #if HAS_X_STEP
@@ -1490,7 +1491,7 @@ void Stepper::isr() {
     #if EXTRA_CYCLES_XYZE > 20
       if (i) while (EXTRA_CYCLES_XYZE > (uint32_t)(TCNT0 - pulse_start) * (INT0_PRESCALER)) { /* nada */ }
     #elif EXTRA_CYCLES_XYZE > 0
-      if (i) DELAY_NOPS(EXTRA_CYCLES_XYZE);
+      if (i) DELAY_NS(EXTRA_CYCLES_XYZE * NANOSECONDS_PER_CYCLE);
     #endif
 
   } // steps_loop
@@ -1714,7 +1715,7 @@ void Stepper::isr() {
         while (EXTRA_CYCLES_E > (uint32_t)(TCNT0 - pulse_start) * (INT0_PRESCALER)) { /* nada */ }
         pulse_start = TCNT0;
       #elif EXTRA_CYCLES_E > 0
-        DELAY_NOPS(EXTRA_CYCLES_E);
+        DELAY_NS(EXTRA_CYCLES_E * NANOSECONDS_PER_CYCLE);
       #endif
 
       switch (LA_active_extruder) {
@@ -1737,7 +1738,7 @@ void Stepper::isr() {
       #if EXTRA_CYCLES_E > 20
         if (e_steps) while (EXTRA_CYCLES_E > (uint32_t)(TCNT0 - pulse_start) * (INT0_PRESCALER)) { /* nada */ }
       #elif EXTRA_CYCLES_E > 0
-        if (e_steps) DELAY_NOPS(EXTRA_CYCLES_E);
+        if (e_steps) DELAY_NS(EXTRA_CYCLES_E * NANOSECONDS_PER_CYCLE);
       #endif
 
     } // e_steps
@@ -2113,13 +2114,13 @@ void Stepper::report_positions() {
   #else
     #define _SAVE_START NOOP
     #if EXTRA_CYCLES_BABYSTEP > 0
-      #define _PULSE_WAIT DELAY_NOPS(EXTRA_CYCLES_BABYSTEP)
+      #define _PULSE_WAIT DELAY_NS(EXTRA_CYCLES_BABYSTEP * NANOSECONDS_PER_CYCLE)
     #elif STEP_PULSE_CYCLES > 0
       #define _PULSE_WAIT NOOP
     #elif ENABLED(DELTA)
-      #define _PULSE_WAIT delayMicroseconds(2);
+      #define _PULSE_WAIT DELAY_US(2);
     #else
-      #define _PULSE_WAIT delayMicroseconds(4);
+      #define _PULSE_WAIT DELAY_US(4);
     #endif
   #endif
 
diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp
index 4ee0ed3ac6e..629197c8281 100644
--- a/Marlin/temperature.cpp
+++ b/Marlin/temperature.cpp
@@ -31,6 +31,7 @@
 #include "planner.h"
 #include "language.h"
 #include "printcounter.h"
+#include "delay.h"
 
 #if ENABLED(HEATER_0_USES_MAX6675)
   #include "MarlinSPI.h"
@@ -1611,7 +1612,7 @@ void Temperature::disable_all_heaters() {
 
     WRITE(MAX6675_SS, 0); // enable TT_MAX6675
 
-    DELAY_100NS;          // Ensure 100ns delay
+    DELAY_NS(100);       // Ensure 100ns delay
 
     // Read a big-endian temperature value
     max6675_temp = 0;
diff --git a/Marlin/ultralcd_st7565_u8glib_VIKI.h b/Marlin/ultralcd_st7565_u8glib_VIKI.h
index 7f589e2ecf4..0e97edfaa0c 100644
--- a/Marlin/ultralcd_st7565_u8glib_VIKI.h
+++ b/Marlin/ultralcd_st7565_u8glib_VIKI.h
@@ -24,6 +24,7 @@
 #define ULCDST7565_H
 
 #include <U8glib.h>
+#include "delay.h"
 
 #define ST7565_CLK_PIN  DOGLCD_SCK
 #define ST7565_DAT_PIN  DOGLCD_MOSI
@@ -38,9 +39,9 @@
 #pragma GCC optimize (3)
 
 // If you want you can define your own set of delays in Configuration.h
-//#define ST7565_DELAY_1 DELAY_0_NOP
-//#define ST7565_DELAY_2 DELAY_0_NOP
-//#define ST7565_DELAY_3 DELAY_0_NOP
+//#define ST7565_DELAY_1 DELAY_NS(0)
+//#define ST7565_DELAY_2 DELAY_NS(0)
+//#define ST7565_DELAY_3 DELAY_NS(0)
 
 /*
 #define ST7565_DELAY_1 u8g_10MicroDelay()
@@ -49,25 +50,25 @@
 */
 
 #if F_CPU >= 20000000
-  #define CPU_ST7565_DELAY_1 DELAY_0_NOP
-  #define CPU_ST7565_DELAY_2 DELAY_0_NOP
-  #define CPU_ST7565_DELAY_3 DELAY_1_NOP
+  #define CPU_ST7565_DELAY_1 DELAY_NS(0)
+  #define CPU_ST7565_DELAY_2 DELAY_NS(0)
+  #define CPU_ST7565_DELAY_3 DELAY_NS(63)
 #elif MB(3DRAG) || MB(K8200) || MB(K8400)
-  #define CPU_ST7565_DELAY_1 DELAY_0_NOP
-  #define CPU_ST7565_DELAY_2 DELAY_3_NOP
-  #define CPU_ST7565_DELAY_3 DELAY_0_NOP
+  #define CPU_ST7565_DELAY_1 DELAY_NS(0)
+  #define CPU_ST7565_DELAY_2 DELAY_NS(188)
+  #define CPU_ST7565_DELAY_3 DELAY_NS(0)
 #elif MB(MINIRAMBO)
-  #define CPU_ST7565_DELAY_1 DELAY_0_NOP
-  #define CPU_ST7565_DELAY_2 DELAY_4_NOP
-  #define CPU_ST7565_DELAY_3 DELAY_0_NOP
+  #define CPU_ST7565_DELAY_1 DELAY_NS(0)
+  #define CPU_ST7565_DELAY_2 DELAY_NS(250)
+  #define CPU_ST7565_DELAY_3 DELAY_NS(0)
 #elif MB(RAMBO)
-  #define CPU_ST7565_DELAY_1 DELAY_0_NOP
-  #define CPU_ST7565_DELAY_2 DELAY_0_NOP
-  #define CPU_ST7565_DELAY_3 DELAY_0_NOP
+  #define CPU_ST7565_DELAY_1 DELAY_NS(0)
+  #define CPU_ST7565_DELAY_2 DELAY_NS(0)
+  #define CPU_ST7565_DELAY_3 DELAY_NS(0)
 #elif F_CPU == 16000000
-  #define CPU_ST7565_DELAY_1 DELAY_0_NOP
-  #define CPU_ST7565_DELAY_2 DELAY_0_NOP
-  #define CPU_ST7565_DELAY_3 DELAY_1_NOP
+  #define CPU_ST7565_DELAY_1 DELAY_NS(0)
+  #define CPU_ST7565_DELAY_2 DELAY_NS(0)
+  #define CPU_ST7565_DELAY_3 DELAY_NS(63)
 #else
   #error "No valid condition for delays in 'ultralcd_st7565_u8glib_VIKI.h'"
 #endif
@@ -115,8 +116,8 @@
 
 #endif // !HARDWARE_SPI
 
-#if defined(DOGM_SPI_DELAY_US) && DOGM_SPI_DELAY_US > 0
-  #define U8G_DELAY() delayMicroseconds(DOGM_SPI_DELAY_US)
+#if DOGM_SPI_DELAY_US > 0
+  #define U8G_DELAY() DELAY_US(DOGM_SPI_DELAY_US)
 #else
   #define U8G_DELAY() u8g_10MicroDelay()
 #endif
diff --git a/Marlin/ultralcd_st7920_u8glib_rrd.h b/Marlin/ultralcd_st7920_u8glib_rrd.h
index 3b379726f22..96a1f05f094 100644
--- a/Marlin/ultralcd_st7920_u8glib_rrd.h
+++ b/Marlin/ultralcd_st7920_u8glib_rrd.h
@@ -24,6 +24,7 @@
 #define ULCDST7920_H
 
 #include <U8glib.h>
+#include "delay.h"
 
 #define ST7920_CLK_PIN  LCD_PINS_D4
 #define ST7920_DAT_PIN  LCD_PINS_ENABLE
@@ -40,30 +41,30 @@
 #pragma GCC optimize (3)
 
 // If you want you can define your own set of delays in Configuration.h
-//#define ST7920_DELAY_1 DELAY_0_NOP
-//#define ST7920_DELAY_2 DELAY_0_NOP
-//#define ST7920_DELAY_3 DELAY_0_NOP
+//#define ST7920_DELAY_1 DELAY_NS(0)
+//#define ST7920_DELAY_2 DELAY_NS(0)
+//#define ST7920_DELAY_3 DELAY_NS(0)
 
 #if F_CPU >= 20000000
-  #define CPU_ST7920_DELAY_1 DELAY_0_NOP
-  #define CPU_ST7920_DELAY_2 DELAY_0_NOP
-  #define CPU_ST7920_DELAY_3 DELAY_1_NOP
+  #define CPU_ST7920_DELAY_1 DELAY_NS(0)
+  #define CPU_ST7920_DELAY_2 DELAY_NS(0)
+  #define CPU_ST7920_DELAY_3 DELAY_NS(50)
 #elif MB(3DRAG) || MB(K8200) || MB(K8400) || MB(SILVER_GATE)
-  #define CPU_ST7920_DELAY_1 DELAY_0_NOP
-  #define CPU_ST7920_DELAY_2 DELAY_3_NOP
-  #define CPU_ST7920_DELAY_3 DELAY_0_NOP
+  #define CPU_ST7920_DELAY_1 DELAY_NS(0)
+  #define CPU_ST7920_DELAY_2 DELAY_NS(188)
+  #define CPU_ST7920_DELAY_3 DELAY_NS(0)
 #elif MB(MINIRAMBO)
-  #define CPU_ST7920_DELAY_1 DELAY_0_NOP
-  #define CPU_ST7920_DELAY_2 DELAY_4_NOP
-  #define CPU_ST7920_DELAY_3 DELAY_0_NOP
+  #define CPU_ST7920_DELAY_1 DELAY_NS(0)
+  #define CPU_ST7920_DELAY_2 DELAY_NS(250)
+  #define CPU_ST7920_DELAY_3 DELAY_NS(0)
 #elif MB(RAMBO)
-  #define CPU_ST7920_DELAY_1 DELAY_0_NOP
-  #define CPU_ST7920_DELAY_2 DELAY_0_NOP
-  #define CPU_ST7920_DELAY_3 DELAY_0_NOP
+  #define CPU_ST7920_DELAY_1 DELAY_NS(0)
+  #define CPU_ST7920_DELAY_2 DELAY_NS(0)
+  #define CPU_ST7920_DELAY_3 DELAY_NS(0)
 #elif F_CPU == 16000000
-  #define CPU_ST7920_DELAY_1 DELAY_0_NOP
-  #define CPU_ST7920_DELAY_2 DELAY_0_NOP
-  #define CPU_ST7920_DELAY_3 DELAY_1_NOP
+  #define CPU_ST7920_DELAY_1 DELAY_NS(0)
+  #define CPU_ST7920_DELAY_2 DELAY_NS(0)
+  #define CPU_ST7920_DELAY_3 DELAY_NS(63)
 #else
   #error "No valid condition for delays in 'ultralcd_st7920_u8glib_rrd.h'"
 #endif
@@ -95,8 +96,8 @@ static void ST7920_SWSPI_SND_8BIT(uint8_t val) {
   ST7920_SND_BIT; // 8
 }
 
-#if defined(DOGM_SPI_DELAY_US) && DOGM_SPI_DELAY_US > 0
-  #define U8G_DELAY() delayMicroseconds(DOGM_SPI_DELAY_US)
+#if DOGM_SPI_DELAY_US > 0
+  #define U8G_DELAY() DELAY_US(DOGM_SPI_DELAY_US)
 #else
   #define U8G_DELAY() u8g_10MicroDelay()
 #endif