diff --git a/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.cpp b/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.cpp
index b2aaf5ea3f61a260dfd3e96e209b821b7c08ce9d..ac2589272470205138cf63844abd1437d0f6c4af 100644
--- a/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.cpp
+++ b/Marlin/src/HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.cpp
@@ -37,7 +37,7 @@
 
 #include "../../../inc/MarlinConfig.h"
 #include "../../../Marlin.h"
-#include "../../../module/stepper_indirection.h"
+#include "../../../module/stepper/indirection.h"
 #include "../../../module/printcounter.h"
 #include "../../../libs/duration_t.h"
 #include "../../../libs/hex_print_routines.h"
diff --git a/Marlin/src/Marlin.cpp b/Marlin/src/Marlin.cpp
index 68f37d2a72534aca8ec6ddc838f6fa5caf166971..376bd6dc910331e85c0d65d56607196026e427ce 100644
--- a/Marlin/src/Marlin.cpp
+++ b/Marlin/src/Marlin.cpp
@@ -45,7 +45,7 @@
 
 #include "HAL/shared/Delay.h"
 
-#include "module/stepper_indirection.h"
+#include "module/stepper/indirection.h"
 
 #ifdef ARDUINO
   #include <pins_arduino.h>
diff --git a/Marlin/src/feature/controllerfan.cpp b/Marlin/src/feature/controllerfan.cpp
index 00d895aa680500bbffe958fd3256dde1eb25e317..1a458a2a5574ec0c58e8ac88c23d0ec082f3b2c8 100644
--- a/Marlin/src/feature/controllerfan.cpp
+++ b/Marlin/src/feature/controllerfan.cpp
@@ -24,7 +24,7 @@
 
 #if ENABLED(USE_CONTROLLER_FAN)
 
-#include "../module/stepper_indirection.h"
+#include "../module/stepper/indirection.h"
 #include "../module/temperature.h"
 
 uint8_t controllerfan_speed;
diff --git a/Marlin/src/feature/power.cpp b/Marlin/src/feature/power.cpp
index 2ff82331b32142c13f4482b157babe8a8150f4d4..777c7a052eaefd49f71d7e50b2467c79e765ad1d 100644
--- a/Marlin/src/feature/power.cpp
+++ b/Marlin/src/feature/power.cpp
@@ -30,7 +30,7 @@
 
 #include "power.h"
 #include "../module/temperature.h"
-#include "../module/stepper_indirection.h"
+#include "../module/stepper/indirection.h"
 #include "../Marlin.h"
 
 Power powerManager;
diff --git a/Marlin/src/feature/prusa_MMU2/mmu2.cpp b/Marlin/src/feature/prusa_MMU2/mmu2.cpp
index 57d0418c4fc75ec1a306445290c8ef6adb998de8..0baa5bd95864cd0bd7cf1064c2d896d3175a7a96 100644
--- a/Marlin/src/feature/prusa_MMU2/mmu2.cpp
+++ b/Marlin/src/feature/prusa_MMU2/mmu2.cpp
@@ -35,7 +35,7 @@ MMU2 mmu2;
 #include "../../libs/nozzle.h"
 #include "../../module/temperature.h"
 #include "../../module/planner.h"
-#include "../../module/stepper_indirection.h"
+#include "../../module/stepper/indirection.h"
 #include "../../Marlin.h"
 
 #if ENABLED(HOST_PROMPT_SUPPORT)
diff --git a/Marlin/src/feature/tmc_util.cpp b/Marlin/src/feature/tmc_util.cpp
index b3ea6e7cb7ea1ba2225f9b620da1107a2529a1b7..428a5986fadb6e1d8d939fad5d0baca77c00e8c4 100644
--- a/Marlin/src/feature/tmc_util.cpp
+++ b/Marlin/src/feature/tmc_util.cpp
@@ -27,7 +27,7 @@
 #include "tmc_util.h"
 #include "../Marlin.h"
 
-#include "../module/stepper_indirection.h"
+#include "../module/stepper/indirection.h"
 #include "../module/printcounter.h"
 #include "../libs/duration_t.h"
 #include "../gcode/gcode.h"
diff --git a/Marlin/src/gcode/feature/L6470/M122.cpp b/Marlin/src/gcode/feature/L6470/M122.cpp
index 2e50d8ff79055437691e6521a63ddcbfcd93d2ae..1fbb72aacf3ad05e10accef27518bfc83b44e75a 100644
--- a/Marlin/src/gcode/feature/L6470/M122.cpp
+++ b/Marlin/src/gcode/feature/L6470/M122.cpp
@@ -26,7 +26,7 @@
 
 #include "../../gcode.h"
 #include "../../../libs/L6470/L6470_Marlin.h"
-#include "../../../module/stepper_indirection.h"
+#include "../../../module/stepper/indirection.h"
 
 inline void echo_yes_no(const bool yes) { serialprintPGM(yes ? PSTR(" YES") : PSTR(" NO ")); }
 
diff --git a/Marlin/src/gcode/feature/L6470/M906.cpp b/Marlin/src/gcode/feature/L6470/M906.cpp
index df0c085bc697354d72eb6501f6d9fc2502ea18ef..7f48033190a1ce0f2ca4d6f4f6f994d142cea3bb 100644
--- a/Marlin/src/gcode/feature/L6470/M906.cpp
+++ b/Marlin/src/gcode/feature/L6470/M906.cpp
@@ -26,7 +26,7 @@
 
 #include "../../gcode.h"
 #include "../../../libs/L6470/L6470_Marlin.h"
-#include "../../../module/stepper_indirection.h"
+#include "../../../module/stepper/indirection.h"
 #include "../../../module/planner.h"
 
 #define DEBUG_OUT ENABLED(L6470_CHITCHAT)
diff --git a/Marlin/src/gcode/feature/L6470/M916-918.cpp b/Marlin/src/gcode/feature/L6470/M916-918.cpp
index 0e79d5f233d76320003387f8f8625662193735c2..b756c6cf88e54cf2b6af10fd6beaf02c31b77a8e 100644
--- a/Marlin/src/gcode/feature/L6470/M916-918.cpp
+++ b/Marlin/src/gcode/feature/L6470/M916-918.cpp
@@ -25,7 +25,7 @@
 #if HAS_DRIVER(L6470)
 
 #include "../../gcode.h"
-#include "../../../module/stepper_indirection.h"
+#include "../../../module/stepper/indirection.h"
 #include "../../../module/planner.h"
 #include "../../../libs/L6470/L6470_Marlin.h"
 
diff --git a/Marlin/src/gcode/feature/trinamic/M569.cpp b/Marlin/src/gcode/feature/trinamic/M569.cpp
index 6463889c2a2527099814846916218e4b956cbd9c..e8239838d79c01bbde731b5edae1b116a7ee4372 100644
--- a/Marlin/src/gcode/feature/trinamic/M569.cpp
+++ b/Marlin/src/gcode/feature/trinamic/M569.cpp
@@ -26,7 +26,7 @@
 
 #include "../../gcode.h"
 #include "../../../feature/tmc_util.h"
-#include "../../../module/stepper_indirection.h"
+#include "../../../module/stepper/indirection.h"
 
 template<typename TMC>
 void tmc_say_stealth_status(TMC &st) {
diff --git a/Marlin/src/gcode/feature/trinamic/M906.cpp b/Marlin/src/gcode/feature/trinamic/M906.cpp
index ba57fbb4ce380845ea9ac41242edc4ecf3080d83..072f7ba1fdd7aeb25f4c5f96b462251bd3790ce8 100644
--- a/Marlin/src/gcode/feature/trinamic/M906.cpp
+++ b/Marlin/src/gcode/feature/trinamic/M906.cpp
@@ -26,7 +26,7 @@
 
 #include "../../gcode.h"
 #include "../../../feature/tmc_util.h"
-#include "../../../module/stepper_indirection.h"
+#include "../../../module/stepper/indirection.h"
 
 /**
  * M906: Set motor current in milliamps.
diff --git a/Marlin/src/gcode/feature/trinamic/M911-M914.cpp b/Marlin/src/gcode/feature/trinamic/M911-M914.cpp
index 459c3f6aa8464e2f919cfd50765a902798b8ace4..27a0be9a64cc0cac1c7846db447d4d5b55dce38a 100644
--- a/Marlin/src/gcode/feature/trinamic/M911-M914.cpp
+++ b/Marlin/src/gcode/feature/trinamic/M911-M914.cpp
@@ -26,7 +26,7 @@
 
 #include "../../gcode.h"
 #include "../../../feature/tmc_util.h"
-#include "../../../module/stepper_indirection.h"
+#include "../../../module/stepper/indirection.h"
 #include "../../../module/planner.h"
 #include "../../queue.h"
 
diff --git a/Marlin/src/gcode/host/M114.cpp b/Marlin/src/gcode/host/M114.cpp
index b4b2f58d33370cfefebcc46124a6cfed27540fe9..58d7ef3e33c61d6c664a96521b02b238bb77b304 100644
--- a/Marlin/src/gcode/host/M114.cpp
+++ b/Marlin/src/gcode/host/M114.cpp
@@ -31,7 +31,7 @@
   #if HAS_DRIVER(L6470)
     //C:\Users\bobku\Documents\GitHub\Marlin-Bob-2\Marlin\src\gcode\host\M114.cpp
     //C:\Users\bobku\Documents\GitHub\Marlin-Bob-2\Marlin\src\module\bob_L6470.cpp
-    #include "../../module/L6470/L6470_Marlin.h"
+    #include "../../libs/L6470/L6470_Marlin.h"
     #define DEBUG_OUT ENABLED(L6470_CHITCHAT)
     #include "../../core/debug_out.h"
   #endif
diff --git a/Marlin/src/lcd/extensible_ui/ui_api.cpp b/Marlin/src/lcd/extensible_ui/ui_api.cpp
index d24e636b129b8eb213575626b64348fb39bb1c45..43ffca36553f7ab6fb1c369e864af6e3da44cf61 100644
--- a/Marlin/src/lcd/extensible_ui/ui_api.cpp
+++ b/Marlin/src/lcd/extensible_ui/ui_api.cpp
@@ -77,7 +77,7 @@
 
 #if HAS_TRINAMIC
   #include "../../feature/tmc_util.h"
-  #include "../../module/stepper_indirection.h"
+  #include "../../module/stepper/indirection.h"
 #endif
 
 #include "ui_api.h"
diff --git a/Marlin/src/lcd/menu/menu_tmc.cpp b/Marlin/src/lcd/menu/menu_tmc.cpp
index 8218463dafe41902242f4550b14f5cd104ba52aa..917b39ebfad68e16f3dbfd780bfb652399286d27 100644
--- a/Marlin/src/lcd/menu/menu_tmc.cpp
+++ b/Marlin/src/lcd/menu/menu_tmc.cpp
@@ -29,7 +29,7 @@
 #if HAS_TRINAMIC && HAS_LCD_MENU
 
 #include "menu.h"
-#include "../../module/stepper_indirection.h"
+#include "../../module/stepper/indirection.h"
 #include "../../feature/tmc_util.h"
 
 #define TMC_EDIT_STORED_I_RMS(ST,MSG) MENU_ITEM_EDIT_CALLBACK(uint16_4, MSG, &stepper##ST.val_mA, 100, 3000, refresh_stepper_current_##ST)
diff --git a/Marlin/src/libs/L6470/L6470_Marlin.cpp b/Marlin/src/libs/L6470/L6470_Marlin.cpp
index ae90f761f7034862f86be67f715c39a19bfa6f9c..7dc2b2d1f8dc8db5b0c627b3426b28243a6061d2 100644
--- a/Marlin/src/libs/L6470/L6470_Marlin.cpp
+++ b/Marlin/src/libs/L6470/L6470_Marlin.cpp
@@ -21,7 +21,7 @@
  */
 
 /**
- *  The monitor_driver routines are a close copy of the TMC code
+ * The monitor_driver routines are a close copy of the TMC code
  */
 
 #include "../../inc/MarlinConfig.h"
@@ -32,9 +32,9 @@
 
 L6470_Marlin L6470;
 
-#include "../stepper_indirection.h"
+#include "../../module/stepper/indirection.h"
+#include "../../module/planner.h"
 #include "../../gcode/gcode.h"
-#include "../planner.h"
 
 #define DEBUG_OUT ENABLED(L6470_CHITCHAT)
 #include "../../core/debug_out.h"
diff --git a/Marlin/src/module/configuration_store.cpp b/Marlin/src/module/configuration_store.cpp
index 2bcfdb6047186519e2d2aaf2235c8ac787806c74..190bde400d1b821532dc0ca469f067507efb180b 100644
--- a/Marlin/src/module/configuration_store.cpp
+++ b/Marlin/src/module/configuration_store.cpp
@@ -112,7 +112,7 @@
 #endif
 
 #if HAS_TRINAMIC
-  #include "stepper_indirection.h"
+  #include "stepper/indirection.h"
   #include "../feature/tmc_util.h"
 #endif
 
diff --git a/Marlin/src/module/delta.cpp b/Marlin/src/module/delta.cpp
index 88485605b90d5dc1c141880c344eb3f8182f9d76..e44fd86200049147609cd27a43fef1568fc8a6ef 100644
--- a/Marlin/src/module/delta.cpp
+++ b/Marlin/src/module/delta.cpp
@@ -43,7 +43,7 @@
 
 #if ENABLED(SENSORLESS_HOMING)
   #include "../feature/tmc_util.h"
-  #include "stepper_indirection.h"
+  #include "stepper/indirection.h"
 #endif
 
 #define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
diff --git a/Marlin/src/module/probe.cpp b/Marlin/src/module/probe.cpp
index 7e2a0deb5f2a9714c049cca022f0edcd744f2836..d20257fa3255b952af4816ac7c939478ecb0cd63 100644
--- a/Marlin/src/module/probe.cpp
+++ b/Marlin/src/module/probe.cpp
@@ -76,7 +76,7 @@ float zprobe_zoffset; // Initialized by settings.load()
 #endif
 
 #if QUIET_PROBING
-  #include "stepper_indirection.h"
+  #include "stepper/indirection.h"
 #endif
 
 #if ENABLED(EXTENSIBLE_UI)
diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h
index eca4a75c175719d49e40320b0de42cd533c075ad..e1d60fffce49277d81351fd555baff0fb3a381ff 100644
--- a/Marlin/src/module/stepper.h
+++ b/Marlin/src/module/stepper.h
@@ -218,7 +218,7 @@
 // Stepper class definition
 //
 
-#include "stepper_indirection.h"
+#include "stepper/indirection.h"
 
 #ifdef __AVR__
   #include "speed_lookuptable.h"
diff --git a/Marlin/src/module/stepper/L6470.cpp b/Marlin/src/module/stepper/L6470.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d682193aa985a45ffe0698f18fa63bced82ceb9b
--- /dev/null
+++ b/Marlin/src/module/stepper/L6470.cpp
@@ -0,0 +1,143 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2019 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/>.
+ *
+ */
+
+/**
+ * stepper/L6470.cpp
+ * Stepper driver indirection for L6470 drivers
+ */
+
+#include "../../inc/MarlinConfig.h"
+
+#if HAS_DRIVER(L6470)
+
+#include "L6470.h"
+
+#define _L6470_DEFINE(ST) L6470 stepper##ST((const int)L6470_CHAIN_SS_PIN)
+
+// L6470 Stepper objects
+#if AXIS_DRIVER_TYPE_X(L6470)
+  _L6470_DEFINE(X);
+#endif
+#if AXIS_DRIVER_TYPE_X2(L6470)
+  _L6470_DEFINE(X2);
+#endif
+#if AXIS_DRIVER_TYPE_Y(L6470)
+  _L6470_DEFINE(Y);
+#endif
+#if AXIS_DRIVER_TYPE_Y2(L6470)
+  _L6470_DEFINE(Y2);
+#endif
+#if AXIS_DRIVER_TYPE_Z(L6470)
+  _L6470_DEFINE(Z);
+#endif
+#if AXIS_DRIVER_TYPE_Z2(L6470)
+  _L6470_DEFINE(Z2);
+#endif
+#if AXIS_DRIVER_TYPE_Z3(L6470)
+  _L6470_DEFINE(Z3);
+#endif
+#if AXIS_DRIVER_TYPE_E0(L6470)
+  _L6470_DEFINE(E0);
+#endif
+#if AXIS_DRIVER_TYPE_E1(L6470)
+  _L6470_DEFINE(E1);
+#endif
+#if AXIS_DRIVER_TYPE_E2(L6470)
+  _L6470_DEFINE(E2);
+#endif
+#if AXIS_DRIVER_TYPE_E3(L6470)
+  _L6470_DEFINE(E3);
+#endif
+#if AXIS_DRIVER_TYPE_E4(L6470)
+  _L6470_DEFINE(E4);
+#endif
+#if AXIS_DRIVER_TYPE_E5(L6470)
+  _L6470_DEFINE(E5);
+#endif
+
+// not using L6470 library's init command because it
+// briefly sends power to the steppers
+
+#define _L6470_INIT_CHIP(Q) do{                             \
+  stepper##Q.resetDev();                                    \
+  stepper##Q.softFree();                                    \
+  stepper##Q.SetParam(L6470_CONFIG, CONFIG_PWM_DIV_1        \
+                                  | CONFIG_PWM_MUL_2        \
+                                  | CONFIG_SR_290V_us       \
+                                  | CONFIG_OC_SD_DISABLE    \
+                                  | CONFIG_VS_COMP_DISABLE  \
+                                  | CONFIG_SW_HARD_STOP     \
+                                  | CONFIG_INT_16MHZ);      \
+  stepper##Q.SetParam(L6470_KVAL_RUN, 0xFF);                \
+  stepper##Q.SetParam(L6470_KVAL_ACC, 0xFF);                \
+  stepper##Q.SetParam(L6470_KVAL_DEC, 0xFF);                \
+  stepper##Q.setMicroSteps(Q##_MICROSTEPS);                 \
+  stepper##Q.setOverCurrent(Q##_OVERCURRENT);               \
+  stepper##Q.setStallCurrent(Q##_STALLCURRENT);             \
+  stepper##Q.SetParam(L6470_KVAL_HOLD, Q##_MAX_VOLTAGE);    \
+  stepper##Q.SetParam(L6470_ABS_POS, 0);                    \
+  stepper##Q.getStatus();                                   \
+}while(0)
+
+void L6470_Marlin::init_to_defaults() {
+  #if AXIS_DRIVER_TYPE_X(L6470)
+    _L6470_INIT_CHIP(X);
+  #endif
+  #if AXIS_DRIVER_TYPE_X2(L6470)
+    _L6470_INIT_CHIP(X2);
+  #endif
+  #if AXIS_DRIVER_TYPE_Y(L6470)
+    _L6470_INIT_CHIP(Y);
+  #endif
+  #if AXIS_DRIVER_TYPE_Y2(L6470)
+    _L6470_INIT_CHIP(Y2);
+  #endif
+  #if AXIS_DRIVER_TYPE_Z(L6470)
+    _L6470_INIT_CHIP(Z);
+  #endif
+  #if AXIS_DRIVER_TYPE_Z2(L6470)
+    _L6470_INIT_CHIP(Z2);
+  #endif
+  #if AXIS_DRIVER_TYPE_Z3(L6470)
+    _L6470_INIT_CHIP(Z3);
+  #endif
+  #if AXIS_DRIVER_TYPE_E0(L6470)
+    _L6470_INIT_CHIP(E0);
+  #endif
+  #if AXIS_DRIVER_TYPE_E1(L6470)
+    _L6470_INIT_CHIP(E1);
+  #endif
+  #if AXIS_DRIVER_TYPE_E2(L6470)
+    _L6470_INIT_CHIP(E2);
+  #endif
+  #if AXIS_DRIVER_TYPE_E3(L6470)
+    _L6470_INIT_CHIP(E3);
+  #endif
+  #if AXIS_DRIVER_TYPE_E4(L6470)
+    _L6470_INIT_CHIP(E4);
+  #endif
+  #if AXIS_DRIVER_TYPE_E5(L6470)
+    _L6470_INIT_CHIP(E5);
+  #endif
+}
+
+#endif // L6470
diff --git a/Marlin/src/module/stepper/L6470.h b/Marlin/src/module/stepper/L6470.h
new file mode 100644
index 0000000000000000000000000000000000000000..8c731a80424ab3750bf5b4572220286772d5a0bb
--- /dev/null
+++ b/Marlin/src/module/stepper/L6470.h
@@ -0,0 +1,176 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2019 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/>.
+ *
+ */
+#pragma once
+
+/**
+ * stepper/L6470.h
+ * Stepper driver indirection for L6470 drivers
+ */
+
+#include "../../inc/MarlinConfig.h"
+#include "../../libs/L6470/L6470_Marlin.h"
+
+// L6470 has STEP on normal pins, but DIR/ENABLE via SPI
+#define L6470_WRITE_DIR_COMMAND(STATE,Q) do{ L6470_dir_commands[Q] = (STATE ?  dSPIN_STEP_CLOCK_REV : dSPIN_STEP_CLOCK_FWD); }while(0)
+
+// X Stepper
+#if AXIS_DRIVER_TYPE_X(L6470)
+  extern L6470 stepperX;
+  #define X_ENABLE_INIT NOOP
+  #define X_ENABLE_WRITE(STATE) NOOP
+  #define X_ENABLE_READ() (stepperX.getStatus() & STATUS_HIZ)
+  #define X_DIR_INIT NOOP
+  #define X_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,X)
+  #define X_DIR_READ() (stepperX.getStatus() & STATUS_DIR)
+#endif
+
+// Y Stepper
+#if AXIS_DRIVER_TYPE_Y(L6470)
+  extern L6470 stepperY;
+  #define Y_ENABLE_INIT NOOP
+  #define Y_ENABLE_WRITE(STATE) NOOP
+  #define Y_ENABLE_READ() (stepperY.getStatus() & STATUS_HIZ)
+  #define Y_DIR_INIT NOOP
+  #define Y_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,Y)
+  #define Y_DIR_READ() (stepperY.getStatus() & STATUS_DIR)
+#endif
+
+// Z Stepper
+#if AXIS_DRIVER_TYPE_Z(L6470)
+  extern L6470 stepperZ;
+  #define Z_ENABLE_INIT NOOP
+  #define Z_ENABLE_WRITE(STATE) NOOP
+  #define Z_ENABLE_READ() (stepperZ.getStatus() & STATUS_HIZ)
+  #define Z_DIR_INIT NOOP
+  #define Z_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,Z)
+  #define Z_DIR_READ() (stepperZ.getStatus() & STATUS_DIR)
+#endif
+
+// X2 Stepper
+#if HAS_X2_ENABLE && AXIS_DRIVER_TYPE_X2(L6470)
+  extern L6470 stepperX2;
+  #define X2_ENABLE_INIT NOOP
+  #define X2_ENABLE_WRITE(STATE) NOOP
+  #define X2_ENABLE_READ() (stepperX2.getStatus() & STATUS_HIZ)
+  #define X2_DIR_INIT NOOP
+  #define X2_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,X2)
+  #define X2_DIR_READ() (stepperX2.getStatus() & STATUS_DIR)
+#endif
+
+// Y2 Stepper
+#if HAS_Y2_ENABLE && AXIS_DRIVER_TYPE_Y2(L6470)
+  extern L6470 stepperY2;
+  #define Y2_ENABLE_INIT NOOP
+  #define Y2_ENABLE_WRITE(STATE) NOOP
+  #define Y2_ENABLE_READ() (stepperY2.getStatus() & STATUS_HIZ)
+  #define Y2_DIR_INIT NOOP
+  #define Y2_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,Y2)
+  #define Y2_DIR_READ() (stepperY2.getStatus() & STATUS_DIR)
+#endif
+
+// Z2 Stepper
+#if HAS_Z2_ENABLE && AXIS_DRIVER_TYPE_Z2(L6470)
+  extern L6470 stepperZ2;
+  #define Z2_ENABLE_INIT NOOP
+  #define Z2_ENABLE_WRITE(STATE) NOOP
+  #define Z2_ENABLE_READ() (stepperZ2.getStatus() & STATUS_HIZ)
+  #define Z2_DIR_INIT NOOP
+  #define Z2_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,Z2)
+  #define Z2_DIR_READ() (stepperZ2.getStatus() & STATUS_DIR)
+#endif
+
+// Z3 Stepper
+#if HAS_Z3_ENABLE && AXIS_DRIVER_TYPE_Z3(L6470)
+  extern L6470 stepperZ3;
+  #define Z3_ENABLE_INIT NOOP
+  #define Z3_ENABLE_WRITE(STATE) NOOP
+  #define Z3_ENABLE_READ() (stepperZ3.getStatus() & STATUS_HIZ)
+  #define Z3_DIR_INIT NOOP
+  #define Z3_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,Z3)
+  #define Z3_DIR_READ() (stepperZ3.getStatus() & STATUS_DIR)
+#endif
+
+// E0 Stepper
+#if AXIS_DRIVER_TYPE_E0(L6470)
+  extern L6470 stepperE0;
+  #define E0_ENABLE_INIT NOOP
+  #define E0_ENABLE_WRITE(STATE) NOOP
+  #define E0_ENABLE_READ() (stepperE0.getStatus() & STATUS_HIZ)
+  #define E0_DIR_INIT NOOP
+  #define E0_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,E0)
+  #define E0_DIR_READ() (stepperE0.getStatus() & STATUS_DIR)
+#endif
+
+// E1 Stepper
+#if AXIS_DRIVER_TYPE_E1(L6470)
+  extern L6470 stepperE1;
+  #define E1_ENABLE_INIT NOOP
+  #define E1_ENABLE_WRITE(STATE) NOOP
+  #define E1_ENABLE_READ() (stepperE1.getStatus() & STATUS_HIZ)
+  #define E1_DIR_INIT NOOP
+  #define E1_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,E1)
+  #define E1_DIR_READ() (stepperE1.getStatus() & STATUS_DIR)
+#endif
+
+// E2 Stepper
+#if AXIS_DRIVER_TYPE_E2(L6470)
+  extern L6470 stepperE2;
+  #define E2_ENABLE_INIT NOOP
+  #define E2_ENABLE_WRITE(STATE) NOOP
+  #define E2_ENABLE_READ() (stepperE2.getStatus() & STATUS_HIZ)
+  #define E2_DIR_INIT NOOP
+  #define E2_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,E2)
+  #define E2_DIR_READ() (stepperE2.getStatus() & STATUS_DIR)
+#endif
+
+// E3 Stepper
+#if AXIS_DRIVER_TYPE_E3(L6470)
+  extern L6470 stepperE3;
+  #define E3_ENABLE_INIT NOOP
+  #define E3_ENABLE_WRITE(STATE) NOOP
+  #define E3_ENABLE_READ() (stepperE3.getStatus() & STATUS_HIZ)
+  #define E3_DIR_INIT NOOP
+  #define E3_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,E3)
+  #define E3_DIR_READ() (stepperE3.getStatus() & STATUS_DIR)
+#endif
+
+// E4 Stepper
+#if AXIS_DRIVER_TYPE_E4(L6470)
+  extern L6470 stepperE4;
+  #define E4_ENABLE_INIT NOOP
+  #define E4_ENABLE_WRITE(STATE) NOOP
+  #define E4_ENABLE_READ() (stepperE4.getStatus() & STATUS_HIZ)
+  #define E4_DIR_INIT NOOP
+  #define E4_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,E4)
+  #define E4_DIR_READ() (stepperE4.getStatus() & STATUS_DIR)
+#endif
+
+// E5 Stepper
+#if AXIS_DRIVER_TYPE_E5(L6470)
+  extern L6470 stepperE5;
+  #define E5_ENABLE_INIT NOOP
+  #define E5_ENABLE_WRITE(STATE) NOOP
+  #define E5_ENABLE_READ() (stepperE5.getStatus() & STATUS_HIZ)
+  #define E5_DIR_INIT NOOP
+  #define E5_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,E5)
+  #define E5_DIR_READ() (stepperE5.getStatus() & STATUS_DIR)
+#endif
diff --git a/Marlin/src/module/stepper/TMC26X.cpp b/Marlin/src/module/stepper/TMC26X.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8acb735c9db6a9abe68fa38de71a9f75e8387aa4
--- /dev/null
+++ b/Marlin/src/module/stepper/TMC26X.cpp
@@ -0,0 +1,126 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2019 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/>.
+ *
+ */
+
+/**
+ * stepper/TMC26X.cpp
+ * Stepper driver indirection for TMC26X drivers
+ */
+
+#include "../../inc/MarlinConfig.h"
+
+//
+// TMC26X Driver objects and inits
+//
+#if HAS_DRIVER(TMC26X)
+
+#include "TMC26X.h"
+
+#define _TMC26X_DEFINE(ST) TMC26XStepper stepper##ST(200, ST##_CS_PIN, ST##_STEP_PIN, ST##_DIR_PIN, ST##_MAX_CURRENT, ST##_SENSE_RESISTOR)
+
+#if AXIS_DRIVER_TYPE_X(TMC26X)
+  _TMC26X_DEFINE(X);
+#endif
+#if AXIS_DRIVER_TYPE_X2(TMC26X)
+  _TMC26X_DEFINE(X2);
+#endif
+#if AXIS_DRIVER_TYPE_Y(TMC26X)
+  _TMC26X_DEFINE(Y);
+#endif
+#if AXIS_DRIVER_TYPE_Y2(TMC26X)
+  _TMC26X_DEFINE(Y2);
+#endif
+#if AXIS_DRIVER_TYPE_Z(TMC26X)
+  _TMC26X_DEFINE(Z);
+#endif
+#if AXIS_DRIVER_TYPE_Z2(TMC26X)
+  _TMC26X_DEFINE(Z2);
+#endif
+#if AXIS_DRIVER_TYPE_Z3(TMC26X)
+  _TMC26X_DEFINE(Z3);
+#endif
+#if AXIS_DRIVER_TYPE_E0(TMC26X)
+  _TMC26X_DEFINE(E0);
+#endif
+#if AXIS_DRIVER_TYPE_E1(TMC26X)
+  _TMC26X_DEFINE(E1);
+#endif
+#if AXIS_DRIVER_TYPE_E2(TMC26X)
+  _TMC26X_DEFINE(E2);
+#endif
+#if AXIS_DRIVER_TYPE_E3(TMC26X)
+  _TMC26X_DEFINE(E3);
+#endif
+#if AXIS_DRIVER_TYPE_E4(TMC26X)
+  _TMC26X_DEFINE(E4);
+#endif
+#if AXIS_DRIVER_TYPE_E5(TMC26X)
+  _TMC26X_DEFINE(E5);
+#endif
+
+#define _TMC26X_INIT(A) do{ \
+  stepper##A.setMicrosteps(A##_MICROSTEPS); \
+  stepper##A.start(); \
+}while(0)
+
+void tmc26x_init_to_defaults() {
+  #if AXIS_DRIVER_TYPE_X(TMC26X)
+    _TMC26X_INIT(X);
+  #endif
+  #if AXIS_DRIVER_TYPE_X2(TMC26X)
+    _TMC26X_INIT(X2);
+  #endif
+  #if AXIS_DRIVER_TYPE_Y(TMC26X)
+    _TMC26X_INIT(Y);
+  #endif
+  #if AXIS_DRIVER_TYPE_Y2(TMC26X)
+    _TMC26X_INIT(Y2);
+  #endif
+  #if AXIS_DRIVER_TYPE_Z(TMC26X)
+    _TMC26X_INIT(Z);
+  #endif
+  #if AXIS_DRIVER_TYPE_Z2(TMC26X)
+    _TMC26X_INIT(Z2);
+  #endif
+  #if AXIS_DRIVER_TYPE_Z3(TMC26X)
+    _TMC26X_INIT(Z3);
+  #endif
+  #if AXIS_DRIVER_TYPE_E0(TMC26X)
+    _TMC26X_INIT(E0);
+  #endif
+  #if AXIS_DRIVER_TYPE_E1(TMC26X)
+    _TMC26X_INIT(E1);
+  #endif
+  #if AXIS_DRIVER_TYPE_E2(TMC26X)
+    _TMC26X_INIT(E2);
+  #endif
+  #if AXIS_DRIVER_TYPE_E3(TMC26X)
+    _TMC26X_INIT(E3);
+  #endif
+  #if AXIS_DRIVER_TYPE_E4(TMC26X)
+    _TMC26X_INIT(E4);
+  #endif
+  #if AXIS_DRIVER_TYPE_E5(TMC26X)
+    _TMC26X_INIT(E5);
+  #endif
+}
+
+#endif // TMC26X
diff --git a/Marlin/src/module/stepper/TMC26X.h b/Marlin/src/module/stepper/TMC26X.h
new file mode 100644
index 0000000000000000000000000000000000000000..d195a50c0395d9da94e5068c37129d443b6072cb
--- /dev/null
+++ b/Marlin/src/module/stepper/TMC26X.h
@@ -0,0 +1,144 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2019 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/>.
+ *
+ */
+#pragma once
+
+/**
+ * stepper/TMC26X.h
+ * Stepper driver indirection for TMC26X drivers
+ */
+
+#include "../../inc/MarlinConfig.h"
+
+// TMC26X drivers have STEP/DIR on normal pins, but ENABLE via SPI
+
+#include <SPI.h>
+#if defined(STM32GENERIC) && defined(STM32F7)
+ #include "../../HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.h"
+#else
+ #include <TMC26XStepper.h>
+#endif
+
+void tmc26x_init_to_defaults();
+
+// X Stepper
+#if AXIS_DRIVER_TYPE_X(TMC26X)
+  extern TMC26XStepper stepperX;
+  #define X_ENABLE_INIT NOOP
+  #define X_ENABLE_WRITE(STATE) stepperX.setEnabled(STATE)
+  #define X_ENABLE_READ() stepperX.isEnabled()
+#endif
+
+// Y Stepper
+#if AXIS_DRIVER_TYPE_Y(TMC26X)
+  extern TMC26XStepper stepperY;
+  #define Y_ENABLE_INIT NOOP
+  #define Y_ENABLE_WRITE(STATE) stepperY.setEnabled(STATE)
+  #define Y_ENABLE_READ() stepperY.isEnabled()
+#endif
+
+// Z Stepper
+#if AXIS_DRIVER_TYPE_Z(TMC26X)
+  extern TMC26XStepper stepperZ;
+  #define Z_ENABLE_INIT NOOP
+  #define Z_ENABLE_WRITE(STATE) stepperZ.setEnabled(STATE)
+  #define Z_ENABLE_READ() stepperZ.isEnabled()
+#endif
+
+// X2 Stepper
+#if HAS_X2_ENABLE && AXIS_DRIVER_TYPE_X2(TMC26X)
+  extern TMC26XStepper stepperX2;
+  #define X2_ENABLE_INIT NOOP
+  #define X2_ENABLE_WRITE(STATE) stepperX2.setEnabled(STATE)
+  #define X2_ENABLE_READ() stepperX2.isEnabled()
+#endif
+
+// Y2 Stepper
+#if HAS_Y2_ENABLE && AXIS_DRIVER_TYPE_Y2(TMC26X)
+  extern TMC26XStepper stepperY2;
+  #define Y2_ENABLE_INIT NOOP
+  #define Y2_ENABLE_WRITE(STATE) stepperY2.setEnabled(STATE)
+  #define Y2_ENABLE_READ() stepperY2.isEnabled()
+#endif
+
+// Z2 Stepper
+#if HAS_Z2_ENABLE && AXIS_DRIVER_TYPE_Z2(TMC26X)
+  extern TMC26XStepper stepperZ2;
+  #define Z2_ENABLE_INIT NOOP
+  #define Z2_ENABLE_WRITE(STATE) stepperZ2.setEnabled(STATE)
+  #define Z2_ENABLE_READ() stepperZ2.isEnabled()
+#endif
+
+// Z3 Stepper
+#if HAS_Z3_ENABLE && ENABLED(Z3_IS_TMC26X)
+  extern TMC26XStepper stepperZ3;
+  #define Z3_ENABLE_INIT NOOP
+  #define Z3_ENABLE_WRITE(STATE) stepperZ3.setEnabled(STATE)
+  #define Z3_ENABLE_READ() stepperZ3.isEnabled()
+#endif
+
+// E0 Stepper
+#if AXIS_DRIVER_TYPE_E0(TMC26X)
+  extern TMC26XStepper stepperE0;
+  #define E0_ENABLE_INIT NOOP
+  #define E0_ENABLE_WRITE(STATE) stepperE0.setEnabled(STATE)
+  #define E0_ENABLE_READ() stepperE0.isEnabled()
+#endif
+
+// E1 Stepper
+#if AXIS_DRIVER_TYPE_E1(TMC26X)
+  extern TMC26XStepper stepperE1;
+  #define E1_ENABLE_INIT NOOP
+  #define E1_ENABLE_WRITE(STATE) stepperE1.setEnabled(STATE)
+  #define E1_ENABLE_READ() stepperE1.isEnabled()
+#endif
+
+// E2 Stepper
+#if AXIS_DRIVER_TYPE_E2(TMC26X)
+  extern TMC26XStepper stepperE2;
+  #define E2_ENABLE_INIT NOOP
+  #define E2_ENABLE_WRITE(STATE) stepperE2.setEnabled(STATE)
+  #define E2_ENABLE_READ() stepperE2.isEnabled()
+#endif
+
+// E3 Stepper
+#if AXIS_DRIVER_TYPE_E3(TMC26X)
+  extern TMC26XStepper stepperE3;
+  #define E3_ENABLE_INIT NOOP
+  #define E3_ENABLE_WRITE(STATE) stepperE3.setEnabled(STATE)
+  #define E3_ENABLE_READ() stepperE3.isEnabled()
+#endif
+
+// E4 Stepper
+#if AXIS_DRIVER_TYPE_E4(TMC26X)
+  extern TMC26XStepper stepperE4;
+  #define E4_ENABLE_INIT NOOP
+  #define E4_ENABLE_WRITE(STATE) stepperE4.setEnabled(STATE)
+  #define E4_ENABLE_READ() stepperE4.isEnabled()
+#endif
+
+// E5 Stepper
+#if AXIS_DRIVER_TYPE_E5(TMC26X)
+  extern TMC26XStepper stepperE5;
+  #define E5_ENABLE_INIT NOOP
+  #define E5_ENABLE_WRITE(STATE) stepperE5.setEnabled(STATE)
+  #define E5_ENABLE_READ() stepperE5.isEnabled()
+#endif
diff --git a/Marlin/src/module/stepper/indirection.cpp b/Marlin/src/module/stepper/indirection.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2037c1b84e16c581669e21257cb6468e1956ed66
--- /dev/null
+++ b/Marlin/src/module/stepper/indirection.cpp
@@ -0,0 +1,53 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2019 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/>.
+ *
+ */
+
+/**
+ * stepper/indirection.cpp
+ *
+ * Stepper motor driver indirection to allow some stepper functions to
+ * be done via SPI/I2c instead of direct pin manipulation.
+ *
+ * Copyright (c) 2015 Dominik Wenger
+ */
+
+#include "../../inc/MarlinConfig.h"
+#include "indirection.h"
+
+void restore_stepper_drivers() {
+  #if HAS_TRINAMIC
+    restore_trinamic_drivers();
+  #endif
+}
+
+void reset_stepper_drivers() {
+  #if HAS_DRIVER(TMC26X)
+    tmc26x_init_to_defaults();
+  #endif
+
+  #if HAS_DRIVER(L6470)
+    L6470.init_to_defaults();
+  #endif
+
+  #if HAS_TRINAMIC
+    reset_trinamic_drivers();
+  #endif
+}
diff --git a/Marlin/src/module/stepper/indirection.h b/Marlin/src/module/stepper/indirection.h
new file mode 100644
index 0000000000000000000000000000000000000000..ed87fde83cb8070208feb1e3a18d76f043526713
--- /dev/null
+++ b/Marlin/src/module/stepper/indirection.h
@@ -0,0 +1,399 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2019 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/>.
+ *
+ */
+#pragma once
+
+/**
+ * stepper/indirection.h
+ *
+ * Stepper motor driver indirection to allow some stepper functions to
+ * be done via SPI/I2c instead of direct pin manipulation.
+ *
+ * Copyright (c) 2015 Dominik Wenger
+ */
+
+#include "../../inc/MarlinConfig.h"
+
+#if HAS_DRIVER(L6470)
+  #include "L6470.h"
+#endif
+
+#if HAS_DRIVER(TMC26X)
+  #include "TMC26X.h"
+#endif
+
+#if HAS_TRINAMIC
+  #include "trinamic.h"
+#endif
+
+void restore_stepper_drivers();  // Called by PSU_ON
+void reset_stepper_drivers();    // Called by settings.load / settings.reset
+
+// X Stepper
+#ifndef X_ENABLE_INIT
+  #define X_ENABLE_INIT SET_OUTPUT(X_ENABLE_PIN)
+  #define X_ENABLE_WRITE(STATE) WRITE(X_ENABLE_PIN,STATE)
+  #define X_ENABLE_READ() READ(X_ENABLE_PIN)
+#endif
+#ifndef X_DIR_INIT
+  #define X_DIR_INIT SET_OUTPUT(X_DIR_PIN)
+  #define X_DIR_WRITE(STATE) WRITE(X_DIR_PIN,STATE)
+  #define X_DIR_READ() READ(X_DIR_PIN)
+#endif
+#define X_STEP_INIT SET_OUTPUT(X_STEP_PIN)
+#ifndef X_STEP_WRITE
+  #define X_STEP_WRITE(STATE) WRITE(X_STEP_PIN,STATE)
+#endif
+#define X_STEP_READ READ(X_STEP_PIN)
+
+// Y Stepper
+#ifndef Y_ENABLE_INIT
+  #define Y_ENABLE_INIT SET_OUTPUT(Y_ENABLE_PIN)
+  #define Y_ENABLE_WRITE(STATE) WRITE(Y_ENABLE_PIN,STATE)
+  #define Y_ENABLE_READ() READ(Y_ENABLE_PIN)
+#endif
+#ifndef Y_DIR_INIT
+  #define Y_DIR_INIT SET_OUTPUT(Y_DIR_PIN)
+  #define Y_DIR_WRITE(STATE) WRITE(Y_DIR_PIN,STATE)
+  #define Y_DIR_READ() READ(Y_DIR_PIN)
+#endif
+#define Y_STEP_INIT SET_OUTPUT(Y_STEP_PIN)
+#ifndef Y_STEP_WRITE
+  #define Y_STEP_WRITE(STATE) WRITE(Y_STEP_PIN,STATE)
+#endif
+#define Y_STEP_READ READ(Y_STEP_PIN)
+
+// Z Stepper
+#ifndef Z_ENABLE_INIT
+  #define Z_ENABLE_INIT SET_OUTPUT(Z_ENABLE_PIN)
+  #define Z_ENABLE_WRITE(STATE) WRITE(Z_ENABLE_PIN,STATE)
+  #define Z_ENABLE_READ() READ(Z_ENABLE_PIN)
+#endif
+#ifndef Z_DIR_INIT
+  #define Z_DIR_INIT SET_OUTPUT(Z_DIR_PIN)
+  #define Z_DIR_WRITE(STATE) WRITE(Z_DIR_PIN,STATE)
+  #define Z_DIR_READ() READ(Z_DIR_PIN)
+#endif
+#define Z_STEP_INIT SET_OUTPUT(Z_STEP_PIN)
+#ifndef Z_STEP_WRITE
+  #define Z_STEP_WRITE(STATE) WRITE(Z_STEP_PIN,STATE)
+#endif
+#define Z_STEP_READ READ(Z_STEP_PIN)
+
+// X2 Stepper
+#if HAS_X2_ENABLE
+  #ifndef X2_ENABLE_INIT
+    #define X2_ENABLE_INIT SET_OUTPUT(X2_ENABLE_PIN)
+    #define X2_ENABLE_WRITE(STATE) WRITE(X2_ENABLE_PIN,STATE)
+    #define X2_ENABLE_READ() READ(X2_ENABLE_PIN)
+  #endif
+  #ifndef X2_DIR_INIT
+    #define X2_DIR_INIT SET_OUTPUT(X2_DIR_PIN)
+    #define X2_DIR_WRITE(STATE) WRITE(X2_DIR_PIN,STATE)
+    #define X2_DIR_READ() READ(X2_DIR_PIN)
+  #endif
+  #define X2_STEP_INIT SET_OUTPUT(X2_STEP_PIN)
+  #ifndef X2_STEP_WRITE
+    #define X2_STEP_WRITE(STATE) WRITE(X2_STEP_PIN,STATE)
+  #endif
+  #define X2_STEP_READ READ(X2_STEP_PIN)
+#endif
+
+// Y2 Stepper
+#if HAS_Y2_ENABLE
+  #ifndef Y2_ENABLE_INIT
+    #define Y2_ENABLE_INIT SET_OUTPUT(Y2_ENABLE_PIN)
+    #define Y2_ENABLE_WRITE(STATE) WRITE(Y2_ENABLE_PIN,STATE)
+    #define Y2_ENABLE_READ() READ(Y2_ENABLE_PIN)
+  #endif
+  #ifndef Y2_DIR_INIT
+    #define Y2_DIR_INIT SET_OUTPUT(Y2_DIR_PIN)
+    #define Y2_DIR_WRITE(STATE) WRITE(Y2_DIR_PIN,STATE)
+    #define Y2_DIR_READ() READ(Y2_DIR_PIN)
+  #endif
+  #define Y2_STEP_INIT SET_OUTPUT(Y2_STEP_PIN)
+  #ifndef Y2_STEP_WRITE
+    #define Y2_STEP_WRITE(STATE) WRITE(Y2_STEP_PIN,STATE)
+  #endif
+  #define Y2_STEP_READ READ(Y2_STEP_PIN)
+#else
+  #define Y2_DIR_WRITE(STATE) NOOP
+#endif
+
+// Z2 Stepper
+#if HAS_Z2_ENABLE
+  #ifndef Z2_ENABLE_INIT
+    #define Z2_ENABLE_INIT SET_OUTPUT(Z2_ENABLE_PIN)
+    #define Z2_ENABLE_WRITE(STATE) WRITE(Z2_ENABLE_PIN,STATE)
+    #define Z2_ENABLE_READ() READ(Z2_ENABLE_PIN)
+  #endif
+  #ifndef Z2_DIR_INIT
+    #define Z2_DIR_INIT SET_OUTPUT(Z2_DIR_PIN)
+    #define Z2_DIR_WRITE(STATE) WRITE(Z2_DIR_PIN,STATE)
+    #define Z2_DIR_READ() READ(Z2_DIR_PIN)
+  #endif
+  #define Z2_STEP_INIT SET_OUTPUT(Z2_STEP_PIN)
+  #ifndef Z2_STEP_WRITE
+    #define Z2_STEP_WRITE(STATE) WRITE(Z2_STEP_PIN,STATE)
+  #endif
+  #define Z2_STEP_READ READ(Z2_STEP_PIN)
+#else
+  #define Z2_DIR_WRITE(STATE) NOOP
+#endif
+
+// Z3 Stepper
+#if HAS_Z3_ENABLE
+  #ifndef Z3_ENABLE_INIT
+    #define Z3_ENABLE_INIT SET_OUTPUT(Z3_ENABLE_PIN)
+    #define Z3_ENABLE_WRITE(STATE) WRITE(Z3_ENABLE_PIN,STATE)
+    #define Z3_ENABLE_READ() READ(Z3_ENABLE_PIN)
+  #endif
+  #ifndef Z3_DIR_INIT
+    #define Z3_DIR_INIT SET_OUTPUT(Z3_DIR_PIN)
+    #define Z3_DIR_WRITE(STATE) WRITE(Z3_DIR_PIN,STATE)
+    #define Z3_DIR_READ() READ(Z3_DIR_PIN)
+  #endif
+  #define Z3_STEP_INIT SET_OUTPUT(Z3_STEP_PIN)
+  #ifndef Z3_STEP_WRITE
+    #define Z3_STEP_WRITE(STATE) WRITE(Z3_STEP_PIN,STATE)
+  #endif
+  #define Z3_STEP_READ READ(Z3_STEP_PIN)
+#else
+  #define Z3_DIR_WRITE(STATE) NOOP
+#endif
+
+// E0 Stepper
+#ifndef E0_ENABLE_INIT
+  #define E0_ENABLE_INIT SET_OUTPUT(E0_ENABLE_PIN)
+  #define E0_ENABLE_WRITE(STATE) WRITE(E0_ENABLE_PIN,STATE)
+  #define E0_ENABLE_READ() READ(E0_ENABLE_PIN)
+#endif
+#ifndef E0_DIR_INIT
+  #define E0_DIR_INIT SET_OUTPUT(E0_DIR_PIN)
+  #define E0_DIR_WRITE(STATE) WRITE(E0_DIR_PIN,STATE)
+  #define E0_DIR_READ() READ(E0_DIR_PIN)
+#endif
+#define E0_STEP_INIT SET_OUTPUT(E0_STEP_PIN)
+#ifndef E0_STEP_WRITE
+  #define E0_STEP_WRITE(STATE) WRITE(E0_STEP_PIN,STATE)
+#endif
+#define E0_STEP_READ READ(E0_STEP_PIN)
+
+// E1 Stepper
+#ifndef E1_ENABLE_INIT
+  #define E1_ENABLE_INIT SET_OUTPUT(E1_ENABLE_PIN)
+  #define E1_ENABLE_WRITE(STATE) WRITE(E1_ENABLE_PIN,STATE)
+  #define E1_ENABLE_READ() READ(E1_ENABLE_PIN)
+#endif
+#ifndef E1_DIR_INIT
+  #define E1_DIR_INIT SET_OUTPUT(E1_DIR_PIN)
+  #define E1_DIR_WRITE(STATE) WRITE(E1_DIR_PIN,STATE)
+  #define E1_DIR_READ() READ(E1_DIR_PIN)
+#endif
+#define E1_STEP_INIT SET_OUTPUT(E1_STEP_PIN)
+#ifndef E1_STEP_WRITE
+  #define E1_STEP_WRITE(STATE) WRITE(E1_STEP_PIN,STATE)
+#endif
+#define E1_STEP_READ READ(E1_STEP_PIN)
+
+// E2 Stepper
+#ifndef E2_ENABLE_INIT
+  #define E2_ENABLE_INIT SET_OUTPUT(E2_ENABLE_PIN)
+  #define E2_ENABLE_WRITE(STATE) WRITE(E2_ENABLE_PIN,STATE)
+  #define E2_ENABLE_READ() READ(E2_ENABLE_PIN)
+#endif
+#ifndef E2_DIR_INIT
+  #define E2_DIR_INIT SET_OUTPUT(E2_DIR_PIN)
+  #define E2_DIR_WRITE(STATE) WRITE(E2_DIR_PIN,STATE)
+  #define E2_DIR_READ() READ(E2_DIR_PIN)
+#endif
+#define E2_STEP_INIT SET_OUTPUT(E2_STEP_PIN)
+#ifndef E2_STEP_WRITE
+  #define E2_STEP_WRITE(STATE) WRITE(E2_STEP_PIN,STATE)
+#endif
+#define E2_STEP_READ READ(E2_STEP_PIN)
+
+// E3 Stepper
+#ifndef E3_ENABLE_INIT
+  #define E3_ENABLE_INIT SET_OUTPUT(E3_ENABLE_PIN)
+  #define E3_ENABLE_WRITE(STATE) WRITE(E3_ENABLE_PIN,STATE)
+  #define E3_ENABLE_READ() READ(E3_ENABLE_PIN)
+#endif
+#ifndef E3_DIR_INIT
+  #define E3_DIR_INIT SET_OUTPUT(E3_DIR_PIN)
+  #define E3_DIR_WRITE(STATE) WRITE(E3_DIR_PIN,STATE)
+  #define E3_DIR_READ() READ(E3_DIR_PIN)
+#endif
+#define E3_STEP_INIT SET_OUTPUT(E3_STEP_PIN)
+#ifndef E3_STEP_WRITE
+  #define E3_STEP_WRITE(STATE) WRITE(E3_STEP_PIN,STATE)
+#endif
+#define E3_STEP_READ READ(E3_STEP_PIN)
+
+// E4 Stepper
+#ifndef E4_ENABLE_INIT
+  #define E4_ENABLE_INIT SET_OUTPUT(E4_ENABLE_PIN)
+  #define E4_ENABLE_WRITE(STATE) WRITE(E4_ENABLE_PIN,STATE)
+  #define E4_ENABLE_READ() READ(E4_ENABLE_PIN)
+#endif
+#ifndef E4_DIR_INIT
+  #define E4_DIR_INIT SET_OUTPUT(E4_DIR_PIN)
+  #define E4_DIR_WRITE(STATE) WRITE(E4_DIR_PIN,STATE)
+  #define E4_DIR_READ() READ(E4_DIR_PIN)
+#endif
+#define E4_STEP_INIT SET_OUTPUT(E4_STEP_PIN)
+#ifndef E4_STEP_WRITE
+  #define E4_STEP_WRITE(STATE) WRITE(E4_STEP_PIN,STATE)
+#endif
+#define E4_STEP_READ READ(E4_STEP_PIN)
+
+// E5 Stepper
+#ifndef E5_ENABLE_INIT
+  #define E5_ENABLE_INIT SET_OUTPUT(E5_ENABLE_PIN)
+  #define E5_ENABLE_WRITE(STATE) WRITE(E5_ENABLE_PIN,STATE)
+  #define E5_ENABLE_READ() READ(E5_ENABLE_PIN)
+#endif
+#ifndef E5_DIR_INIT
+  #define E5_DIR_INIT SET_OUTPUT(E5_DIR_PIN)
+  #define E5_DIR_WRITE(STATE) WRITE(E5_DIR_PIN,STATE)
+  #define E5_DIR_READ() READ(E5_DIR_PIN)
+#endif
+#define E5_STEP_INIT SET_OUTPUT(E5_STEP_PIN)
+#ifndef E5_STEP_WRITE
+  #define E5_STEP_WRITE(STATE) WRITE(E5_STEP_PIN,STATE)
+#endif
+#define E5_STEP_READ READ(E5_STEP_PIN)
+
+/**
+ * Extruder indirection for the single E axis
+ */
+#if ENABLED(SWITCHING_EXTRUDER) // One stepper driver per two extruders, reversed on odd index
+  #if EXTRUDERS > 5
+    #define E_STEP_WRITE(E,V) do{ if (E < 2) { E0_STEP_WRITE(V); } else if (E < 4) { E1_STEP_WRITE(V); } else { E2_STEP_WRITE(V); } }while(0)
+    #define   NORM_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 3: E1_DIR_WRITE( INVERT_E1_DIR); break; case 4: E2_DIR_WRITE(!INVERT_E2_DIR); case 5: E2_DIR_WRITE( INVERT_E2_DIR); } }while(0)
+    #define    REV_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 2: E1_DIR_WRITE( INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 4: E2_DIR_WRITE( INVERT_E2_DIR); case 5: E2_DIR_WRITE(!INVERT_E2_DIR); } }while(0)
+  #elif EXTRUDERS > 4
+    #define E_STEP_WRITE(E,V) do{ if (E < 2) { E0_STEP_WRITE(V); } else if (E < 4) { E1_STEP_WRITE(V); } else { E2_STEP_WRITE(V); } }while(0)
+    #define   NORM_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 3: E1_DIR_WRITE( INVERT_E1_DIR); break; case 4: E2_DIR_WRITE(!INVERT_E2_DIR); } }while(0)
+    #define    REV_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 2: E1_DIR_WRITE( INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 4: E2_DIR_WRITE( INVERT_E2_DIR); } }while(0)
+  #elif EXTRUDERS > 3
+    #define E_STEP_WRITE(E,V) do{ if (E < 2) { E0_STEP_WRITE(V); } else { E1_STEP_WRITE(V); } }while(0)
+    #define   NORM_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 3: E1_DIR_WRITE( INVERT_E1_DIR); } }while(0)
+    #define    REV_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 2: E1_DIR_WRITE( INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
+  #elif EXTRUDERS > 2
+    #define E_STEP_WRITE(E,V) do{ if (E < 2) { E0_STEP_WRITE(V); } else { E1_STEP_WRITE(V); } }while(0)
+    #define   NORM_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
+    #define    REV_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 2: E1_DIR_WRITE( INVERT_E1_DIR); } }while(0)
+  #else
+    #define E_STEP_WRITE(E,V) E0_STEP_WRITE(V)
+    #define   NORM_E_DIR(E)   do{ E0_DIR_WRITE(E ?  INVERT_E0_DIR : !INVERT_E0_DIR); }while(0)
+    #define    REV_E_DIR(E)   do{ E0_DIR_WRITE(E ? !INVERT_E0_DIR :  INVERT_E0_DIR); }while(0)
+  #endif
+#elif ENABLED(PRUSA_MMU2)
+  #define E_STEP_WRITE(E,V) E0_STEP_WRITE(V)
+  #define   NORM_E_DIR(E)   E0_DIR_WRITE(!INVERT_E0_DIR)
+  #define    REV_E_DIR(E)   E0_DIR_WRITE( INVERT_E0_DIR)
+
+#elif ENABLED(MK2_MULTIPLEXER) // One multiplexed stepper driver, reversed on odd index
+  #define E_STEP_WRITE(E,V) E0_STEP_WRITE(V)
+  #define   NORM_E_DIR(E)   do{ E0_DIR_WRITE(TEST(E, 0) ? !INVERT_E0_DIR:  INVERT_E0_DIR); }while(0)
+  #define    REV_E_DIR(E)   do{ E0_DIR_WRITE(TEST(E, 0) ?  INVERT_E0_DIR: !INVERT_E0_DIR); }while(0)
+
+#elif E_STEPPERS > 1
+
+  #if E_STEPPERS > 5
+    #define _E_STEP_WRITE(E,V) do{ switch (E) { case 0: E0_STEP_WRITE(V); break; case 1: E1_STEP_WRITE(V); break; case 2: E2_STEP_WRITE(V); break; case 3: E3_STEP_WRITE(V); break; case 4: E4_STEP_WRITE(V); case 5: E5_STEP_WRITE(V); } }while(0)
+    #define   _NORM_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); break; case 4: E4_DIR_WRITE(!INVERT_E4_DIR); case 5: E5_DIR_WRITE(!INVERT_E5_DIR); } }while(0)
+    #define    _REV_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; case 2: E2_DIR_WRITE( INVERT_E2_DIR); break; case 3: E3_DIR_WRITE( INVERT_E3_DIR); break; case 4: E4_DIR_WRITE( INVERT_E4_DIR); case 5: E5_DIR_WRITE( INVERT_E5_DIR); } }while(0)
+  #elif E_STEPPERS > 4
+    #define _E_STEP_WRITE(E,V) do{ switch (E) { case 0: E0_STEP_WRITE(V); break; case 1: E1_STEP_WRITE(V); break; case 2: E2_STEP_WRITE(V); break; case 3: E3_STEP_WRITE(V); break; case 4: E4_STEP_WRITE(V); } }while(0)
+    #define   _NORM_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); break; case 4: E4_DIR_WRITE(!INVERT_E4_DIR); } }while(0)
+    #define    _REV_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; case 2: E2_DIR_WRITE( INVERT_E2_DIR); break; case 3: E3_DIR_WRITE( INVERT_E3_DIR); break; case 4: E4_DIR_WRITE( INVERT_E4_DIR); } }while(0)
+  #elif E_STEPPERS > 3
+    #define _E_STEP_WRITE(E,V) do{ switch (E) { case 0: E0_STEP_WRITE(V); break; case 1: E1_STEP_WRITE(V); break; case 2: E2_STEP_WRITE(V); break; case 3: E3_STEP_WRITE(V); } }while(0)
+    #define   _NORM_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); } }while(0)
+    #define    _REV_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; case 2: E2_DIR_WRITE( INVERT_E2_DIR); break; case 3: E3_DIR_WRITE( INVERT_E3_DIR); } }while(0)
+  #elif E_STEPPERS > 2
+    #define _E_STEP_WRITE(E,V) do{ switch (E) { case 0: E0_STEP_WRITE(V); break; case 1: E1_STEP_WRITE(V); break; case 2: E2_STEP_WRITE(V); } }while(0)
+    #define   _NORM_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); } }while(0)
+    #define    _REV_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; case 2: E2_DIR_WRITE( INVERT_E2_DIR); } }while(0)
+  #else
+    #define _E_STEP_WRITE(E,V) do{ if (E == 0) { E0_STEP_WRITE(V); } else { E1_STEP_WRITE(V); } }while(0)
+    #define   _NORM_E_DIR(E)   do{ if (E == 0) { E0_DIR_WRITE(!INVERT_E0_DIR); } else { E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
+    #define    _REV_E_DIR(E)   do{ if (E == 0) { E0_DIR_WRITE( INVERT_E0_DIR); } else { E1_DIR_WRITE( INVERT_E1_DIR); } }while(0)
+  #endif
+
+  #if HAS_DUPLICATION_MODE
+
+    #if ENABLED(MULTI_NOZZLE_DUPLICATION)
+      #define _DUPE(N,T,V)  do{ if (TEST(duplication_e_mask, N)) E##N##_##T##_WRITE(V); }while(0)
+    #else
+      #define _DUPE(N,T,V)  E##N##_##T##_WRITE(V)
+    #endif
+
+    #define NDIR(N) _DUPE(N,DIR,!INVERT_E##N##_DIR)
+    #define RDIR(N) _DUPE(N,DIR, INVERT_E##N##_DIR)
+
+    #define E_STEP_WRITE(E,V) do{ if (extruder_duplication_enabled) { DUPE(STEP,V); } else _E_STEP_WRITE(E,V); }while(0)
+
+    #if E_STEPPERS > 2
+      #if E_STEPPERS > 5
+        #define DUPE(T,V)     do{ _DUPE(0,T,V); _DUPE(1,T,V); _DUPE(2,T,V); _DUPE(3,T,V); _DUPE(4,T,V); _DUPE(5,T,V); }while(0)
+        #define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { NDIR(0); NDIR(1); NDIR(2); NDIR(3); NDIR(4); NDIR(5); } else _NORM_E_DIR(E); }while(0)
+        #define REV_E_DIR(E)  do{ if (extruder_duplication_enabled) { RDIR(0); RDIR(1); RDIR(2); RDIR(3); RDIR(4); RDIR(5); } else  _REV_E_DIR(E); }while(0)
+      #elif E_STEPPERS > 4
+        #define DUPE(T,V)     do{ _DUPE(0,T,V); _DUPE(1,T,V); _DUPE(2,T,V); _DUPE(3,T,V); _DUPE(4,T,V); }while(0)
+        #define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { NDIR(0); NDIR(1); NDIR(2); NDIR(3); NDIR(4); } else _NORM_E_DIR(E); }while(0)
+        #define REV_E_DIR(E)  do{ if (extruder_duplication_enabled) { RDIR(0); RDIR(1); RDIR(2); RDIR(3); RDIR(4); } else  _REV_E_DIR(E); }while(0)
+      #elif E_STEPPERS > 3
+        #define DUPE(T,V)     do{ _DUPE(0,T,V); _DUPE(1,T,V); _DUPE(2,T,V); _DUPE(3,T,V); }while(0)
+        #define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { NDIR(0); NDIR(1); NDIR(2); NDIR(3); } else _NORM_E_DIR(E); }while(0)
+        #define REV_E_DIR(E)  do{ if (extruder_duplication_enabled) { RDIR(0); RDIR(1); RDIR(2); RDIR(3); } else  _REV_E_DIR(E); }while(0)
+      #else
+        #define DUPE(T,V)     do{ _DUPE(0,T,V); _DUPE(1,T,V); _DUPE(2,T,V); }while(0)
+        #define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { NDIR(0); NDIR(1); NDIR(2); } else _NORM_E_DIR(E); }while(0)
+        #define REV_E_DIR(E)  do{ if (extruder_duplication_enabled) { RDIR(0); RDIR(1); RDIR(2); } else  _REV_E_DIR(E); }while(0)
+      #endif
+    #else
+      #define DUPE(T,V)     do{ _DUPE(0,T,V); _DUPE(1,T,V); }while(0)
+      #define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { NDIR(0); NDIR(1); } else _NORM_E_DIR(E); }while(0)
+      #define REV_E_DIR(E)  do{ if (extruder_duplication_enabled) { RDIR(0); RDIR(1); } else  _REV_E_DIR(E); }while(0)
+    #endif
+
+  #else
+
+    #define E_STEP_WRITE(E,V) _E_STEP_WRITE(E,V)
+    #define   NORM_E_DIR(E)   _NORM_E_DIR(E)
+    #define    REV_E_DIR(E)   _REV_E_DIR(E)
+
+  #endif
+
+#elif E_STEPPERS
+  #define E_STEP_WRITE(E,V) E0_STEP_WRITE(V)
+  #define   NORM_E_DIR(E)   E0_DIR_WRITE(!INVERT_E0_DIR)
+  #define    REV_E_DIR(E)   E0_DIR_WRITE( INVERT_E0_DIR)
+
+#else
+  #define E_STEP_WRITE(E,V) NOOP
+  #define   NORM_E_DIR(E)   NOOP
+  #define    REV_E_DIR(E)   NOOP
+
+#endif
diff --git a/Marlin/src/module/stepper_indirection.cpp b/Marlin/src/module/stepper/trinamic.cpp
similarity index 66%
rename from Marlin/src/module/stepper_indirection.cpp
rename to Marlin/src/module/stepper/trinamic.cpp
index 80d7978e33c0228edd9323eae009177cfe8b43f2..a0910204e6b116f1578e7b258a52e0b7fcd2fb47 100644
--- a/Marlin/src/module/stepper_indirection.cpp
+++ b/Marlin/src/module/stepper/trinamic.cpp
@@ -21,204 +21,90 @@
  */
 
 /**
- * stepper_indirection.cpp
- *
- * Stepper motor driver indirection to allow some stepper functions to
- * be done via SPI/I2c instead of direct pin manipulation.
- *
- * Copyright (c) 2015 Dominik Wenger
+ * stepper/trinamic.cpp
+ * Stepper driver indirection for Trinamic
  */
 
-#include "stepper_indirection.h"
-
-#include "../inc/MarlinConfig.h"
-
-#include "stepper.h"
-
-#if HAS_DRIVER(L6470)
-  #include "L6470/L6470_Marlin.h"
-#endif
-
-//
-// TMC26X Driver objects and inits
-//
-#if HAS_DRIVER(TMC26X)
-  #include <SPI.h>
+#include "../../inc/MarlinConfig.h"
 
-  #if defined(STM32GENERIC) && defined(STM32F7)
-    #include "../HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.h"
-  #else
-    #include <TMC26XStepper.h>
-  #endif
+#if HAS_TRINAMIC
 
-  #define _TMC26X_DEFINE(ST) TMC26XStepper stepper##ST(200, ST##_CS_PIN, ST##_STEP_PIN, ST##_DIR_PIN, ST##_MAX_CURRENT, ST##_SENSE_RESISTOR)
+#include "trinamic.h"
+#include "../stepper.h"
 
-  #if AXIS_DRIVER_TYPE_X(TMC26X)
-    _TMC26X_DEFINE(X);
-  #endif
-  #if AXIS_DRIVER_TYPE_X2(TMC26X)
-    _TMC26X_DEFINE(X2);
-  #endif
-  #if AXIS_DRIVER_TYPE_Y(TMC26X)
-    _TMC26X_DEFINE(Y);
-  #endif
-  #if AXIS_DRIVER_TYPE_Y2(TMC26X)
-    _TMC26X_DEFINE(Y2);
-  #endif
-  #if AXIS_DRIVER_TYPE_Z(TMC26X)
-    _TMC26X_DEFINE(Z);
-  #endif
-  #if AXIS_DRIVER_TYPE_Z2(TMC26X)
-    _TMC26X_DEFINE(Z2);
-  #endif
-  #if AXIS_DRIVER_TYPE_Z3(TMC26X)
-    _TMC26X_DEFINE(Z3);
-  #endif
-  #if AXIS_DRIVER_TYPE_E0(TMC26X)
-    _TMC26X_DEFINE(E0);
-  #endif
-  #if AXIS_DRIVER_TYPE_E1(TMC26X)
-    _TMC26X_DEFINE(E1);
-  #endif
-  #if AXIS_DRIVER_TYPE_E2(TMC26X)
-    _TMC26X_DEFINE(E2);
-  #endif
-  #if AXIS_DRIVER_TYPE_E3(TMC26X)
-    _TMC26X_DEFINE(E3);
-  #endif
-  #if AXIS_DRIVER_TYPE_E4(TMC26X)
-    _TMC26X_DEFINE(E4);
-  #endif
-  #if AXIS_DRIVER_TYPE_E5(TMC26X)
-    _TMC26X_DEFINE(E5);
-  #endif
+#include <HardwareSerial.h>
+#include <SPI.h>
 
-  #define _TMC26X_INIT(A) do{ \
-    stepper##A.setMicrosteps(A##_MICROSTEPS); \
-    stepper##A.start(); \
-  }while(0)
+enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E };
+#define _TMC_INIT(ST, STEALTH_INDEX) tmc_init(stepper##ST, ST##_CURRENT, ST##_MICROSTEPS, ST##_HYBRID_THRESHOLD, stealthchop_by_axis[STEALTH_INDEX])
 
-  void tmc26x_init_to_defaults() {
-    #if AXIS_DRIVER_TYPE_X(TMC26X)
-      _TMC26X_INIT(X);
-    #endif
-    #if AXIS_DRIVER_TYPE_X2(TMC26X)
-      _TMC26X_INIT(X2);
-    #endif
-    #if AXIS_DRIVER_TYPE_Y(TMC26X)
-      _TMC26X_INIT(Y);
-    #endif
-    #if AXIS_DRIVER_TYPE_Y2(TMC26X)
-      _TMC26X_INIT(Y2);
-    #endif
-    #if AXIS_DRIVER_TYPE_Z(TMC26X)
-      _TMC26X_INIT(Z);
-    #endif
-    #if AXIS_DRIVER_TYPE_Z2(TMC26X)
-      _TMC26X_INIT(Z2);
-    #endif
-    #if AXIS_DRIVER_TYPE_Z3(TMC26X)
-      _TMC26X_INIT(Z3);
-    #endif
-    #if AXIS_DRIVER_TYPE_E0(TMC26X)
-      _TMC26X_INIT(E0);
-    #endif
-    #if AXIS_DRIVER_TYPE_E1(TMC26X)
-      _TMC26X_INIT(E1);
-    #endif
-    #if AXIS_DRIVER_TYPE_E2(TMC26X)
-      _TMC26X_INIT(E2);
-    #endif
-    #if AXIS_DRIVER_TYPE_E3(TMC26X)
-      _TMC26X_INIT(E3);
-    #endif
-    #if AXIS_DRIVER_TYPE_E4(TMC26X)
-      _TMC26X_INIT(E4);
-    #endif
-    #if AXIS_DRIVER_TYPE_E5(TMC26X)
-      _TMC26X_INIT(E5);
-    #endif
-  }
-#endif // TMC26X
-
-#if HAS_TRINAMIC
-  #include <HardwareSerial.h>
-  #include <SPI.h>
-  #include "planner.h"
-  #include "../core/enum.h"
-
-  enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E };
-  #define _TMC_INIT(ST, STEALTH_INDEX) tmc_init(stepper##ST, ST##_CURRENT, ST##_MICROSTEPS, ST##_HYBRID_THRESHOLD, stealthchop_by_axis[STEALTH_INDEX])
-
-  //   IC = TMC model number
-  //   ST = Stepper object letter
-  //   L  = Label characters
-  //   AI = Axis Enum Index
-  // SWHW = SW/SH UART selection
-  #if ENABLED(TMC_USE_SW_SPI)
-    #define __TMC_SPI_DEFINE(IC, ST, L, AI) TMCMarlin<IC##Stepper, L, AI> stepper##ST(ST##_CS_PIN, ST##_RSENSE, TMC_SW_MOSI, TMC_SW_MISO, TMC_SW_SCK)
-  #else
-    #define __TMC_SPI_DEFINE(IC, ST, L, AI) TMCMarlin<IC##Stepper, L, AI> stepper##ST(ST##_CS_PIN, ST##_RSENSE)
-  #endif
-
-  #define TMC_UART_HW_DEFINE(IC, ST, L, AI) TMCMarlin<IC##Stepper, L, AI> stepper##ST(&ST##_HARDWARE_SERIAL, ST##_RSENSE, ST##_SLAVE_ADDRESS)
-  #define TMC_UART_SW_DEFINE(IC, ST, L, AI) TMCMarlin<IC##Stepper, L, AI> stepper##ST(ST##_SERIAL_RX_PIN, ST##_SERIAL_TX_PIN, ST##_RSENSE, ST##_SLAVE_ADDRESS, ST##_SERIAL_RX_PIN > -1)
+//   IC = TMC model number
+//   ST = Stepper object letter
+//   L  = Label characters
+//   AI = Axis Enum Index
+// SWHW = SW/SH UART selection
+#if ENABLED(TMC_USE_SW_SPI)
+  #define __TMC_SPI_DEFINE(IC, ST, L, AI) TMCMarlin<IC##Stepper, L, AI> stepper##ST(ST##_CS_PIN, ST##_RSENSE, TMC_SW_MOSI, TMC_SW_MISO, TMC_SW_SCK)
+#else
+  #define __TMC_SPI_DEFINE(IC, ST, L, AI) TMCMarlin<IC##Stepper, L, AI> stepper##ST(ST##_CS_PIN, ST##_RSENSE)
+#endif
 
-  #define _TMC_SPI_DEFINE(IC, ST, AI) __TMC_SPI_DEFINE(IC, ST, TMC_##ST##_LABEL, AI)
-  #define TMC_SPI_DEFINE(ST, AI) _TMC_SPI_DEFINE(ST##_DRIVER_TYPE, ST, AI##_AXIS)
+#define TMC_UART_HW_DEFINE(IC, ST, L, AI) TMCMarlin<IC##Stepper, L, AI> stepper##ST(&ST##_HARDWARE_SERIAL, ST##_RSENSE, ST##_SLAVE_ADDRESS)
+#define TMC_UART_SW_DEFINE(IC, ST, L, AI) TMCMarlin<IC##Stepper, L, AI> stepper##ST(ST##_SERIAL_RX_PIN, ST##_SERIAL_TX_PIN, ST##_RSENSE, ST##_SLAVE_ADDRESS, ST##_SERIAL_RX_PIN > -1)
 
-  #define _TMC_UART_DEFINE(SWHW, IC, ST, AI) TMC_UART_##SWHW##_DEFINE(IC, ST, TMC_##ST##_LABEL, AI)
-  #define TMC_UART_DEFINE(SWHW, ST, AI) _TMC_UART_DEFINE(SWHW, ST##_DRIVER_TYPE, ST, AI##_AXIS)
+#define _TMC_SPI_DEFINE(IC, ST, AI) __TMC_SPI_DEFINE(IC, ST, TMC_##ST##_LABEL, AI)
+#define TMC_SPI_DEFINE(ST, AI) _TMC_SPI_DEFINE(ST##_DRIVER_TYPE, ST, AI##_AXIS)
 
-  #if ENABLED(DISTINCT_E_FACTORS) && E_STEPPERS > 1
-    #define TMC_SPI_DEFINE_E(AI) TMC_SPI_DEFINE(E##AI, E##AI)
-    #define TMC_UART_DEFINE_E(SWHW, AI) TMC_UART_DEFINE(SWHW, E##AI, E##AI)
-  #else
-    #define TMC_SPI_DEFINE_E(AI) TMC_SPI_DEFINE(E##AI, E)
-    #define TMC_UART_DEFINE_E(SWHW, AI) TMC_UART_DEFINE(SWHW, E##AI, E)
-  #endif
+#define _TMC_UART_DEFINE(SWHW, IC, ST, AI) TMC_UART_##SWHW##_DEFINE(IC, ST, TMC_##ST##_LABEL, AI)
+#define TMC_UART_DEFINE(SWHW, ST, AI) _TMC_UART_DEFINE(SWHW, ST##_DRIVER_TYPE, ST, AI##_AXIS)
 
-  // Stepper objects of TMC2130/TMC2160/TMC2660/TMC5130/TMC5160 steppers used
-  #if AXIS_HAS_SPI(X)
-    TMC_SPI_DEFINE(X, X);
-  #endif
-  #if AXIS_HAS_SPI(X2)
-    TMC_SPI_DEFINE(X2, X);
-  #endif
-  #if AXIS_HAS_SPI(Y)
-    TMC_SPI_DEFINE(Y, Y);
-  #endif
-  #if AXIS_HAS_SPI(Y2)
-    TMC_SPI_DEFINE(Y2, Y);
-  #endif
-  #if AXIS_HAS_SPI(Z)
-    TMC_SPI_DEFINE(Z, Z);
-  #endif
-  #if AXIS_HAS_SPI(Z2)
-    TMC_SPI_DEFINE(Z2, Z);
-  #endif
-  #if AXIS_HAS_SPI(Z3)
-    TMC_SPI_DEFINE(Z3, Z);
-  #endif
-  #if AXIS_HAS_SPI(E0)
-    TMC_SPI_DEFINE_E(0);
-  #endif
-  #if AXIS_HAS_SPI(E1)
-    TMC_SPI_DEFINE_E(1);
-  #endif
-  #if AXIS_HAS_SPI(E2)
-    TMC_SPI_DEFINE_E(2);
-  #endif
-  #if AXIS_HAS_SPI(E3)
-    TMC_SPI_DEFINE_E(3);
-  #endif
-  #if AXIS_HAS_SPI(E4)
-    TMC_SPI_DEFINE_E(4);
-  #endif
-  #if AXIS_HAS_SPI(E5)
-    TMC_SPI_DEFINE_E(5);
-  #endif
+#if ENABLED(DISTINCT_E_FACTORS) && E_STEPPERS > 1
+  #define TMC_SPI_DEFINE_E(AI) TMC_SPI_DEFINE(E##AI, E##AI)
+  #define TMC_UART_DEFINE_E(SWHW, AI) TMC_UART_DEFINE(SWHW, E##AI, E##AI)
+#else
+  #define TMC_SPI_DEFINE_E(AI) TMC_SPI_DEFINE(E##AI, E)
+  #define TMC_UART_DEFINE_E(SWHW, AI) TMC_UART_DEFINE(SWHW, E##AI, E)
+#endif
 
+// Stepper objects of TMC2130/TMC2160/TMC2660/TMC5130/TMC5160 steppers used
+#if AXIS_HAS_SPI(X)
+  TMC_SPI_DEFINE(X, X);
+#endif
+#if AXIS_HAS_SPI(X2)
+  TMC_SPI_DEFINE(X2, X);
+#endif
+#if AXIS_HAS_SPI(Y)
+  TMC_SPI_DEFINE(Y, Y);
+#endif
+#if AXIS_HAS_SPI(Y2)
+  TMC_SPI_DEFINE(Y2, Y);
+#endif
+#if AXIS_HAS_SPI(Z)
+  TMC_SPI_DEFINE(Z, Z);
+#endif
+#if AXIS_HAS_SPI(Z2)
+  TMC_SPI_DEFINE(Z2, Z);
+#endif
+#if AXIS_HAS_SPI(Z3)
+  TMC_SPI_DEFINE(Z3, Z);
+#endif
+#if AXIS_HAS_SPI(E0)
+  TMC_SPI_DEFINE_E(0);
+#endif
+#if AXIS_HAS_SPI(E1)
+  TMC_SPI_DEFINE_E(1);
+#endif
+#if AXIS_HAS_SPI(E2)
+  TMC_SPI_DEFINE_E(2);
+#endif
+#if AXIS_HAS_SPI(E3)
+  TMC_SPI_DEFINE_E(3);
+#endif
+#if AXIS_HAS_SPI(E4)
+  TMC_SPI_DEFINE_E(4);
+#endif
+#if AXIS_HAS_SPI(E5)
+  TMC_SPI_DEFINE_E(5);
 #endif
 
 #if HAS_DRIVER(TMC2130)
@@ -704,7 +590,7 @@
   }
 #endif // TMC5160
 
-void restore_stepper_drivers() {
+void restore_trinamic_drivers() {
   #if AXIS_IS_TMC(X)
     stepperX.push();
   #endif
@@ -746,39 +632,28 @@ void restore_stepper_drivers() {
   #endif
 }
 
-void reset_stepper_drivers() {
-
-  #if HAS_DRIVER(TMC26X)
-    tmc26x_init_to_defaults();
-  #endif
-
-  #if HAS_DRIVER(L6470)
-    L6470.init_to_defaults();
-  #endif
-
-  #if HAS_TRINAMIC
-    static constexpr bool stealthchop_by_axis[] = {
-      #if ENABLED(STEALTHCHOP_XY)
-        true
-      #else
-        false
-      #endif
-      ,
-      #if ENABLED(STEALTHCHOP_Z)
-        true
-      #else
-        false
-      #endif
-      ,
-      #if ENABLED(STEALTHCHOP_E)
-        true
-      #else
-        false
-      #endif
-    };
-  #endif
+void reset_trinamic_drivers() {
+  static constexpr bool stealthchop_by_axis[] = {
+    #if ENABLED(STEALTHCHOP_XY)
+      true
+    #else
+      false
+    #endif
+    ,
+    #if ENABLED(STEALTHCHOP_Z)
+      true
+    #else
+      false
+    #endif
+    ,
+    #if ENABLED(STEALTHCHOP_E)
+      true
+    #else
+      false
+    #endif
+  };
 
- #if TMC_USE_CHAIN
+  #if TMC_USE_CHAIN
 
     enum TMC_axis_enum : unsigned char { _, X, Y, Z, X2, Y2, Z2, Z3, E0, E1, E2, E3, E4, E5 };
     #define __TMC_CHAIN(Q,V) do{ stepper##Q.set_chain_info(Q,V); }while(0)
@@ -942,125 +817,7 @@ void reset_stepper_drivers() {
     TMC_ADV()
   #endif
 
-  #if HAS_TRINAMIC
-    stepper.set_directions();
-  #endif
+  stepper.set_directions();
 }
 
-//
-// L6470 Driver objects and inits
-//
-#if HAS_DRIVER(L6470)
-
-  // create stepper objects
-
-  #define _L6470_DEFINE(ST) L6470 stepper##ST((const int)L6470_CHAIN_SS_PIN)
-
-  // L6470 Stepper objects
-  #if AXIS_DRIVER_TYPE_X(L6470)
-    _L6470_DEFINE(X);
-  #endif
-  #if AXIS_DRIVER_TYPE_X2(L6470)
-    _L6470_DEFINE(X2);
-  #endif
-  #if AXIS_DRIVER_TYPE_Y(L6470)
-    _L6470_DEFINE(Y);
-  #endif
-  #if AXIS_DRIVER_TYPE_Y2(L6470)
-    _L6470_DEFINE(Y2);
-  #endif
-  #if AXIS_DRIVER_TYPE_Z(L6470)
-    _L6470_DEFINE(Z);
-  #endif
-  #if AXIS_DRIVER_TYPE_Z2(L6470)
-    _L6470_DEFINE(Z2);
-  #endif
-  #if AXIS_DRIVER_TYPE_Z3(L6470)
-    _L6470_DEFINE(Z3);
-  #endif
-  #if AXIS_DRIVER_TYPE_E0(L6470)
-    _L6470_DEFINE(E0);
-  #endif
-  #if AXIS_DRIVER_TYPE_E1(L6470)
-    _L6470_DEFINE(E1);
-  #endif
-  #if AXIS_DRIVER_TYPE_E2(L6470)
-    _L6470_DEFINE(E2);
-  #endif
-  #if AXIS_DRIVER_TYPE_E3(L6470)
-    _L6470_DEFINE(E3);
-  #endif
-  #if AXIS_DRIVER_TYPE_E4(L6470)
-    _L6470_DEFINE(E4);
-  #endif
-  #if AXIS_DRIVER_TYPE_E5(L6470)
-    _L6470_DEFINE(E5);
-  #endif
-
-  // not using L6470 library's init command because it
-  // briefly sends power to the steppers
-
-  #define _L6470_INIT_CHIP(Q) do{                             \
-    stepper##Q.resetDev();                                    \
-    stepper##Q.softFree();                                    \
-    stepper##Q.SetParam(L6470_CONFIG, CONFIG_PWM_DIV_1        \
-                                    | CONFIG_PWM_MUL_2        \
-                                    | CONFIG_SR_290V_us       \
-                                    | CONFIG_OC_SD_DISABLE    \
-                                    | CONFIG_VS_COMP_DISABLE  \
-                                    | CONFIG_SW_HARD_STOP     \
-                                    | CONFIG_INT_16MHZ);      \
-    stepper##Q.SetParam(L6470_KVAL_RUN, 0xFF);                \
-    stepper##Q.SetParam(L6470_KVAL_ACC, 0xFF);                \
-    stepper##Q.SetParam(L6470_KVAL_DEC, 0xFF);                \
-    stepper##Q.setMicroSteps(Q##_MICROSTEPS);                 \
-    stepper##Q.setOverCurrent(Q##_OVERCURRENT);               \
-    stepper##Q.setStallCurrent(Q##_STALLCURRENT);             \
-    stepper##Q.SetParam(L6470_KVAL_HOLD, Q##_MAX_VOLTAGE);    \
-    stepper##Q.SetParam(L6470_ABS_POS, 0);                    \
-    stepper##Q.getStatus();                                   \
-  }while(0)
-
-  void L6470_Marlin::init_to_defaults() {
-    #if AXIS_DRIVER_TYPE_X(L6470)
-      _L6470_INIT_CHIP(X);
-    #endif
-    #if AXIS_DRIVER_TYPE_X2(L6470)
-      _L6470_INIT_CHIP(X2);
-    #endif
-    #if AXIS_DRIVER_TYPE_Y(L6470)
-      _L6470_INIT_CHIP(Y);
-    #endif
-    #if AXIS_DRIVER_TYPE_Y2(L6470)
-      _L6470_INIT_CHIP(Y2);
-    #endif
-    #if AXIS_DRIVER_TYPE_Z(L6470)
-      _L6470_INIT_CHIP(Z);
-    #endif
-    #if AXIS_DRIVER_TYPE_Z2(L6470)
-      _L6470_INIT_CHIP(Z2);
-    #endif
-    #if AXIS_DRIVER_TYPE_Z3(L6470)
-      _L6470_INIT_CHIP(Z3);
-    #endif
-    #if AXIS_DRIVER_TYPE_E0(L6470)
-      _L6470_INIT_CHIP(E0);
-    #endif
-    #if AXIS_DRIVER_TYPE_E1(L6470)
-      _L6470_INIT_CHIP(E1);
-    #endif
-    #if AXIS_DRIVER_TYPE_E2(L6470)
-      _L6470_INIT_CHIP(E2);
-    #endif
-    #if AXIS_DRIVER_TYPE_E3(L6470)
-      _L6470_INIT_CHIP(E3);
-    #endif
-    #if AXIS_DRIVER_TYPE_E4(L6470)
-      _L6470_INIT_CHIP(E4);
-    #endif
-    #if AXIS_DRIVER_TYPE_E5(L6470)
-      _L6470_INIT_CHIP(E5);
-    #endif
-  }
-
-#endif // L6470
+#endif // HAS_TRINAMIC
diff --git a/Marlin/src/module/stepper/trinamic.h b/Marlin/src/module/stepper/trinamic.h
new file mode 100644
index 0000000000000000000000000000000000000000..711d46b65835b44f24ec81c1452e7d5d7ce99a79
--- /dev/null
+++ b/Marlin/src/module/stepper/trinamic.h
@@ -0,0 +1,232 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2019 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/>.
+ *
+ */
+#pragma once
+
+/**
+ * stepper/trinamic.h
+ * Stepper driver indirection for Trinamic
+ */
+
+#include <TMCStepper.h>
+#if TMCSTEPPER_VERSION < 0x000405
+  #error "Update TMCStepper library to 0.4.5 or newer."
+#endif
+
+#include "../../inc/MarlinConfig.h"
+#include "../../feature/tmc_util.h"
+
+#define ____TMC_CLASS(MODEL, A, I, E) TMCMarlin<TMC##MODEL##Stepper, A, I, E>
+#define ___TMC_CLASS(MODEL, A, I, E) ____TMC_CLASS(MODEL, A, I, E)
+#define __TMC_CLASS(MODEL, A, I, E) ___TMC_CLASS(_##MODEL, A, I, E)
+#define _TMC_CLASS(MODEL, L, E) __TMC_CLASS(MODEL, L, E)
+#define TMC_CLASS(ST, A) _TMC_CLASS(ST##_DRIVER_TYPE, TMC_##ST##_LABEL, A##_AXIS)
+#if ENABLED(DISTINCT_E_FACTORS)
+  #define TMC_CLASS_E(I) TMC_CLASS(E##I, E##I)
+#else
+  #define TMC_CLASS_E(I) TMC_CLASS(E##I, E)
+#endif
+
+typedef struct {
+  uint8_t toff;
+  int8_t hend;
+  uint8_t hstrt;
+} chopper_timing_t;
+
+static constexpr chopper_timing_t chopper_timing = CHOPPER_TIMING;
+
+#if HAS_TMC220x
+  void tmc_serial_begin();
+#endif
+
+void restore_trinamic_drivers();
+void reset_trinamic_drivers();
+
+#define AXIS_HAS_SQUARE_WAVE(A) (AXIS_IS_TMC(A) && ENABLED(SQUARE_WAVE_STEPPING))
+
+// X Stepper
+#if AXIS_IS_TMC(X)
+  extern TMC_CLASS(X, X) stepperX;
+  #if ENABLED(SOFTWARE_DRIVER_ENABLE)
+    #define X_ENABLE_INIT NOOP
+    #define X_ENABLE_WRITE(STATE) stepperX.toff((STATE)==X_ENABLE_ON ? chopper_timing.toff : 0)
+    #define X_ENABLE_READ() stepperX.isEnabled()
+  #endif
+  #if AXIS_HAS_SQUARE_WAVE(X)
+    #define X_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(X_STEP_PIN); }while(0)
+  #endif
+#endif
+
+// Y Stepper
+#if AXIS_IS_TMC(Y)
+  extern TMC_CLASS(Y, Y) stepperY;
+  #if ENABLED(SOFTWARE_DRIVER_ENABLE)
+    #define Y_ENABLE_INIT NOOP
+    #define Y_ENABLE_WRITE(STATE) stepperY.toff((STATE)==Y_ENABLE_ON ? chopper_timing.toff : 0)
+    #define Y_ENABLE_READ() stepperY.isEnabled()
+  #endif
+  #if AXIS_HAS_SQUARE_WAVE(Y)
+    #define Y_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(Y_STEP_PIN); }while(0)
+  #endif
+#endif
+
+// Z Stepper
+#if AXIS_IS_TMC(Z)
+  extern TMC_CLASS(Z, Z) stepperZ;
+  #if ENABLED(SOFTWARE_DRIVER_ENABLE)
+    #define Z_ENABLE_INIT NOOP
+    #define Z_ENABLE_WRITE(STATE) stepperZ.toff((STATE)==Z_ENABLE_ON ? chopper_timing.toff : 0)
+    #define Z_ENABLE_READ() stepperZ.isEnabled()
+  #endif
+  #if AXIS_HAS_SQUARE_WAVE(Z)
+    #define Z_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(Z_STEP_PIN); }while(0)
+  #endif
+#endif
+
+// X2 Stepper
+#if HAS_X2_ENABLE && AXIS_IS_TMC(X2)
+  extern TMC_CLASS(X2, X) stepperX2;
+  #if ENABLED(SOFTWARE_DRIVER_ENABLE)
+    #define X2_ENABLE_INIT NOOP
+    #define X2_ENABLE_WRITE(STATE) stepperX2.toff((STATE)==X_ENABLE_ON ? chopper_timing.toff : 0)
+    #define X2_ENABLE_READ() stepperX2.isEnabled()
+  #endif
+  #if AXIS_HAS_SQUARE_WAVE(X2)
+    #define X2_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(X2_STEP_PIN); }while(0)
+  #endif
+#endif
+
+// Y2 Stepper
+#if HAS_Y2_ENABLE && AXIS_IS_TMC(Y2)
+  extern TMC_CLASS(Y2, Y) stepperY2;
+  #if ENABLED(SOFTWARE_DRIVER_ENABLE)
+    #define Y2_ENABLE_INIT NOOP
+    #define Y2_ENABLE_WRITE(STATE) stepperY2.toff((STATE)==Y_ENABLE_ON ? chopper_timing.toff : 0)
+    #define Y2_ENABLE_READ() stepperY2.isEnabled()
+  #endif
+  #if AXIS_HAS_SQUARE_WAVE(Y2)
+    #define Y2_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(Y2_STEP_PIN); }while(0)
+  #endif
+#endif
+
+// Z2 Stepper
+#if HAS_Z2_ENABLE && AXIS_IS_TMC(Z2)
+  extern TMC_CLASS(Z2, Z) stepperZ2;
+  #if ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z2)
+    #define Z2_ENABLE_INIT NOOP
+    #define Z2_ENABLE_WRITE(STATE) stepperZ2.toff((STATE)==Z_ENABLE_ON ? chopper_timing.toff : 0)
+    #define Z2_ENABLE_READ() stepperZ2.isEnabled()
+  #endif
+  #if AXIS_HAS_SQUARE_WAVE(Z2)
+    #define Z2_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(Z2_STEP_PIN); }while(0)
+  #endif
+#endif
+
+// Z3 Stepper
+#if HAS_Z3_ENABLE && AXIS_IS_TMC(Z3)
+  extern TMC_CLASS(Z3, Z) stepperZ3;
+  #if ENABLED(SOFTWARE_DRIVER_ENABLE)
+    #define Z3_ENABLE_INIT NOOP
+    #define Z3_ENABLE_WRITE(STATE) stepperZ3.toff((STATE)==Z_ENABLE_ON ? chopper_timing.toff : 0)
+    #define Z3_ENABLE_READ() stepperZ3.isEnabled()
+  #endif
+  #if AXIS_HAS_SQUARE_WAVE(Z3)
+    #define Z3_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(Z3_STEP_PIN); }while(0)
+  #endif
+#endif
+
+// E0 Stepper
+#if AXIS_IS_TMC(E0)
+  extern TMC_CLASS_E(0) stepperE0;
+  #if ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E0)
+    #define E0_ENABLE_INIT NOOP
+    #define E0_ENABLE_WRITE(STATE) stepperE0.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
+    #define E0_ENABLE_READ() stepperE0.isEnabled()
+  #endif
+  #if AXIS_HAS_SQUARE_WAVE(E0)
+    #define E0_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(E0_STEP_PIN); }while(0)
+  #endif
+#endif
+
+// E1 Stepper
+#if AXIS_IS_TMC(E1)
+  extern TMC_CLASS_E(1) stepperE1;
+  #if ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E1)
+    #define E1_ENABLE_INIT NOOP
+    #define E1_ENABLE_WRITE(STATE) stepperE1.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
+    #define E1_ENABLE_READ() stepperE1.isEnabled()
+  #endif
+  #if AXIS_HAS_SQUARE_WAVE(E1)
+    #define E1_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(E1_STEP_PIN); }while(0)
+  #endif
+#endif
+
+// E2 Stepper
+#if AXIS_IS_TMC(E2)
+  extern TMC_CLASS_E(1) stepperE2;
+  #if ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E2)
+    #define E2_ENABLE_INIT NOOP
+    #define E2_ENABLE_WRITE(STATE) stepperE2.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
+    #define E2_ENABLE_READ() stepperE2.isEnabled()
+  #endif
+  #if AXIS_HAS_SQUARE_WAVE(E2)
+    #define E2_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(E2_STEP_PIN); }while(0)
+  #endif
+#endif
+
+// E3 Stepper
+#if AXIS_IS_TMC(E3)
+  extern TMC_CLASS_E(1) stepperE3;
+  #if ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E3)
+    #define E3_ENABLE_INIT NOOP
+    #define E3_ENABLE_WRITE(STATE) stepperE3.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
+    #define E3_ENABLE_READ() stepperE3.isEnabled()
+  #endif
+  #if AXIS_HAS_SQUARE_WAVE(E3)
+    #define E3_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(E3_STEP_PIN); }while(0)
+  #endif
+#endif
+
+// E4 Stepper
+#if AXIS_IS_TMC(E4)
+  extern TMC_CLASS_E(1) stepperE4;
+  #if ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E4)
+    #define E4_ENABLE_INIT NOOP
+    #define E4_ENABLE_WRITE(STATE) stepperE4.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
+    #define E4_ENABLE_READ() stepperE4.isEnabled()
+  #endif
+  #if AXIS_HAS_SQUARE_WAVE(E4)
+    #define E4_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(E4_STEP_PIN); }while(0)
+  #endif
+#endif
+
+// E5 Stepper
+#if AXIS_IS_TMC(E5)
+  extern TMC_CLASS_E(1) stepperE5;
+  #if ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E5)
+    #define E5_ENABLE_INIT NOOP
+    #define E5_ENABLE_WRITE(STATE) stepperE5.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
+    #define E5_ENABLE_READ() stepperE5.isEnabled()
+  #endif
+  #if AXIS_HAS_SQUARE_WAVE(E5)
+    #define E5_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(E5_STEP_PIN); }while(0)
+  #endif
+#endif
diff --git a/Marlin/src/module/stepper_indirection.h b/Marlin/src/module/stepper_indirection.h
deleted file mode 100644
index 4651b707c28e89bde8aecc5179ab7fa8acdaa8b9..0000000000000000000000000000000000000000
--- a/Marlin/src/module/stepper_indirection.h
+++ /dev/null
@@ -1,727 +0,0 @@
-/**
- * Marlin 3D Printer Firmware
- * Copyright (c) 2019 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/>.
- *
- */
-#pragma once
-
-/**
- * stepper_indirection.h
- *
- * Stepper motor driver indirection to allow some stepper functions to
- * be done via SPI/I2c instead of direct pin manipulation.
- *
- * Copyright (c) 2015 Dominik Wenger
- */
-
-#include "../inc/MarlinConfig.h"
-
-// TMC26X drivers have STEP/DIR on normal pins, but ENABLE via SPI
-#if HAS_DRIVER(TMC26X)
-  #include <SPI.h>
-  #if defined(STM32GENERIC) && defined(STM32F7)
-    #include "../HAL/HAL_STM32_F4_F7/STM32F7/TMC2660.h"
-  #else
-    #include <TMC26XStepper.h>
-  #endif
-  void tmc26x_init_to_defaults();
-#endif
-
-#if HAS_TRINAMIC
-  #include <TMCStepper.h>
-  #include "../feature/tmc_util.h"
-  #if TMCSTEPPER_VERSION < 0x000405
-    #error "Update TMCStepper library to 0.4.5 or newer."
-  #endif
-
-  #define ____TMC_CLASS(MODEL, A, I, E) TMCMarlin<TMC##MODEL##Stepper, A, I, E>
-  #define ___TMC_CLASS(MODEL, A, I, E) ____TMC_CLASS(MODEL, A, I, E)
-  #define __TMC_CLASS(MODEL, A, I, E) ___TMC_CLASS(_##MODEL, A, I, E)
-  #define _TMC_CLASS(MODEL, L, E) __TMC_CLASS(MODEL, L, E)
-  #define TMC_CLASS(ST, A) _TMC_CLASS(ST##_DRIVER_TYPE, TMC_##ST##_LABEL, A##_AXIS)
-  #if ENABLED(DISTINCT_E_FACTORS)
-    #define TMC_CLASS_E(I) TMC_CLASS(E##I, E##I)
-  #else
-    #define TMC_CLASS_E(I) TMC_CLASS(E##I, E)
-  #endif
-
-  typedef struct {
-    uint8_t toff;
-    int8_t hend;
-    uint8_t hstrt;
-  } chopper_timing_t;
-
-  static constexpr chopper_timing_t chopper_timing = CHOPPER_TIMING;
-
-  #if HAS_TMC220x
-    void tmc_serial_begin();
-  #endif
-#endif
-
-// L6470 has STEP on normal pins, but DIR/ENABLE via SPI
-#if HAS_DRIVER(L6470)
-  #include "L6470/L6470_Marlin.h"
-  #define L6470_WRITE_DIR_COMMAND(STATE,Q) do{ L6470_dir_commands[Q] = (STATE ?  dSPIN_STEP_CLOCK_REV : dSPIN_STEP_CLOCK_FWD); }while(0)
-#endif
-
-void restore_stepper_drivers();  // Called by PSU_ON
-void reset_stepper_drivers();    // Called by settings.load / settings.reset
-
-#define AXIS_HAS_SQUARE_WAVE(A) (AXIS_IS_TMC(A) && ENABLED(SQUARE_WAVE_STEPPING))
-
-// X Stepper
-#if AXIS_DRIVER_TYPE_X(L6470)
-  extern L6470 stepperX;
-  #define X_ENABLE_INIT NOOP
-  #define X_ENABLE_WRITE(STATE) NOOP
-  #define X_ENABLE_READ() (stepperX.getStatus() & STATUS_HIZ)
-  #define X_DIR_INIT NOOP
-  #define X_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,X)
-  #define X_DIR_READ() (stepperX.getStatus() & STATUS_DIR)
-#else
-  #if AXIS_IS_TMC(X)
-    extern TMC_CLASS(X, X) stepperX;
-  #endif
-  #if AXIS_DRIVER_TYPE_X(TMC26X)
-    extern TMC26XStepper stepperX;
-    #define X_ENABLE_INIT NOOP
-    #define X_ENABLE_WRITE(STATE) stepperX.setEnabled(STATE)
-    #define X_ENABLE_READ() stepperX.isEnabled()
-  #elif ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(X)
-    #define X_ENABLE_INIT NOOP
-    #define X_ENABLE_WRITE(STATE) stepperX.toff((STATE)==X_ENABLE_ON ? chopper_timing.toff : 0)
-    #define X_ENABLE_READ() stepperX.isEnabled()
-  #else
-    #define X_ENABLE_INIT SET_OUTPUT(X_ENABLE_PIN)
-    #define X_ENABLE_WRITE(STATE) WRITE(X_ENABLE_PIN,STATE)
-    #define X_ENABLE_READ() READ(X_ENABLE_PIN)
-  #endif
-  #define X_DIR_INIT SET_OUTPUT(X_DIR_PIN)
-  #define X_DIR_WRITE(STATE) WRITE(X_DIR_PIN,STATE)
-  #define X_DIR_READ() READ(X_DIR_PIN)
-#endif
-#define X_STEP_INIT SET_OUTPUT(X_STEP_PIN)
-#if AXIS_HAS_SQUARE_WAVE(X)
-  #define X_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(X_STEP_PIN); }while(0)
-#else
-  #define X_STEP_WRITE(STATE) WRITE(X_STEP_PIN,STATE)
-#endif
-#define X_STEP_READ READ(X_STEP_PIN)
-
-// Y Stepper
-#if AXIS_DRIVER_TYPE_Y(L6470)
-  extern L6470 stepperY;
-  #define Y_ENABLE_INIT NOOP
-  #define Y_ENABLE_WRITE(STATE) NOOP
-  #define Y_ENABLE_READ() (stepperY.getStatus() & STATUS_HIZ)
-  #define Y_DIR_INIT NOOP
-  #define Y_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,Y)
-  #define Y_DIR_READ() (stepperY.getStatus() & STATUS_DIR)
-#else
-  #if AXIS_IS_TMC(Y)
-    extern TMC_CLASS(Y, Y) stepperY;
-  #endif
-  #if AXIS_DRIVER_TYPE_Y(TMC26X)
-    extern TMC26XStepper stepperY;
-    #define Y_ENABLE_INIT NOOP
-    #define Y_ENABLE_WRITE(STATE) stepperY.setEnabled(STATE)
-    #define Y_ENABLE_READ() stepperY.isEnabled()
-  #elif ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Y)
-    #define Y_ENABLE_INIT NOOP
-    #define Y_ENABLE_WRITE(STATE) stepperY.toff((STATE)==Y_ENABLE_ON ? chopper_timing.toff : 0)
-    #define Y_ENABLE_READ() stepperY.isEnabled()
-  #else
-    #define Y_ENABLE_INIT SET_OUTPUT(Y_ENABLE_PIN)
-    #define Y_ENABLE_WRITE(STATE) WRITE(Y_ENABLE_PIN,STATE)
-    #define Y_ENABLE_READ() READ(Y_ENABLE_PIN)
-  #endif
-  #define Y_DIR_INIT SET_OUTPUT(Y_DIR_PIN)
-  #define Y_DIR_WRITE(STATE) WRITE(Y_DIR_PIN,STATE)
-  #define Y_DIR_READ() READ(Y_DIR_PIN)
-#endif
-#define Y_STEP_INIT SET_OUTPUT(Y_STEP_PIN)
-#if AXIS_HAS_SQUARE_WAVE(Y)
-  #define Y_STEP_WRITE(STATE) do{ if (STATE) TOGGLE(Y_STEP_PIN); }while(0)
-#else
-  #define Y_STEP_WRITE(STATE) WRITE(Y_STEP_PIN,STATE)
-#endif
-#define Y_STEP_READ READ(Y_STEP_PIN)
-
-// Z Stepper
-#if AXIS_DRIVER_TYPE_Z(L6470)
-  extern L6470 stepperZ;
-  #define Z_ENABLE_INIT NOOP
-  #define Z_ENABLE_WRITE(STATE) NOOP
-  #define Z_ENABLE_READ() (stepperZ.getStatus() & STATUS_HIZ)
-  #define Z_DIR_INIT NOOP
-  #define Z_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,Z)
-  #define Z_DIR_READ() (stepperZ.getStatus() & STATUS_DIR)
-#else
-  #if AXIS_IS_TMC(Z)
-    extern TMC_CLASS(Z, Z) stepperZ;
-  #endif
-  #if AXIS_DRIVER_TYPE_Z(TMC26X)
-    extern TMC26XStepper stepperZ;
-    #define Z_ENABLE_INIT NOOP
-    #define Z_ENABLE_WRITE(STATE) stepperZ.setEnabled(STATE)
-    #define Z_ENABLE_READ() stepperZ.isEnabled()
-  #elif ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z)
-    #define Z_ENABLE_INIT NOOP
-    #define Z_ENABLE_WRITE(STATE) stepperZ.toff((STATE)==Z_ENABLE_ON ? chopper_timing.toff : 0)
-    #define Z_ENABLE_READ() stepperZ.isEnabled()
-  #else
-    #define Z_ENABLE_INIT SET_OUTPUT(Z_ENABLE_PIN)
-    #define Z_ENABLE_WRITE(STATE) WRITE(Z_ENABLE_PIN,STATE)
-    #define Z_ENABLE_READ() READ(Z_ENABLE_PIN)
-  #endif
-  #define Z_DIR_INIT SET_OUTPUT(Z_DIR_PIN)
-  #define Z_DIR_WRITE(STATE) WRITE(Z_DIR_PIN,STATE)
-  #define Z_DIR_READ() READ(Z_DIR_PIN)
-#endif
-#define Z_STEP_INIT SET_OUTPUT(Z_STEP_PIN)
-#if AXIS_HAS_SQUARE_WAVE(Z)
-  #define Z_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(Z_STEP_PIN); }while(0)
-#else
-  #define Z_STEP_WRITE(STATE) WRITE(Z_STEP_PIN,STATE)
-#endif
-#define Z_STEP_READ READ(Z_STEP_PIN)
-
-// X2 Stepper
-#if HAS_X2_ENABLE
-  #if AXIS_DRIVER_TYPE_X2(L6470)
-    extern L6470 stepperX2;
-    #define X2_ENABLE_INIT NOOP
-    #define X2_ENABLE_WRITE(STATE) NOOP
-    #define X2_ENABLE_READ() (stepperX2.getStatus() & STATUS_HIZ)
-    #define X2_DIR_INIT NOOP
-    #define X2_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,X2)
-    #define X2_DIR_READ() (stepperX2.getStatus() & STATUS_DIR)
-  #else
-    #if AXIS_IS_TMC(X2)
-      extern TMC_CLASS(X2, X) stepperX2;
-    #endif
-    #if AXIS_DRIVER_TYPE_X2(TMC26X)
-      extern TMC26XStepper stepperX2;
-      #define X2_ENABLE_INIT NOOP
-      #define X2_ENABLE_WRITE(STATE) stepperX2.setEnabled(STATE)
-      #define X2_ENABLE_READ() stepperX2.isEnabled()
-    #elif ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(X2)
-      #define X2_ENABLE_INIT NOOP
-      #define X2_ENABLE_WRITE(STATE) stepperX2.toff((STATE)==X_ENABLE_ON ? chopper_timing.toff : 0)
-      #define X2_ENABLE_READ() stepperX2.isEnabled()
-    #else
-      #define X2_ENABLE_INIT SET_OUTPUT(X2_ENABLE_PIN)
-      #define X2_ENABLE_WRITE(STATE) WRITE(X2_ENABLE_PIN,STATE)
-      #define X2_ENABLE_READ() READ(X2_ENABLE_PIN)
-    #endif
-    #define X2_DIR_INIT SET_OUTPUT(X2_DIR_PIN)
-    #define X2_DIR_WRITE(STATE) WRITE(X2_DIR_PIN,STATE)
-    #define X2_DIR_READ() READ(X2_DIR_PIN)
-  #endif
-  #define X2_STEP_INIT SET_OUTPUT(X2_STEP_PIN)
-  #if AXIS_HAS_SQUARE_WAVE(X2)
-    #define X2_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(X2_STEP_PIN); }while(0)
-  #else
-    #define X2_STEP_WRITE(STATE) WRITE(X2_STEP_PIN,STATE)
-  #endif
-
-  #define X2_STEP_READ READ(X2_STEP_PIN)
-#endif
-
-// Y2 Stepper
-#if HAS_Y2_ENABLE
-  #if AXIS_DRIVER_TYPE_Y2(L6470)
-    extern L6470 stepperY2;
-    #define Y2_ENABLE_INIT NOOP
-    #define Y2_ENABLE_WRITE(STATE) NOOP
-    #define Y2_ENABLE_READ() (stepperY2.getStatus() & STATUS_HIZ)
-    #define Y2_DIR_INIT NOOP
-    #define Y2_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,Y2)
-    #define Y2_DIR_READ() (stepperY2.getStatus() & STATUS_DIR)
-  #else
-    #if AXIS_IS_TMC(Y2)
-      extern TMC_CLASS(Y2, Y) stepperY2;
-    #endif
-    #if AXIS_DRIVER_TYPE_Y2(TMC26X)
-      extern TMC26XStepper stepperY2;
-      #define Y2_ENABLE_INIT NOOP
-      #define Y2_ENABLE_WRITE(STATE) stepperY2.setEnabled(STATE)
-      #define Y2_ENABLE_READ() stepperY2.isEnabled()
-    #elif ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Y2)
-      #define Y2_ENABLE_INIT NOOP
-      #define Y2_ENABLE_WRITE(STATE) stepperY2.toff((STATE)==Y_ENABLE_ON ? chopper_timing.toff : 0)
-      #define Y2_ENABLE_READ() stepperY2.isEnabled()
-    #else
-      #define Y2_ENABLE_INIT SET_OUTPUT(Y2_ENABLE_PIN)
-      #define Y2_ENABLE_WRITE(STATE) WRITE(Y2_ENABLE_PIN,STATE)
-      #define Y2_ENABLE_READ() READ(Y2_ENABLE_PIN)
-    #endif
-    #define Y2_DIR_INIT SET_OUTPUT(Y2_DIR_PIN)
-    #define Y2_DIR_WRITE(STATE) WRITE(Y2_DIR_PIN,STATE)
-    #define Y2_DIR_READ() READ(Y2_DIR_PIN)
-  #endif
-  #define Y2_STEP_INIT SET_OUTPUT(Y2_STEP_PIN)
-  #if AXIS_HAS_SQUARE_WAVE(Y2)
-    #define Y2_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(Y2_STEP_PIN); }while(0)
-  #else
-    #define Y2_STEP_WRITE(STATE) WRITE(Y2_STEP_PIN,STATE)
-  #endif
-
-  #define Y2_STEP_READ READ(Y2_STEP_PIN)
-#else
-  #define Y2_DIR_WRITE(STATE) NOOP
-#endif
-
-// Z2 Stepper
-#if HAS_Z2_ENABLE
-  #if AXIS_DRIVER_TYPE_Z2(L6470)
-    extern L6470 stepperZ2;
-    #define Z2_ENABLE_INIT NOOP
-    #define Z2_ENABLE_WRITE(STATE) NOOP
-    #define Z2_ENABLE_READ() (stepperZ2.getStatus() & STATUS_HIZ)
-    #define Z2_DIR_INIT NOOP
-    #define Z2_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,Z2)
-    #define Z2_DIR_READ() (stepperZ2.getStatus() & STATUS_DIR)
-  #else
-    #if AXIS_IS_TMC(Z2)
-      extern TMC_CLASS(Z2, Z) stepperZ2;
-    #endif
-    #if AXIS_DRIVER_TYPE_Z2(TMC26X)
-      extern TMC26XStepper stepperZ2;
-      #define Z2_ENABLE_INIT NOOP
-      #define Z2_ENABLE_WRITE(STATE) stepperZ2.setEnabled(STATE)
-      #define Z2_ENABLE_READ() stepperZ2.isEnabled()
-    #elif ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z2)
-      #define Z2_ENABLE_INIT NOOP
-      #define Z2_ENABLE_WRITE(STATE) stepperZ2.toff((STATE)==Z_ENABLE_ON ? chopper_timing.toff : 0)
-      #define Z2_ENABLE_READ() stepperZ2.isEnabled()
-    #else
-      #define Z2_ENABLE_INIT SET_OUTPUT(Z2_ENABLE_PIN)
-      #define Z2_ENABLE_WRITE(STATE) WRITE(Z2_ENABLE_PIN,STATE)
-      #define Z2_ENABLE_READ() READ(Z2_ENABLE_PIN)
-    #endif
-    #define Z2_DIR_INIT SET_OUTPUT(Z2_DIR_PIN)
-    #define Z2_DIR_WRITE(STATE) WRITE(Z2_DIR_PIN,STATE)
-    #define Z2_DIR_READ() READ(Z2_DIR_PIN)
-  #endif
-  #define Z2_STEP_INIT SET_OUTPUT(Z2_STEP_PIN)
-  #if AXIS_HAS_SQUARE_WAVE(Z2)
-    #define Z2_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(Z2_STEP_PIN); }while(0)
-  #else
-    #define Z2_STEP_WRITE(STATE) WRITE(Z2_STEP_PIN,STATE)
-  #endif
-
-  #define Z2_STEP_READ READ(Z2_STEP_PIN)
-#else
-  #define Z2_DIR_WRITE(STATE) NOOP
-#endif
-
-// Z3 Stepper
-#if HAS_Z3_ENABLE
-  #if AXIS_DRIVER_TYPE_Z3(L6470)
-    extern L6470 stepperZ3;
-    #define Z3_ENABLE_INIT NOOP
-    #define Z3_ENABLE_WRITE(STATE) NOOP
-    #define Z3_ENABLE_READ() (stepperZ3.getStatus() & STATUS_HIZ)
-    #define Z3_DIR_INIT NOOP
-    #define Z3_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,Z3)
-    #define Z3_DIR_READ() (stepperZ3.getStatus() & STATUS_DIR)
-  #else
-    #if AXIS_IS_TMC(Z3)
-      extern TMC_CLASS(Z3, Z) stepperZ3;
-    #endif
-    #if ENABLED(Z3_IS_TMC26X)
-      extern TMC26XStepper stepperZ3;
-      #define Z3_ENABLE_INIT NOOP
-      #define Z3_ENABLE_WRITE(STATE) stepperZ3.setEnabled(STATE)
-      #define Z3_ENABLE_READ() stepperZ3.isEnabled()
-    #elif ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z3)
-      #define Z3_ENABLE_INIT NOOP
-      #define Z3_ENABLE_WRITE(STATE) stepperZ3.toff((STATE)==Z_ENABLE_ON ? chopper_timing.toff : 0)
-      #define Z3_ENABLE_READ() stepperZ3.isEnabled()
-    #else
-      #define Z3_ENABLE_INIT SET_OUTPUT(Z3_ENABLE_PIN)
-      #define Z3_ENABLE_WRITE(STATE) WRITE(Z3_ENABLE_PIN,STATE)
-      #define Z3_ENABLE_READ() READ(Z3_ENABLE_PIN)
-    #endif
-    #define Z3_DIR_INIT SET_OUTPUT(Z3_DIR_PIN)
-    #define Z3_DIR_WRITE(STATE) WRITE(Z3_DIR_PIN,STATE)
-    #define Z3_DIR_READ() READ(Z3_DIR_PIN)
-  #endif
-  #define Z3_STEP_INIT SET_OUTPUT(Z3_STEP_PIN)
-  #if AXIS_HAS_SQUARE_WAVE(Z3)
-    #define Z3_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(Z3_STEP_PIN); }while(0)
-  #else
-    #define Z3_STEP_WRITE(STATE) WRITE(Z3_STEP_PIN,STATE)
-  #endif
-
-  #define Z3_STEP_READ READ(Z3_STEP_PIN)
-#else
-  #define Z3_DIR_WRITE(STATE) NOOP
-#endif
-
-// E0 Stepper
-#if AXIS_DRIVER_TYPE_E0(L6470)
-  extern L6470 stepperE0;
-  #define E0_ENABLE_INIT NOOP
-  #define E0_ENABLE_WRITE(STATE) NOOP
-  #define E0_ENABLE_READ() (stepperE0.getStatus() & STATUS_HIZ)
-  #define E0_DIR_INIT NOOP
-  #define E0_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,E0)
-  #define E0_DIR_READ() (stepperE0.getStatus() & STATUS_DIR)
-#else
-  #if AXIS_IS_TMC(E0)
-    extern TMC_CLASS_E(0) stepperE0;
-  #endif
-  #if AXIS_DRIVER_TYPE_E0(TMC26X)
-    extern TMC26XStepper stepperE0;
-    #define E0_ENABLE_INIT NOOP
-    #define E0_ENABLE_WRITE(STATE) stepperE0.setEnabled(STATE)
-    #define E0_ENABLE_READ() stepperE0.isEnabled()
-  #elif ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E0)
-    #define E0_ENABLE_INIT NOOP
-    #define E0_ENABLE_WRITE(STATE) stepperE0.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
-    #define E0_ENABLE_READ() stepperE0.isEnabled()
-  #else
-    #define E0_ENABLE_INIT SET_OUTPUT(E0_ENABLE_PIN)
-    #define E0_ENABLE_WRITE(STATE) WRITE(E0_ENABLE_PIN,STATE)
-    #define E0_ENABLE_READ() READ(E0_ENABLE_PIN)
-  #endif
-  #define E0_DIR_INIT SET_OUTPUT(E0_DIR_PIN)
-  #define E0_DIR_WRITE(STATE) WRITE(E0_DIR_PIN,STATE)
-  #define E0_DIR_READ() READ(E0_DIR_PIN)
-#endif
-#define E0_STEP_INIT SET_OUTPUT(E0_STEP_PIN)
-#if AXIS_HAS_SQUARE_WAVE(E0)
-  #define E0_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(E0_STEP_PIN); }while(0)
-#else
-  #define E0_STEP_WRITE(STATE) WRITE(E0_STEP_PIN,STATE)
-#endif
-#define E0_STEP_READ READ(E0_STEP_PIN)
-
-// E1 Stepper
-#if AXIS_DRIVER_TYPE_E1(L6470)
-  extern L6470 stepperE1;
-  #define E1_ENABLE_INIT NOOP
-  #define E1_ENABLE_WRITE(STATE) NOOP
-  #define E1_ENABLE_READ() (stepperE1.getStatus() & STATUS_HIZ)
-  #define E1_DIR_INIT NOOP
-  #define E1_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,E1)
-  #define E1_DIR_READ() (stepperE1.getStatus() & STATUS_DIR)
-#else
-  #if AXIS_IS_TMC(E1)
-    extern TMC_CLASS_E(1) stepperE1;
-  #endif
-  #if AXIS_DRIVER_TYPE_E1(TMC26X)
-    extern TMC26XStepper stepperE1;
-    #define E1_ENABLE_INIT NOOP
-    #define E1_ENABLE_WRITE(STATE) stepperE1.setEnabled(STATE)
-    #define E1_ENABLE_READ() stepperE1.isEnabled()
-  #elif ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E1)
-    #define E1_ENABLE_INIT NOOP
-    #define E1_ENABLE_WRITE(STATE) stepperE1.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
-    #define E1_ENABLE_READ() stepperE1.isEnabled()
-  #else
-    #define E1_ENABLE_INIT SET_OUTPUT(E1_ENABLE_PIN)
-    #define E1_ENABLE_WRITE(STATE) WRITE(E1_ENABLE_PIN,STATE)
-    #define E1_ENABLE_READ() READ(E1_ENABLE_PIN)
-  #endif
-  #define E1_DIR_INIT SET_OUTPUT(E1_DIR_PIN)
-  #define E1_DIR_WRITE(STATE) WRITE(E1_DIR_PIN,STATE)
-  #define E1_DIR_READ() READ(E1_DIR_PIN)
-#endif
-#define E1_STEP_INIT SET_OUTPUT(E1_STEP_PIN)
-#if AXIS_HAS_SQUARE_WAVE(E1)
-  #define E1_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(E1_STEP_PIN); }while(0)
-#else
-  #define E1_STEP_WRITE(STATE) WRITE(E1_STEP_PIN,STATE)
-#endif
-#define E1_STEP_READ READ(E1_STEP_PIN)
-
-// E2 Stepper
-#if AXIS_DRIVER_TYPE_E2(L6470)
-  extern L6470 stepperE2;
-  #define E2_ENABLE_INIT NOOP
-  #define E2_ENABLE_WRITE(STATE) NOOP
-  #define E2_ENABLE_READ() (stepperE2.getStatus() & STATUS_HIZ)
-  #define E2_DIR_INIT NOOP
-  #define E2_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,E2)
-  #define E2_DIR_READ() (stepperE2.getStatus() & STATUS_DIR)
-#else
-  #if AXIS_IS_TMC(E2)
-    extern TMC_CLASS_E(2) stepperE2;
-  #endif
-  #if AXIS_DRIVER_TYPE_E2(TMC26X)
-    extern TMC26XStepper stepperE2;
-    #define E2_ENABLE_INIT NOOP
-    #define E2_ENABLE_WRITE(STATE) stepperE2.setEnabled(STATE)
-    #define E2_ENABLE_READ() stepperE2.isEnabled()
-  #elif ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E2)
-    #define E2_ENABLE_INIT NOOP
-    #define E2_ENABLE_WRITE(STATE) stepperE2.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
-    #define E2_ENABLE_READ() stepperE2.isEnabled()
-  #else
-    #define E2_ENABLE_INIT SET_OUTPUT(E2_ENABLE_PIN)
-    #define E2_ENABLE_WRITE(STATE) WRITE(E2_ENABLE_PIN,STATE)
-    #define E2_ENABLE_READ() READ(E2_ENABLE_PIN)
-  #endif
-  #define E2_DIR_INIT SET_OUTPUT(E2_DIR_PIN)
-  #define E2_DIR_WRITE(STATE) WRITE(E2_DIR_PIN,STATE)
-  #define E2_DIR_READ() READ(E2_DIR_PIN)
-#endif
-#define E2_STEP_INIT SET_OUTPUT(E2_STEP_PIN)
-#if AXIS_HAS_SQUARE_WAVE(E2)
-  #define E2_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(E2_STEP_PIN); }while(0)
-#else
-  #define E2_STEP_WRITE(STATE) WRITE(E2_STEP_PIN,STATE)
-#endif
-#define E2_STEP_READ READ(E2_STEP_PIN)
-
-// E3 Stepper
-#if AXIS_DRIVER_TYPE_E3(L6470)
-  extern L6470 stepperE3;
-  #define E3_ENABLE_INIT NOOP
-  #define E3_ENABLE_WRITE(STATE) NOOP
-  #define E3_ENABLE_READ() (stepperE3.getStatus() & STATUS_HIZ)
-  #define E3_DIR_INIT NOOP
-  #define E3_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,E3)
-  #define E3_DIR_READ() (stepperE3.getStatus() & STATUS_DIR)
-#else
-  #if AXIS_IS_TMC(E3)
-    extern TMC_CLASS_E(3) stepperE3;
-  #endif
-  #if AXIS_DRIVER_TYPE_E3(TMC26X)
-    extern TMC26XStepper stepperE3;
-    #define E3_ENABLE_INIT NOOP
-    #define E3_ENABLE_WRITE(STATE) stepperE3.setEnabled(STATE)
-    #define E3_ENABLE_READ() stepperE3.isEnabled()
-  #elif ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E3)
-    #define E3_ENABLE_INIT NOOP
-    #define E3_ENABLE_WRITE(STATE) stepperE3.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
-    #define E3_ENABLE_READ() stepperE3.isEnabled()
-  #else
-    #define E3_ENABLE_INIT SET_OUTPUT(E3_ENABLE_PIN)
-    #define E3_ENABLE_WRITE(STATE) WRITE(E3_ENABLE_PIN,STATE)
-    #define E3_ENABLE_READ() READ(E3_ENABLE_PIN)
-  #endif
-  #define E3_DIR_INIT SET_OUTPUT(E3_DIR_PIN)
-  #define E3_DIR_WRITE(STATE) WRITE(E3_DIR_PIN,STATE)
-  #define E3_DIR_READ() READ(E3_DIR_PIN)
-#endif
-#define E3_STEP_INIT SET_OUTPUT(E3_STEP_PIN)
-#if AXIS_HAS_SQUARE_WAVE(E3)
-  #define E3_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(E3_STEP_PIN); }while(0)
-#else
-  #define E3_STEP_WRITE(STATE) WRITE(E3_STEP_PIN,STATE)
-#endif
-#define E3_STEP_READ READ(E3_STEP_PIN)
-
-// E4 Stepper
-#if AXIS_DRIVER_TYPE_E4(L6470)
-  extern L6470 stepperE4;
-  #define E4_ENABLE_INIT NOOP
-  #define E4_ENABLE_WRITE(STATE) NOOP
-  #define E4_ENABLE_READ() (stepperE4.getStatus() & STATUS_HIZ)
-  #define E4_DIR_INIT NOOP
-  #define E4_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,E4)
-  #define E4_DIR_READ() (stepperE4.getStatus() & STATUS_DIR)
-#else
-  #if AXIS_IS_TMC(E4)
-    extern TMC_CLASS_E(4) stepperE4;
-  #endif
-  #if AXIS_DRIVER_TYPE_E4(TMC26X)
-    extern TMC26XStepper stepperE4;
-    #define E4_ENABLE_INIT NOOP
-    #define E4_ENABLE_WRITE(STATE) stepperE4.setEnabled(STATE)
-    #define E4_ENABLE_READ() stepperE4.isEnabled()
-  #elif ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E4)
-    #define E4_ENABLE_INIT NOOP
-    #define E4_ENABLE_WRITE(STATE) stepperE4.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
-    #define E4_ENABLE_READ() stepperE4.isEnabled()
-  #else
-    #define E4_ENABLE_INIT SET_OUTPUT(E4_ENABLE_PIN)
-    #define E4_ENABLE_WRITE(STATE) WRITE(E4_ENABLE_PIN,STATE)
-    #define E4_ENABLE_READ() READ(E4_ENABLE_PIN)
-  #endif
-  #define E4_DIR_INIT SET_OUTPUT(E4_DIR_PIN)
-  #define E4_DIR_WRITE(STATE) WRITE(E4_DIR_PIN,STATE)
-  #define E4_DIR_READ() READ(E4_DIR_PIN)
-#endif
-#define E4_STEP_INIT SET_OUTPUT(E4_STEP_PIN)
-#if AXIS_HAS_SQUARE_WAVE(E4)
-  #define E4_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(E4_STEP_PIN); }while(0)
-#else
-  #define E4_STEP_WRITE(STATE) WRITE(E4_STEP_PIN,STATE)
-#endif
-#define E4_STEP_READ READ(E4_STEP_PIN)
-
-// E5 Stepper
-#if AXIS_DRIVER_TYPE_E5(L6470)
-  extern L6470 stepperE5;
-  #define E5_ENABLE_INIT NOOP
-  #define E5_ENABLE_WRITE(STATE) NOOP
-  #define E5_ENABLE_READ() (stepperE5.getStatus() & STATUS_HIZ)
-  #define E5_DIR_INIT NOOP
-  #define E5_DIR_WRITE(STATE) L6470_WRITE_DIR_COMMAND(STATE,E5)
-  #define E5_DIR_READ() (stepperE5.getStatus() & STATUS_DIR)
-#else
-  #if AXIS_IS_TMC(E5)
-    extern TMC_CLASS_E(5) stepperE5;
-  #endif
-  #if AXIS_DRIVER_TYPE_E5(TMC26X)
-    extern TMC26XStepper stepperE5;
-    #define E5_ENABLE_INIT NOOP
-    #define E5_ENABLE_WRITE(STATE) stepperE5.setEnabled(STATE)
-    #define E5_ENABLE_READ() stepperE5.isEnabled()
-  #elif ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E5)
-    #define E5_ENABLE_INIT NOOP
-    #define E5_ENABLE_WRITE(STATE) stepperE5.toff((STATE)==E_ENABLE_ON ? chopper_timing.toff : 0)
-    #define E5_ENABLE_READ() stepperE5.isEnabled()
-  #else
-    #define E5_ENABLE_INIT SET_OUTPUT(E5_ENABLE_PIN)
-    #define E5_ENABLE_WRITE(STATE) WRITE(E5_ENABLE_PIN,STATE)
-    #define E5_ENABLE_READ() READ(E5_ENABLE_PIN)
-  #endif
-  #define E5_DIR_INIT SET_OUTPUT(E5_DIR_PIN)
-  #define E5_DIR_WRITE(STATE) WRITE(E5_DIR_PIN,STATE)
-  #define E5_DIR_READ() READ(E5_DIR_PIN)
-#endif
-#define E5_STEP_INIT SET_OUTPUT(E5_STEP_PIN)
-#if AXIS_HAS_SQUARE_WAVE(E5)
-  #define E5_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(E5_STEP_PIN); }while(0)
-#else
-  #define E5_STEP_WRITE(STATE) WRITE(E5_STEP_PIN,STATE)
-#endif
-#define E5_STEP_READ READ(E5_STEP_PIN)
-
-/**
- * Extruder indirection for the single E axis
- */
-#if ENABLED(SWITCHING_EXTRUDER) // One stepper driver per two extruders, reversed on odd index
-  #if EXTRUDERS > 5
-    #define E_STEP_WRITE(E,V) do{ if (E < 2) { E0_STEP_WRITE(V); } else if (E < 4) { E1_STEP_WRITE(V); } else { E2_STEP_WRITE(V); } }while(0)
-    #define   NORM_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 3: E1_DIR_WRITE( INVERT_E1_DIR); break; case 4: E2_DIR_WRITE(!INVERT_E2_DIR); case 5: E2_DIR_WRITE( INVERT_E2_DIR); } }while(0)
-    #define    REV_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 2: E1_DIR_WRITE( INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 4: E2_DIR_WRITE( INVERT_E2_DIR); case 5: E2_DIR_WRITE(!INVERT_E2_DIR); } }while(0)
-  #elif EXTRUDERS > 4
-    #define E_STEP_WRITE(E,V) do{ if (E < 2) { E0_STEP_WRITE(V); } else if (E < 4) { E1_STEP_WRITE(V); } else { E2_STEP_WRITE(V); } }while(0)
-    #define   NORM_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 3: E1_DIR_WRITE( INVERT_E1_DIR); break; case 4: E2_DIR_WRITE(!INVERT_E2_DIR); } }while(0)
-    #define    REV_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 2: E1_DIR_WRITE( INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 4: E2_DIR_WRITE( INVERT_E2_DIR); } }while(0)
-  #elif EXTRUDERS > 3
-    #define E_STEP_WRITE(E,V) do{ if (E < 2) { E0_STEP_WRITE(V); } else { E1_STEP_WRITE(V); } }while(0)
-    #define   NORM_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 3: E1_DIR_WRITE( INVERT_E1_DIR); } }while(0)
-    #define    REV_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 2: E1_DIR_WRITE( INVERT_E1_DIR); break; case 3: E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
-  #elif EXTRUDERS > 2
-    #define E_STEP_WRITE(E,V) do{ if (E < 2) { E0_STEP_WRITE(V); } else { E1_STEP_WRITE(V); } }while(0)
-    #define   NORM_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E0_DIR_WRITE( INVERT_E0_DIR); break; case 2: E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
-    #define    REV_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 2: E1_DIR_WRITE( INVERT_E1_DIR); } }while(0)
-  #else
-    #define E_STEP_WRITE(E,V) E0_STEP_WRITE(V)
-    #define   NORM_E_DIR(E)   do{ E0_DIR_WRITE(E ?  INVERT_E0_DIR : !INVERT_E0_DIR); }while(0)
-    #define    REV_E_DIR(E)   do{ E0_DIR_WRITE(E ? !INVERT_E0_DIR :  INVERT_E0_DIR); }while(0)
-  #endif
-#elif ENABLED(PRUSA_MMU2)
-  #define E_STEP_WRITE(E,V) E0_STEP_WRITE(V)
-  #define   NORM_E_DIR(E)   E0_DIR_WRITE(!INVERT_E0_DIR)
-  #define    REV_E_DIR(E)   E0_DIR_WRITE( INVERT_E0_DIR)
-
-#elif ENABLED(MK2_MULTIPLEXER) // One multiplexed stepper driver, reversed on odd index
-  #define E_STEP_WRITE(E,V) E0_STEP_WRITE(V)
-  #define   NORM_E_DIR(E)   do{ E0_DIR_WRITE(TEST(E, 0) ? !INVERT_E0_DIR:  INVERT_E0_DIR); }while(0)
-  #define    REV_E_DIR(E)   do{ E0_DIR_WRITE(TEST(E, 0) ?  INVERT_E0_DIR: !INVERT_E0_DIR); }while(0)
-
-#elif E_STEPPERS > 1
-
-  #if E_STEPPERS > 5
-    #define _E_STEP_WRITE(E,V) do{ switch (E) { case 0: E0_STEP_WRITE(V); break; case 1: E1_STEP_WRITE(V); break; case 2: E2_STEP_WRITE(V); break; case 3: E3_STEP_WRITE(V); break; case 4: E4_STEP_WRITE(V); case 5: E5_STEP_WRITE(V); } }while(0)
-    #define   _NORM_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); break; case 4: E4_DIR_WRITE(!INVERT_E4_DIR); case 5: E5_DIR_WRITE(!INVERT_E5_DIR); } }while(0)
-    #define    _REV_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; case 2: E2_DIR_WRITE( INVERT_E2_DIR); break; case 3: E3_DIR_WRITE( INVERT_E3_DIR); break; case 4: E4_DIR_WRITE( INVERT_E4_DIR); case 5: E5_DIR_WRITE( INVERT_E5_DIR); } }while(0)
-  #elif E_STEPPERS > 4
-    #define _E_STEP_WRITE(E,V) do{ switch (E) { case 0: E0_STEP_WRITE(V); break; case 1: E1_STEP_WRITE(V); break; case 2: E2_STEP_WRITE(V); break; case 3: E3_STEP_WRITE(V); break; case 4: E4_STEP_WRITE(V); } }while(0)
-    #define   _NORM_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); break; case 4: E4_DIR_WRITE(!INVERT_E4_DIR); } }while(0)
-    #define    _REV_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; case 2: E2_DIR_WRITE( INVERT_E2_DIR); break; case 3: E3_DIR_WRITE( INVERT_E3_DIR); break; case 4: E4_DIR_WRITE( INVERT_E4_DIR); } }while(0)
-  #elif E_STEPPERS > 3
-    #define _E_STEP_WRITE(E,V) do{ switch (E) { case 0: E0_STEP_WRITE(V); break; case 1: E1_STEP_WRITE(V); break; case 2: E2_STEP_WRITE(V); break; case 3: E3_STEP_WRITE(V); } }while(0)
-    #define   _NORM_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); break; case 3: E3_DIR_WRITE(!INVERT_E3_DIR); } }while(0)
-    #define    _REV_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; case 2: E2_DIR_WRITE( INVERT_E2_DIR); break; case 3: E3_DIR_WRITE( INVERT_E3_DIR); } }while(0)
-  #elif E_STEPPERS > 2
-    #define _E_STEP_WRITE(E,V) do{ switch (E) { case 0: E0_STEP_WRITE(V); break; case 1: E1_STEP_WRITE(V); break; case 2: E2_STEP_WRITE(V); } }while(0)
-    #define   _NORM_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE(!INVERT_E0_DIR); break; case 1: E1_DIR_WRITE(!INVERT_E1_DIR); break; case 2: E2_DIR_WRITE(!INVERT_E2_DIR); } }while(0)
-    #define    _REV_E_DIR(E)   do{ switch (E) { case 0: E0_DIR_WRITE( INVERT_E0_DIR); break; case 1: E1_DIR_WRITE( INVERT_E1_DIR); break; case 2: E2_DIR_WRITE( INVERT_E2_DIR); } }while(0)
-  #else
-    #define _E_STEP_WRITE(E,V) do{ if (E == 0) { E0_STEP_WRITE(V); } else { E1_STEP_WRITE(V); } }while(0)
-    #define   _NORM_E_DIR(E)   do{ if (E == 0) { E0_DIR_WRITE(!INVERT_E0_DIR); } else { E1_DIR_WRITE(!INVERT_E1_DIR); } }while(0)
-    #define    _REV_E_DIR(E)   do{ if (E == 0) { E0_DIR_WRITE( INVERT_E0_DIR); } else { E1_DIR_WRITE( INVERT_E1_DIR); } }while(0)
-  #endif
-
-  #if HAS_DUPLICATION_MODE
-
-    #if ENABLED(MULTI_NOZZLE_DUPLICATION)
-      #define _DUPE(N,T,V)  do{ if (TEST(duplication_e_mask, N)) E##N##_##T##_WRITE(V); }while(0)
-    #else
-      #define _DUPE(N,T,V)  E##N##_##T##_WRITE(V)
-    #endif
-
-    #define NDIR(N) _DUPE(N,DIR,!INVERT_E##N##_DIR)
-    #define RDIR(N) _DUPE(N,DIR, INVERT_E##N##_DIR)
-
-    #define E_STEP_WRITE(E,V) do{ if (extruder_duplication_enabled) { DUPE(STEP,V); } else _E_STEP_WRITE(E,V); }while(0)
-
-    #if E_STEPPERS > 2
-      #if E_STEPPERS > 5
-        #define DUPE(T,V)     do{ _DUPE(0,T,V); _DUPE(1,T,V); _DUPE(2,T,V); _DUPE(3,T,V); _DUPE(4,T,V); _DUPE(5,T,V); }while(0)
-        #define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { NDIR(0); NDIR(1); NDIR(2); NDIR(3); NDIR(4); NDIR(5); } else _NORM_E_DIR(E); }while(0)
-        #define REV_E_DIR(E)  do{ if (extruder_duplication_enabled) { RDIR(0); RDIR(1); RDIR(2); RDIR(3); RDIR(4); RDIR(5); } else  _REV_E_DIR(E); }while(0)
-      #elif E_STEPPERS > 4
-        #define DUPE(T,V)     do{ _DUPE(0,T,V); _DUPE(1,T,V); _DUPE(2,T,V); _DUPE(3,T,V); _DUPE(4,T,V); }while(0)
-        #define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { NDIR(0); NDIR(1); NDIR(2); NDIR(3); NDIR(4); } else _NORM_E_DIR(E); }while(0)
-        #define REV_E_DIR(E)  do{ if (extruder_duplication_enabled) { RDIR(0); RDIR(1); RDIR(2); RDIR(3); RDIR(4); } else  _REV_E_DIR(E); }while(0)
-      #elif E_STEPPERS > 3
-        #define DUPE(T,V)     do{ _DUPE(0,T,V); _DUPE(1,T,V); _DUPE(2,T,V); _DUPE(3,T,V); }while(0)
-        #define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { NDIR(0); NDIR(1); NDIR(2); NDIR(3); } else _NORM_E_DIR(E); }while(0)
-        #define REV_E_DIR(E)  do{ if (extruder_duplication_enabled) { RDIR(0); RDIR(1); RDIR(2); RDIR(3); } else  _REV_E_DIR(E); }while(0)
-      #else
-        #define DUPE(T,V)     do{ _DUPE(0,T,V); _DUPE(1,T,V); _DUPE(2,T,V); }while(0)
-        #define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { NDIR(0); NDIR(1); NDIR(2); } else _NORM_E_DIR(E); }while(0)
-        #define REV_E_DIR(E)  do{ if (extruder_duplication_enabled) { RDIR(0); RDIR(1); RDIR(2); } else  _REV_E_DIR(E); }while(0)
-      #endif
-    #else
-      #define DUPE(T,V)     do{ _DUPE(0,T,V); _DUPE(1,T,V); }while(0)
-      #define NORM_E_DIR(E) do{ if (extruder_duplication_enabled) { NDIR(0); NDIR(1); } else _NORM_E_DIR(E); }while(0)
-      #define REV_E_DIR(E)  do{ if (extruder_duplication_enabled) { RDIR(0); RDIR(1); } else  _REV_E_DIR(E); }while(0)
-    #endif
-
-  #else
-
-    #define E_STEP_WRITE(E,V) _E_STEP_WRITE(E,V)
-    #define   NORM_E_DIR(E)   _NORM_E_DIR(E)
-    #define    REV_E_DIR(E)   _REV_E_DIR(E)
-
-  #endif
-
-#elif E_STEPPERS
-  #define E_STEP_WRITE(E,V) E0_STEP_WRITE(V)
-  #define   NORM_E_DIR(E)   E0_DIR_WRITE(!INVERT_E0_DIR)
-  #define    REV_E_DIR(E)   E0_DIR_WRITE( INVERT_E0_DIR)
-
-#else
-  #define E_STEP_WRITE(E,V) NOOP
-  #define   NORM_E_DIR(E)   NOOP
-  #define    REV_E_DIR(E)   NOOP
-
-#endif