From 99c4900a98163c784ef210ec574fc052873e14e4 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 7 Apr 2017 13:52:05 -0500
Subject: [PATCH 1/3] SPINDLE/LASER config changes

---
 Marlin/Conditionals_post.h                    |  2 +-
 Marlin/Configuration.h                        |  4 ++
 Marlin/Configuration_adv.h                    | 49 +++++++++++++++
 Marlin/SanityCheck.h                          | 61 +++++++++++++++++++
 .../Cartesio/Configuration.h                  |  4 ++
 .../Cartesio/Configuration_adv.h              | 49 +++++++++++++++
 .../Felix/Configuration.h                     |  4 ++
 .../Felix/Configuration_adv.h                 | 49 +++++++++++++++
 .../Felix/DUAL/Configuration.h                |  4 ++
 .../FolgerTech-i3-2020/Configuration.h        |  4 ++
 .../FolgerTech-i3-2020/Configuration_adv.h    | 53 ++++++++++++++++
 .../Hephestos/Configuration.h                 |  4 ++
 .../Hephestos/Configuration_adv.h             | 49 +++++++++++++++
 .../Hephestos_2/Configuration.h               |  4 ++
 .../Hephestos_2/Configuration_adv.h           | 49 +++++++++++++++
 .../K8200/Configuration.h                     |  4 ++
 .../K8200/Configuration_adv.h                 | 49 +++++++++++++++
 .../K8400/Configuration.h                     |  4 ++
 .../K8400/Configuration_adv.h                 | 49 +++++++++++++++
 .../K8400/Dual-head/Configuration.h           |  4 ++
 .../RepRapWorld/Megatronics/Configuration.h   |  4 ++
 .../RigidBot/Configuration.h                  |  4 ++
 .../RigidBot/Configuration_adv.h              | 49 +++++++++++++++
 .../SCARA/Configuration.h                     |  4 ++
 .../SCARA/Configuration_adv.h                 | 49 +++++++++++++++
 .../TAZ4/Configuration.h                      |  4 ++
 .../TAZ4/Configuration_adv.h                  | 49 +++++++++++++++
 .../TinyBoy2/Configuration.h                  |  4 ++
 .../TinyBoy2/Configuration_adv.h              | 49 +++++++++++++++
 .../WITBOX/Configuration.h                    |  4 ++
 .../WITBOX/Configuration_adv.h                | 49 +++++++++++++++
 .../adafruit/ST7565/Configuration.h           |  4 ++
 .../FLSUN/auto_calibrate/Configuration.h      |  4 ++
 .../FLSUN/auto_calibrate/Configuration_adv.h  | 49 +++++++++++++++
 .../delta/FLSUN/kossel_mini/Configuration.h   |  4 ++
 .../FLSUN/kossel_mini/Configuration_adv.h     | 49 +++++++++++++++
 .../delta/generic/Configuration.h             |  4 ++
 .../delta/generic/Configuration_adv.h         | 49 +++++++++++++++
 .../delta/kossel_mini/Configuration.h         |  4 ++
 .../delta/kossel_mini/Configuration_adv.h     | 49 +++++++++++++++
 .../delta/kossel_pro/Configuration.h          |  4 ++
 .../delta/kossel_pro/Configuration_adv.h      | 49 +++++++++++++++
 .../delta/kossel_xl/Configuration.h           |  4 ++
 .../delta/kossel_xl/Configuration_adv.h       | 49 +++++++++++++++
 .../gCreate_gMax1.5+/Configuration.h          |  4 ++
 .../gCreate_gMax1.5+/Configuration_adv.h      | 49 +++++++++++++++
 .../makibox/Configuration.h                   |  4 ++
 .../makibox/Configuration_adv.h               | 49 +++++++++++++++
 .../tvrrug/Round2/Configuration.h             |  4 ++
 .../tvrrug/Round2/Configuration_adv.h         | 49 +++++++++++++++
 .../wt150/Configuration.h                     |  4 ++
 .../wt150/Configuration_adv.h                 | 49 +++++++++++++++
 52 files changed, 1301 insertions(+), 1 deletion(-)

diff --git a/Marlin/Conditionals_post.h b/Marlin/Conditionals_post.h
index 7cf32396ba..c40289ea56 100644
--- a/Marlin/Conditionals_post.h
+++ b/Marlin/Conditionals_post.h
@@ -579,7 +579,7 @@
   #define HAS_SUICIDE (PIN_EXISTS(SUICIDE))
   #define HAS_PHOTOGRAPH (PIN_EXISTS(PHOTOGRAPH))
   #define HAS_BUZZER (PIN_EXISTS(BEEPER) || ENABLED(LCD_USE_I2C_BUZZER))
-  #define HAS_CASE_LIGHT (PIN_EXISTS(CASE_LIGHT))
+  #define HAS_CASE_LIGHT (PIN_EXISTS(CASE_LIGHT) && ENABLED(CASE_LIGHT_ENABLE))
 
   // Digital control
   #define HAS_MICROSTEPS (HAS_X_MICROSTEPS || HAS_Y_MICROSTEPS || HAS_Z_MICROSTEPS || HAS_E0_MICROSTEPS || HAS_E1_MICROSTEPS || HAS_E2_MICROSTEPS || HAS_E3_MICROSTEPS || HAS_E4_MICROSTEPS)
diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 774178f3d3..529b510aa3 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -129,6 +129,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -172,6 +174,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index b51219dbc8..131af4706f 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -1132,6 +1132,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h
index 4d3b680fb6..9ddda7cbcc 100644
--- a/Marlin/SanityCheck.h
+++ b/Marlin/SanityCheck.h
@@ -1134,3 +1134,64 @@ static_assert(COUNT(sanity_arr_3) >= XYZE, "DEFAULT_MAX_ACCELERATION requires 4
 static_assert(COUNT(sanity_arr_1) <= XYZE_N, "DEFAULT_AXIS_STEPS_PER_UNIT has too many elements.");
 static_assert(COUNT(sanity_arr_2) <= XYZE_N, "DEFAULT_MAX_FEEDRATE has too many elements.");
 static_assert(COUNT(sanity_arr_3) <= XYZE_N, "DEFAULT_MAX_ACCELERATION has too many elements.");
+
+/**
+ * Sanity checks for Spindle / Laser
+ */
+#if ENABLED(SPINDLE_LASER_ENABLE)
+  #if !PIN_EXISTS(SPINDLE_LASER_ENABLE)
+    #error "SPINDLE_LASER_ENABLE requires SPINDLE_LASER_ENABLE_PIN."
+  #elif SPINDLE_DIR_CHANGE && !PIN_EXISTS(SPINDLE_DIR)
+    #error "SPINDLE_DIR_PIN not defined."
+  #elif ENABLED(SPINDLE_LASER_PWM) && PIN_EXISTS(SPINDLE_LASER_PWM)
+    #if !(WITHIN(SPINDLE_LASER_PWM_PIN, 2, 13) || WITHIN(SPINDLE_LASER_PWM_PIN, 44, 46))
+      #error "SPINDLE_LASER_PWM_PIN not assigned to a PWM pin."
+    #elif SPINDLE_LASER_POWERUP_DELAY < 1
+      #error "SPINDLE_LASER_POWERUP_DELAY must be greater than 0."
+    #elif SPINDLE_LASER_POWERDOWN_DELAY < 1
+      #error "SPINDLE_LASER_POWERDOWN_DELAY must be greater than 0."
+    #elif !defined(SPINDLE_LASER_PWM_INVERT)
+      #error "SPINDLE_LASER_PWM_INVERT missing."
+    #elif !defined(SPEED_POWER_SLOPE) || !defined(SPEED_POWER_INTERCEPT) || !defined(SPEED_POWER_MIN) || !defined(SPEED_POWER_MAX)
+      #error "SPINDLE_LASER_PWM equation constant(s) missing."
+    #elif SPINDLE_LASER_PWM_PIN == 4 || WITHIN(SPINDLE_LASER_PWM_PIN, 11, 13)
+      #error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by a system interrupt."
+    #elif PIN_EXISTS(X_MAX) && X_MAX_PIN == SPINDLE_LASER_PWM_PIN
+      #error "SPINDLE_LASER_PWM pin is in use by X_MAX endstop."
+    #elif PIN_EXISTS(X_MIN) && X_MIN_PIN == SPINDLE_LASER_PWM_PIN
+      #error "SPINDLE_LASER_PWM pin is in use by X_MIN endstop."
+    #elif PIN_EXISTS(Z_STEP) && Z_STEP_PIN == SPINDLE_LASER_PWM_PIN
+      #error "SPINDLE_LASER_PWM pin in use by Z_STEP."
+    #elif NUM_SERVOS > 0 && (WITHIN(SPINDLE_LASER_PWM_PIN, 2, 3) || SPINDLE_LASER_PWM_PIN == 5)
+      #error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by the servo system."
+    #elif PIN_EXISTS(CASE_LIGHT) && SPINDLE_LASER_PWM_PIN == CASE_LIGHT_PIN
+      #error "SPINDLE_LASER_PWM_PIN is used by CASE_LIGHT_PIN."
+    #elif PIN_EXISTS(E0_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E0_AUTO_FAN_PIN
+      #error "SPINDLE_LASER_PWM_PIN is used by E0_AUTO_FAN_PIN."
+    #elif PIN_EXISTS(E1_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E1_AUTO_FAN_PIN
+      #error "SPINDLE_LASER_PWM_PIN is used by E1_AUTO_FAN_PIN."
+    #elif PIN_EXISTS(E2_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E2_AUTO_FAN_PIN
+      #error "SPINDLE_LASER_PWM_PIN is used by E2_AUTO_FAN_PIN."
+    #elif PIN_EXISTS(E3_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E3_AUTO_FAN_PIN
+      #error "SPINDLE_LASER_PWM_PIN is used by E3_AUTO_FAN_PIN."
+    #elif PIN_EXISTS(E4_AUTO_FAN) && SPINDLE_LASER_PWM_PIN == E4_AUTO_FAN_PIN
+      #error "SPINDLE_LASER_PWM_PIN is used by E4_AUTO_FAN_PIN."
+    #elif PIN_EXISTS(FAN) && SPINDLE_LASER_PWM_PIN == FAN_PIN
+      #error "SPINDLE_LASER_PWM_PIN is used FAN_PIN."
+    #elif PIN_EXISTS(FAN1) && SPINDLE_LASER_PWM_PIN == FAN1_PIN
+      #error "SPINDLE_LASER_PWM_PIN is used FAN1_PIN."
+    #elif PIN_EXISTS(FAN2) && SPINDLE_LASER_PWM_PIN == FAN2_PIN
+      #error "SPINDLE_LASER_PWM_PIN is used FAN2_PIN."
+    #elif PIN_EXISTS(CONTROLLERFAN) && SPINDLE_LASER_PWM_PIN == CONTROLLERFAN_PIN
+      #error "SPINDLE_LASER_PWM_PIN is used by CONTROLLERFAN_PIN."
+    #elif PIN_EXISTS(MOTOR_CURRENT_PWM_XY) && SPINDLE_LASER_PWM_PIN == MOTOR_CURRENT_PWM_XY_PIN
+      #error "SPINDLE_LASER_PWM_PIN is used by MOTOR_CURRENT_PWM_XY."
+    #elif PIN_EXISTS(MOTOR_CURRENT_PWM_Z) && SPINDLE_LASER_PWM_PIN == MOTOR_CURRENT_PWM_Z_PIN
+      #error "SPINDLE_LASER_PWM_PIN is used by MOTOR_CURRENT_PWM_Z."
+    #elif PIN_EXISTS(MOTOR_CURRENT_PWM_E) && SPINDLE_LASER_PWM_PIN == MOTOR_CURRENT_PWM_E_PIN
+      #error "SPINDLE_LASER_PWM_PIN is used by MOTOR_CURRENT_PWM_E."
+    #elif PIN_EXISTS(CASE_LIGHT) && SPINDLE_LASER_PWM_PIN == CASE_LIGHT_PIN
+      #error "SPINDLE_LASER_PWM_PIN is used by CASE_LIGHT."
+    #endif
+  #endif
+#endif // SPINDLE_LASER_ENABLE
diff --git a/Marlin/example_configurations/Cartesio/Configuration.h b/Marlin/example_configurations/Cartesio/Configuration.h
index 0717c4c712..dc247b68f7 100644
--- a/Marlin/example_configurations/Cartesio/Configuration.h
+++ b/Marlin/example_configurations/Cartesio/Configuration.h
@@ -130,6 +130,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 3
@@ -173,6 +175,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/Cartesio/Configuration_adv.h b/Marlin/example_configurations/Cartesio/Configuration_adv.h
index c26dfb816d..372d3fff58 100644
--- a/Marlin/example_configurations/Cartesio/Configuration_adv.h
+++ b/Marlin/example_configurations/Cartesio/Configuration_adv.h
@@ -1125,6 +1125,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/Felix/Configuration.h b/Marlin/example_configurations/Felix/Configuration.h
index aa49cf9804..55cee75a7e 100644
--- a/Marlin/example_configurations/Felix/Configuration.h
+++ b/Marlin/example_configurations/Felix/Configuration.h
@@ -129,6 +129,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -172,6 +174,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/Felix/Configuration_adv.h b/Marlin/example_configurations/Felix/Configuration_adv.h
index 176fd2ab25..3dabf65d41 100644
--- a/Marlin/example_configurations/Felix/Configuration_adv.h
+++ b/Marlin/example_configurations/Felix/Configuration_adv.h
@@ -1125,6 +1125,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/Felix/DUAL/Configuration.h b/Marlin/example_configurations/Felix/DUAL/Configuration.h
index 521374bf1d..6c967aeff0 100644
--- a/Marlin/example_configurations/Felix/DUAL/Configuration.h
+++ b/Marlin/example_configurations/Felix/DUAL/Configuration.h
@@ -129,6 +129,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 2
@@ -172,6 +174,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/FolgerTech-i3-2020/Configuration.h b/Marlin/example_configurations/FolgerTech-i3-2020/Configuration.h
index 6bdc28dee6..c6e7d8774e 100644
--- a/Marlin/example_configurations/FolgerTech-i3-2020/Configuration.h
+++ b/Marlin/example_configurations/FolgerTech-i3-2020/Configuration.h
@@ -129,6 +129,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -172,6 +174,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/FolgerTech-i3-2020/Configuration_adv.h b/Marlin/example_configurations/FolgerTech-i3-2020/Configuration_adv.h
index 62025ff153..c003216e09 100644
--- a/Marlin/example_configurations/FolgerTech-i3-2020/Configuration_adv.h
+++ b/Marlin/example_configurations/FolgerTech-i3-2020/Configuration_adv.h
@@ -1132,11 +1132,64 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
+// @section debug
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
 #define PINS_DEBUGGING
 
+// @section extras
+
 /**
  * Auto-report temperatures with M155 S<seconds>
  */
diff --git a/Marlin/example_configurations/Hephestos/Configuration.h b/Marlin/example_configurations/Hephestos/Configuration.h
index 9db79cd5f5..21395ffe0d 100644
--- a/Marlin/example_configurations/Hephestos/Configuration.h
+++ b/Marlin/example_configurations/Hephestos/Configuration.h
@@ -132,6 +132,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -175,6 +177,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/Hephestos/Configuration_adv.h b/Marlin/example_configurations/Hephestos/Configuration_adv.h
index 798d741775..903b1ab798 100644
--- a/Marlin/example_configurations/Hephestos/Configuration_adv.h
+++ b/Marlin/example_configurations/Hephestos/Configuration_adv.h
@@ -1125,6 +1125,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/Hephestos_2/Configuration.h b/Marlin/example_configurations/Hephestos_2/Configuration.h
index 8fbf2f8d6a..48623dcd3d 100644
--- a/Marlin/example_configurations/Hephestos_2/Configuration.h
+++ b/Marlin/example_configurations/Hephestos_2/Configuration.h
@@ -129,6 +129,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 #define MACHINE_UUID "8d083632-40c5-4649-85b8-43d9ae6c5d55" // BQ Hephestos 2 standard config
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -172,6 +174,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/Hephestos_2/Configuration_adv.h b/Marlin/example_configurations/Hephestos_2/Configuration_adv.h
index a0c0635769..fd07d62e81 100644
--- a/Marlin/example_configurations/Hephestos_2/Configuration_adv.h
+++ b/Marlin/example_configurations/Hephestos_2/Configuration_adv.h
@@ -1109,6 +1109,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/K8200/Configuration.h b/Marlin/example_configurations/K8200/Configuration.h
index b999644c9d..799a405ca3 100644
--- a/Marlin/example_configurations/K8200/Configuration.h
+++ b/Marlin/example_configurations/K8200/Configuration.h
@@ -149,6 +149,8 @@
   #define MACHINE_UUID "92f72de1-c211-452e-9f2b-61ef88a4751e" // K8200 standard config without VM8201 (Display)
 #endif
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -192,6 +194,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/K8200/Configuration_adv.h b/Marlin/example_configurations/K8200/Configuration_adv.h
index 7f5268d93c..7ae8a93940 100644
--- a/Marlin/example_configurations/K8200/Configuration_adv.h
+++ b/Marlin/example_configurations/K8200/Configuration_adv.h
@@ -1138,6 +1138,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/K8400/Configuration.h b/Marlin/example_configurations/K8400/Configuration.h
index e47c06ea0f..f356ebd864 100644
--- a/Marlin/example_configurations/K8400/Configuration.h
+++ b/Marlin/example_configurations/K8400/Configuration.h
@@ -129,6 +129,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -172,6 +174,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/K8400/Configuration_adv.h b/Marlin/example_configurations/K8400/Configuration_adv.h
index 9ef3258f18..03e130a40f 100644
--- a/Marlin/example_configurations/K8400/Configuration_adv.h
+++ b/Marlin/example_configurations/K8400/Configuration_adv.h
@@ -1125,6 +1125,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/K8400/Dual-head/Configuration.h b/Marlin/example_configurations/K8400/Dual-head/Configuration.h
index 4f79510640..ddf10b4ef6 100644
--- a/Marlin/example_configurations/K8400/Dual-head/Configuration.h
+++ b/Marlin/example_configurations/K8400/Dual-head/Configuration.h
@@ -129,6 +129,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 2
@@ -172,6 +174,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h b/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h
index e9c8c35b30..7b4b0e4b8a 100644
--- a/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h
+++ b/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h
@@ -129,6 +129,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -172,6 +174,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/RigidBot/Configuration.h b/Marlin/example_configurations/RigidBot/Configuration.h
index ca717eebd9..476f5caa88 100644
--- a/Marlin/example_configurations/RigidBot/Configuration.h
+++ b/Marlin/example_configurations/RigidBot/Configuration.h
@@ -132,6 +132,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1  // Single extruder. Set to 2 for dual extruders
@@ -175,6 +177,8 @@
 #define HOTEND_OFFSET_X {0.0, 36.00} // (in mm) for each extruder, offset of the hotend on the X axis
 #define HOTEND_OFFSET_Y {0.0, 0.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/RigidBot/Configuration_adv.h b/Marlin/example_configurations/RigidBot/Configuration_adv.h
index 3d6483b263..4b82cbe355 100644
--- a/Marlin/example_configurations/RigidBot/Configuration_adv.h
+++ b/Marlin/example_configurations/RigidBot/Configuration_adv.h
@@ -1125,6 +1125,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/SCARA/Configuration.h b/Marlin/example_configurations/SCARA/Configuration.h
index b0a96106c7..a1f59cbcb2 100644
--- a/Marlin/example_configurations/SCARA/Configuration.h
+++ b/Marlin/example_configurations/SCARA/Configuration.h
@@ -162,6 +162,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -205,6 +207,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/SCARA/Configuration_adv.h b/Marlin/example_configurations/SCARA/Configuration_adv.h
index 9f6d22b2d7..2ace544332 100644
--- a/Marlin/example_configurations/SCARA/Configuration_adv.h
+++ b/Marlin/example_configurations/SCARA/Configuration_adv.h
@@ -1125,6 +1125,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/TAZ4/Configuration.h b/Marlin/example_configurations/TAZ4/Configuration.h
index cf4b46a447..c5af5592a1 100644
--- a/Marlin/example_configurations/TAZ4/Configuration.h
+++ b/Marlin/example_configurations/TAZ4/Configuration.h
@@ -129,6 +129,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -172,6 +174,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/TAZ4/Configuration_adv.h b/Marlin/example_configurations/TAZ4/Configuration_adv.h
index 8c510aab99..ab8ddc9088 100644
--- a/Marlin/example_configurations/TAZ4/Configuration_adv.h
+++ b/Marlin/example_configurations/TAZ4/Configuration_adv.h
@@ -1125,6 +1125,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/TinyBoy2/Configuration.h b/Marlin/example_configurations/TinyBoy2/Configuration.h
index d92556dcc7..b93b90d0d3 100644
--- a/Marlin/example_configurations/TinyBoy2/Configuration.h
+++ b/Marlin/example_configurations/TinyBoy2/Configuration.h
@@ -151,6 +151,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -194,6 +196,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/TinyBoy2/Configuration_adv.h b/Marlin/example_configurations/TinyBoy2/Configuration_adv.h
index ee78175bc3..7e714b3595 100644
--- a/Marlin/example_configurations/TinyBoy2/Configuration_adv.h
+++ b/Marlin/example_configurations/TinyBoy2/Configuration_adv.h
@@ -1128,6 +1128,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/WITBOX/Configuration.h b/Marlin/example_configurations/WITBOX/Configuration.h
index 073dafe000..3dcf34e706 100644
--- a/Marlin/example_configurations/WITBOX/Configuration.h
+++ b/Marlin/example_configurations/WITBOX/Configuration.h
@@ -132,6 +132,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -175,6 +177,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/WITBOX/Configuration_adv.h b/Marlin/example_configurations/WITBOX/Configuration_adv.h
index 798d741775..903b1ab798 100644
--- a/Marlin/example_configurations/WITBOX/Configuration_adv.h
+++ b/Marlin/example_configurations/WITBOX/Configuration_adv.h
@@ -1125,6 +1125,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/adafruit/ST7565/Configuration.h b/Marlin/example_configurations/adafruit/ST7565/Configuration.h
index d9bbb2b256..3b9f667d86 100644
--- a/Marlin/example_configurations/adafruit/ST7565/Configuration.h
+++ b/Marlin/example_configurations/adafruit/ST7565/Configuration.h
@@ -129,6 +129,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -172,6 +174,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h b/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h
index 1e94e31b4e..2c31e0226c 100644
--- a/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h
+++ b/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h
@@ -129,6 +129,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -172,6 +174,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h b/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h
index 010a1989d9..3f1f4db533 100644
--- a/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration_adv.h
@@ -1130,6 +1130,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration.h b/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration.h
index 8ec27db5b0..ce585c1aff 100644
--- a/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration.h
+++ b/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration.h
@@ -129,6 +129,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -172,6 +174,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h b/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h
index b3f183a31c..4234c831a3 100644
--- a/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration_adv.h
@@ -1129,6 +1129,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/delta/generic/Configuration.h b/Marlin/example_configurations/delta/generic/Configuration.h
index 83776fa7f1..0b942adba0 100644
--- a/Marlin/example_configurations/delta/generic/Configuration.h
+++ b/Marlin/example_configurations/delta/generic/Configuration.h
@@ -129,6 +129,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -172,6 +174,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/delta/generic/Configuration_adv.h b/Marlin/example_configurations/delta/generic/Configuration_adv.h
index deb74b6d64..295b82b0d6 100644
--- a/Marlin/example_configurations/delta/generic/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/generic/Configuration_adv.h
@@ -1127,6 +1127,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/delta/kossel_mini/Configuration.h b/Marlin/example_configurations/delta/kossel_mini/Configuration.h
index b8e7fc5ff5..3c9fff7d61 100644
--- a/Marlin/example_configurations/delta/kossel_mini/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_mini/Configuration.h
@@ -129,6 +129,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -172,6 +174,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h b/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h
index deb74b6d64..295b82b0d6 100644
--- a/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h
@@ -1127,6 +1127,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/delta/kossel_pro/Configuration.h b/Marlin/example_configurations/delta/kossel_pro/Configuration.h
index 3e60201950..6e672402a5 100644
--- a/Marlin/example_configurations/delta/kossel_pro/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_pro/Configuration.h
@@ -133,6 +133,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -176,6 +178,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h b/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h
index 8bb8f312a9..dc0a77bdb0 100644
--- a/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/kossel_pro/Configuration_adv.h
@@ -1132,6 +1132,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/delta/kossel_xl/Configuration.h b/Marlin/example_configurations/delta/kossel_xl/Configuration.h
index 4ecc7be435..62f9bafb52 100644
--- a/Marlin/example_configurations/delta/kossel_xl/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_xl/Configuration.h
@@ -129,6 +129,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -172,6 +174,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h b/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h
index aad4304e5e..5f73c52f2b 100644
--- a/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/kossel_xl/Configuration_adv.h
@@ -1127,6 +1127,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/gCreate_gMax1.5+/Configuration.h b/Marlin/example_configurations/gCreate_gMax1.5+/Configuration.h
index 6271302307..776b9e9dd3 100644
--- a/Marlin/example_configurations/gCreate_gMax1.5+/Configuration.h
+++ b/Marlin/example_configurations/gCreate_gMax1.5+/Configuration.h
@@ -134,6 +134,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -177,6 +179,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/gCreate_gMax1.5+/Configuration_adv.h b/Marlin/example_configurations/gCreate_gMax1.5+/Configuration_adv.h
index 52bc16cbcf..1bf2b69c58 100644
--- a/Marlin/example_configurations/gCreate_gMax1.5+/Configuration_adv.h
+++ b/Marlin/example_configurations/gCreate_gMax1.5+/Configuration_adv.h
@@ -1132,6 +1132,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/makibox/Configuration.h b/Marlin/example_configurations/makibox/Configuration.h
index 13f4aa287a..56cec59aa2 100644
--- a/Marlin/example_configurations/makibox/Configuration.h
+++ b/Marlin/example_configurations/makibox/Configuration.h
@@ -129,6 +129,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -172,6 +174,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/makibox/Configuration_adv.h b/Marlin/example_configurations/makibox/Configuration_adv.h
index c8c38d60f6..9050fc6760 100644
--- a/Marlin/example_configurations/makibox/Configuration_adv.h
+++ b/Marlin/example_configurations/makibox/Configuration_adv.h
@@ -1125,6 +1125,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/tvrrug/Round2/Configuration.h b/Marlin/example_configurations/tvrrug/Round2/Configuration.h
index 9701dd114a..53d75f1f65 100644
--- a/Marlin/example_configurations/tvrrug/Round2/Configuration.h
+++ b/Marlin/example_configurations/tvrrug/Round2/Configuration.h
@@ -129,6 +129,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -172,6 +174,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h b/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h
index daf9e0d7dc..f3022c7b23 100644
--- a/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h
+++ b/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h
@@ -1125,6 +1125,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */
diff --git a/Marlin/example_configurations/wt150/Configuration.h b/Marlin/example_configurations/wt150/Configuration.h
index b3b334f24e..2c1e4cfb6a 100644
--- a/Marlin/example_configurations/wt150/Configuration.h
+++ b/Marlin/example_configurations/wt150/Configuration.h
@@ -129,6 +129,8 @@
 // You can use an online service to generate a random UUID. (eg http://www.uuidgenerator.net/version4)
 //#define MACHINE_UUID "5f0bb7a3-0e14-428c-812b-15ab0d3ecc71"
 
+// @section extruder
+
 // This defines the number of extruders
 // :[1, 2, 3, 4, 5]
 #define EXTRUDERS 1
@@ -172,6 +174,8 @@
 //#define HOTEND_OFFSET_X {0.0, 20.00} // (in mm) for each extruder, offset of the hotend on the X axis
 //#define HOTEND_OFFSET_Y {0.0, 5.00}  // (in mm) for each extruder, offset of the hotend on the Y axis
 
+// @section machine
+
 /**
  * Select your power supply here. Use 0 if you haven't connected the PS_ON_PIN
  *
diff --git a/Marlin/example_configurations/wt150/Configuration_adv.h b/Marlin/example_configurations/wt150/Configuration_adv.h
index 81d5028b2d..d5d5952017 100644
--- a/Marlin/example_configurations/wt150/Configuration_adv.h
+++ b/Marlin/example_configurations/wt150/Configuration_adv.h
@@ -1128,6 +1128,55 @@
 //#define EXPERIMENTAL_I2CBUS
 #define I2C_SLAVE_ADDRESS  0 // Set a value from 8 to 127 to act as a slave
 
+// @section extras
+
+/**
+ * Spindle & Laser control
+ *
+ * Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
+ * to set spindle speed, spindle direction, and laser power.
+ *
+ * SuperPid is a router/spindle speed controller used in the CNC milling community.
+ * Marlin can be used to turn the spindle on and off. It can also be used to set
+ * the spindle speed from 5,000 to 30,000 RPM.
+ *
+ * You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
+ * hardware PWM pin for the speed control and a pin for the rotation direction.
+ *
+ * See http://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
+ */
+//#define SPINDLE_LASER_ENABLE
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #define SPINDLE_LASER_ENABLE_INVERT   false  // set to "true" if the on/off function is reversed
+  #define SPINDLE_LASER_PWM             true   // set to true if your controller supports setting the speed/power
+  #define SPINDLE_LASER_PWM_INVERT      true   // set to "true" if the speed/power goes up when you want it to go slower
+  #define SPINDLE_LASER_POWERUP_DELAY   5000   // delay in milliseconds to allow the spindle/laser to come up to speed/power
+  #define SPINDLE_LASER_POWERDOWN_DELAY 5000   // delay in milliseconds to allow the spindle to stop
+  #define SPINDLE_DIR_CHANGE            true   // set to true if your spindle controller supports changing spindle direction
+  #define SPINDLE_INVERT_DIR            false
+  #define SPINDLE_STOP_ON_DIR_CHANGE    true   // set to true if Marlin should stop the spindle before changing rotation direction
+
+  /**
+   *  The M3 & M4 commands use the following equation to convert PWM duty cycle to speed/power
+   *
+   *  SPEED/POWER = PWM duty cycle * SPEED_POWER_SLOPE + SPEED_POWER_INTERCEPT
+   *    where PWM duty cycle varies from 0 to 255
+   *
+   *  set the following for your controller (ALL MUST BE SET)
+   */
+
+  #define SPEED_POWER_SLOPE    118.4
+  #define SPEED_POWER_INTERCEPT  0
+  #define SPEED_POWER_MIN     5000
+  #define SPEED_POWER_MAX    30000    // SuperPID router controller 0 - 30,000 RPM
+
+  //#define SPEED_POWER_SLOPE      0.3922
+  //#define SPEED_POWER_INTERCEPT  0
+  //#define SPEED_POWER_MIN       10
+  //#define SPEED_POWER_MAX      100      // 0-100%
+#endif
+
 /**
  * M43 - display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins
  */

From ffe0e2d19aea47b9f51937cc40a9bcaa3a370e1d Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 7 Apr 2017 13:52:21 -0500
Subject: [PATCH 2/3] SPINDLE/LASER pins changes

---
 Marlin/pinsDebug_list.h        |   4 +-
 Marlin/pins_3DRAG.h            |  57 +++++++++
 Marlin/pins_AZTEEG_X3.h        |  35 ++++++
 Marlin/pins_AZTEEG_X3_PRO.h    |  38 ++++++
 Marlin/pins_BAM_DICE_DUE.h     |   7 ++
 Marlin/pins_BQ_ZUM_MEGA_3D.h   |  12 ++
 Marlin/pins_BRAINWAVE.h        |  34 +++++
 Marlin/pins_BRAINWAVE_PRO.h    |  60 ++++++++-
 Marlin/pins_FELIX2.h           |   7 ++
 Marlin/pins_GEN3_MONOLITHIC.h  |  26 ++++
 Marlin/pins_GEN3_PLUS.h        |  27 +++-
 Marlin/pins_GEN6.h             |  35 ++++++
 Marlin/pins_GEN6_DELUXE.h      |  26 ++++
 Marlin/pins_GEN7_12.h          |  52 +++++++-
 Marlin/pins_GEN7_13.h          |  25 ++++
 Marlin/pins_GEN7_14.h          |  49 ++++++--
 Marlin/pins_GEN7_CUSTOM.h      |  37 +++++-
 Marlin/pins_K8400.h            |   5 +
 Marlin/pins_MEGACONTROLLER.h   |   8 ++
 Marlin/pins_MEGATRONICS.h      |   8 ++
 Marlin/pins_MEGATRONICS_2.h    |  12 +-
 Marlin/pins_MEGATRONICS_3.h    |  27 ++++
 Marlin/pins_MIGHTYBOARD_REVE.h |  31 ++++-
 Marlin/pins_MINIRAMBO.h        |  10 ++
 Marlin/pins_MINITRONICS.h      |  23 ++++
 Marlin/pins_MKS_BASE.h         |  13 +-
 Marlin/pins_OMCA.h             |  25 ++++
 Marlin/pins_OMCA_A.h           |  27 +++-
 Marlin/pins_RAMBO.h            |   8 ++
 Marlin/pins_RAMPS.h            |  26 ++++
 Marlin/pins_RAMPS_OLD.h        |   8 ++
 Marlin/pins_RIGIDBOARD.h       |  18 +--
 Marlin/pins_RUMBA.h            |  12 +-
 Marlin/pins_SANGUINOLOLU_11.h  |  98 +++++++++++++--
 Marlin/pins_SAV_MKI.h          |  16 ++-
 Marlin/pins_SETHI.h            |  25 ++++
 Marlin/pins_TEENSY2.h          |   8 ++
 Marlin/pins_TEENSYLU.h         | 161 +++++++++++++++++-------
 Marlin/pins_ULTIMAIN_2.h       |  21 ++++
 Marlin/pins_ULTIMAKER.h        |  16 +++
 Marlin/pins_ULTIMAKER_OLD.h    | 220 ++++++++++++++++++++++++++++++---
 41 files changed, 1247 insertions(+), 110 deletions(-)

diff --git a/Marlin/pinsDebug_list.h b/Marlin/pinsDebug_list.h
index 758c332dc8..dfdd411046 100644
--- a/Marlin/pinsDebug_list.h
+++ b/Marlin/pinsDebug_list.h
@@ -515,8 +515,8 @@
 #if PIN_EXISTS(SPINDLE_LASER_ENABLE)
   REPORT_NAME_DIGITAL(SPINDLE_LASER_ENABLE_PIN, __LINE__ )
 #endif
-#if PIN_EXISTS(SPINDLE_SPEED_LASER_POWER)
-  REPORT_NAME_DIGITAL(SPINDLE_SPEED_LASER_POWER_PIN, __LINE__ )
+#if PIN_EXISTS(SPINDLE_LASER_PWM)
+  REPORT_NAME_DIGITAL(SPINDLE_LASER_PWM_PIN, __LINE__ )
 #endif
 #if PIN_EXISTS(SR_CLK)
   REPORT_NAME_DIGITAL(SR_CLK_PIN, __LINE__ )
diff --git a/Marlin/pins_3DRAG.h b/Marlin/pins_3DRAG.h
index 9eaf2c9f65..feadea4e3c 100644
--- a/Marlin/pins_3DRAG.h
+++ b/Marlin/pins_3DRAG.h
@@ -43,6 +43,8 @@
 #define RAMPS_D9_PIN 8
 #define MOSFET_D_PIN 12
 
+#define CASE_LIGHT_PIN -1     // MUST BE HARDWARE PWM but one is not available on expansion header
+
 #include "pins_RAMPS.h"
 
 //
@@ -104,3 +106,58 @@
   #define BEEPER_PIN       33
 
 #endif // ULTRA_LCD && NEWPANEL
+
+/**
+ *  M3/M4/M5 - Spindle/Laser Control
+ *
+ *  If you want to control the speed of your spindle then you'll have
+ *  have to sacrifce the Extruder and pull some signals off the Z stepper
+ *  driver socket.
+ *
+ *  The following assumes:
+ *   - the Z stepper driver socket is empty
+ *   - the extruder driver socket has a driver board plugged into it
+ *   - the Z stepper wires are attached the the extruder connector
+ *
+ *  If you want to keep the extruder AND don't have a LCD display then
+ *  you can still control the power on/off and spindle direction.
+ *
+ *  Where to get spindle signals
+ *
+ *      stepper signal           socket name       socket name
+ *                                          -------
+ *       SPINDLE_LASER_ENABLE_PIN /ENABLE  O|     |O  VMOT
+ *                                    MS1  O|     |O  GND
+ *                                    MS2  O|     |O  2B
+ *                                    MS3  O|     |O  2A
+ *                                 /RESET  O|     |O  1A
+ *                                 /SLEEP  O|     |O  1B
+ *          SPINDLE_LASER_PWM_PIN    STEP  O|     |O  VDD
+ *                SPINDLE_DIR_PIN     DIR  O|     |O  GND
+ *                                          -------
+ *
+ *  Note: Socket names vary from vendor to vendor
+ */
+#undef SPINDLE_LASER_PWM_PIN    // Definitions in pins_RAMPS.h are not good with 3DRAG
+#undef SPINDLE_LASER_ENABLE_PIN
+#undef SPINDLE_DIR_PIN
+
+#if ENABLED(SPINDLE_LASER_ENABLE)
+  #if !EXTRUDERS
+    #undef E0_DIR_PIN
+    #undef E0_ENABLE_PIN
+    #undef E0_STEP_PIN
+    #undef Z_DIR_PIN
+    #undef Z_ENABLE_PIN
+    #undef Z_STEP_PIN
+    #define Z_DIR_PIN                28
+    #define Z_ENABLE_PIN             24
+    #define Z_STEP_PIN               26
+    #define SPINDLE_LASER_PWM_PIN    46  // MUST BE HARDWARE PWM
+    #define SPINDLE_LASER_ENABLE_PIN 62  // Pin should have a pullup!
+    #define SPINDLE_DIR_PIN          48
+  #elif !(ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL)) // use expansion header if no LCD in use
+    #define SPINDLE_LASER_ENABLE_PIN 16  // Pin should have a pullup/pulldown!
+    #define SPINDLE_DIR_PIN          17
+  #endif
+#endif
diff --git a/Marlin/pins_AZTEEG_X3.h b/Marlin/pins_AZTEEG_X3.h
index 364697d608..430a9fa427 100644
--- a/Marlin/pins_AZTEEG_X3.h
+++ b/Marlin/pins_AZTEEG_X3.h
@@ -24,12 +24,20 @@
  * AZTEEG_X3 Arduino Mega with RAMPS v1.4 pin assignments
  */
 
+#ifndef __AVR_ATmega2560__
+  #error "Oops! Make sure you have 'Arduino Mega 2560' selected from the 'Tools -> Boards' menu."
+#endif
+
 #if HOTENDS > 2 || E_STEPPERS > 2
   #error "Azteeg X3 supports up to 2 hotends / E-steppers. Comment out this line to continue."
 #endif
 
 #define BOARD_NAME "Azteeg X3"
 
+#if !PIN_EXISTS(CASE_LIGHT)         // doesn't already exist so OK to change the definition coming
+  #define OK_TO_CHANGE_CASE_LIGHT   // in from from the include file
+#endif
+
 #include "pins_RAMPS_13.h"
 
 //
@@ -63,3 +71,30 @@
   #define STAT_LED_BLUE_PIN 11
 
 #endif
+
+//
+// Misc
+//
+#if ENABLED(OK_TO_CHANGE_CASE_LIGHT) && STAT_LED_RED_PIN == 6
+  #undef STAT_LED_RED_PIN
+  #undef CASE_LIGHT_PIN
+  #define CASE_LIGHT_PIN 6  // open collector FET driver
+#endif
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#undef SPINDLE_LASER_PWM_PIN    // Definitions in pins_RAMPS.h are no good with the AzteegX3 board
+#undef SPINDLE_LASER_ENABLE_PIN
+#undef SPINDLE_DIR_PIN
+
+#if ENABLED(SPINDLE_LASER_ENABLE)
+  #undef SDA                       // use EXP3 header
+  #undef SCL
+  #if SERVO0_PIN == 7
+    #undef SERVO0_PIN
+    #def SERVO0_PIN 11
+  #define SPINDLE_LASER_PWM_PIN     7  // MUST BE HARDWARE PWM
+  #define SPINDLE_LASER_ENABLE_PIN 20  // Pin should have a pullup!
+  #define SPINDLE_DIR_PIN          21
+#endif
diff --git a/Marlin/pins_AZTEEG_X3_PRO.h b/Marlin/pins_AZTEEG_X3_PRO.h
index 41df3be5b8..7701f8b681 100644
--- a/Marlin/pins_AZTEEG_X3_PRO.h
+++ b/Marlin/pins_AZTEEG_X3_PRO.h
@@ -30,8 +30,16 @@
 
 #define BOARD_NAME "Azteeg X3 Pro"
 
+#if !PIN_EXISTS(CASE_LIGHT)         // doesn't already exist so OK to change the definition coming
+  #define OK_TO_CHANGE_CASE_LIGHT   // in from from the include file
+#endif
+
 #include "pins_RAMPS.h"
 
+#ifndef __AVR_ATmega2560__
+  #error "Oops! Make sure you have 'Arduino Mega 2560' selected from the 'Tools -> Boards' menu."
+#endif
+
 //
 // Servos
 //
@@ -126,7 +134,37 @@
 #if ENABLED(VIKI2) || ENABLED(miniVIKI)
   #undef SD_DETECT_PIN
   #define SD_DETECT_PIN    49 // For easy adapter board
+  #undef BEEPER_PIN
+  #define  BEEPER_PIN  12     // 33 isn't physically available to the LCD display
 #else
   #define STAT_LED_RED_PIN 32
   #define STAT_LED_BLUE_PIN 35
 #endif
+
+//
+// Misc. Functions
+//
+#undef DOGLCD_A0            // steal pin 44 for the case light
+#define DOGLCD_A0      57
+#if ENABLED(OK_TO_CHANGE_CASE_LIGHT)
+  #undef CASE_LIGHT_PIN
+  #define CASE_LIGHT_PIN 44    // must have a hardware PWM
+#endif
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#undef SPINDLE_LASER_PWM_PIN    // Definitions in pins_RAMPS.h are no good with the AzteegX3 board
+#undef SPINDLE_LASER_ENABLE_PIN
+#undef SPINDLE_DIR_PIN
+
+#if ENABLED(SPINDLE_LASER_ENABLE)   // use EXP2 header
+  #if ENABLED(VIKI2) || ENABLED(miniVIKI)
+    #undef BTN_EN2
+    #define BTN_EN2             31  // need 7 for the spindle speed PWM
+  #endif
+  #define SPINDLE_LASER_PWM_PIN     7  // must have a hardware PWM
+  #define SPINDLE_LASER_ENABLE_PIN 20  // Pin should have a pullup!
+  #define SPINDLE_DIR_PIN          21
+#endif
+
diff --git a/Marlin/pins_BAM_DICE_DUE.h b/Marlin/pins_BAM_DICE_DUE.h
index 0da4f08c40..2b34cddd83 100644
--- a/Marlin/pins_BAM_DICE_DUE.h
+++ b/Marlin/pins_BAM_DICE_DUE.h
@@ -30,6 +30,13 @@
 
 #define BOARD_NAME "2PrintBeta Due"
 
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#define SPINDLE_LASER_ENABLE_PIN 66  // Pin should have a pullup/pulldown!
+#define SPINDLE_DIR_PIN          67
+#define SPINDLE_LASER_PWM_PIN    44  // MUST BE HARDWARE PWM
+
 #include "pins_RAMPS.h"
 
 //
diff --git a/Marlin/pins_BQ_ZUM_MEGA_3D.h b/Marlin/pins_BQ_ZUM_MEGA_3D.h
index 402c1cb2ff..84722f11c9 100644
--- a/Marlin/pins_BQ_ZUM_MEGA_3D.h
+++ b/Marlin/pins_BQ_ZUM_MEGA_3D.h
@@ -46,6 +46,18 @@
 #define ORIG_E2_AUTO_FAN_PIN  6
 #define ORIG_E3_AUTO_FAN_PIN  6
 
+//
+// Misc. Functions
+//
+#define CASE_LIGHT_PIN   44     // MUST BE HARDWARE PWM
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#define SPINDLE_LASER_ENABLE_PIN 40  // Pin should have a pullup/pulldown!
+#define SPINDLE_LASER_PWM_PIN    44  // MUST BE HARDWARE PWM
+#define SPINDLE_DIR_PIN          42
+
 #include "pins_RAMPS_13.h"
 
 //
diff --git a/Marlin/pins_BRAINWAVE.h b/Marlin/pins_BRAINWAVE.h
index ba9d04099c..0d17cac10f 100644
--- a/Marlin/pins_BRAINWAVE.h
+++ b/Marlin/pins_BRAINWAVE.h
@@ -27,6 +27,40 @@
  * https://github.com/unrepentantgeek/brainwave-arduino
  */
 
+/**
+ *  Rev B  16 JAN 2017
+ *
+ *  Added pointer to a currently available Arduino IDE extension that will
+ *  allow this board to use the latest Marlin software
+ */
+
+/**
+ *  Marlin_AT90USB - https://github.com/Bob-the-Kuhn/Marlin_AT90USB
+ *    This is the only known IDE extension that is compatible with the pin definitions
+ *    in this file, Adrduino 1.6.12 and the latest mainstream Marlin software.
+ *
+ *    "Marlin_AT90USB" makes PWM0A available rather than the usual PWM1C. These PWMs share
+ *    the same physical pin. Marlin uses TIMER1 to generate interrupts and sets it up such
+ *    that PWM1A, PWM1B & PWM1C can not be used.
+ *
+ *  Installation:
+ *
+ *    1. In the Arduino IDE, under Files -> Preferences paste the following URL
+ *       https://rawgit.com/Bob-the-Kuhn/Marlin_AT90USB/master/package_MARLIN_AT90USB_index.json
+ *    2. Under Tools -> Board -> Boards manager, scroll to the bottom, click on MARLIN_AT90USB
+ *       and then click on "Install"
+ *    3. Select "AT90USB646_STANDARD" from the 'Tools -> Boards' menu.
+ */
+
+/**
+ *  To burn the bootloader that comes with Marlin_AT90USB:
+ *
+ *    1. Connect your programmer to the board.
+ *    2. In Arduino IDE select "AT90USB646_STANDARD" and then select the programmer.
+ *    3. In Arduino IDE click on "burn bootloader". Don't worry about the "verify failed at 1F000" error message.
+ *    4. The programmer is no longer needed. Remove it.
+ */
+
 #ifndef __AVR_AT90USB646__
   #error "Oops!  Make sure you have 'Brainwave' selected from the 'Tools -> Boards' menu."
 #endif
diff --git a/Marlin/pins_BRAINWAVE_PRO.h b/Marlin/pins_BRAINWAVE_PRO.h
index b353581f0a..1884d3cb13 100644
--- a/Marlin/pins_BRAINWAVE_PRO.h
+++ b/Marlin/pins_BRAINWAVE_PRO.h
@@ -27,14 +27,70 @@
  * https://github.com/unrepentantgeek/brainwave-arduino
  */
 
+/**
+ *  Rev B  16 JAN 2017
+ *
+ *  Added pointers to currently available Arduino IDE extensions that will
+ *  allow this board to use the latest Marlin software
+ */
+
+/**
+ *  There are three Arduino IDE extensions that are compatible with this board
+ *  and with the mainstream Marlin software.  All have been used with Arduino 1.6.12
+ *
+ *  Teensyduino - http://www.pjrc.com/teensy/teensyduino.html
+ *    Select Teensy++ 2.0 in Arduino IDE from the 'Tools -> Boards' menu
+ *
+ *    Installation instructions are at the above URL.  Don't bother loading the
+ *    libraries - they are not used with the Marlin software.
+ *
+ *  Printrboard - https://github.com/scwimbush/Printrboard-HID-Arduino-IDE-Support
+ *    This is basically Teensyduino but with a bootloader that can handle image sizes
+ *    larger than 64K.
+ *
+ *    Installation:
+ *
+ *       1. Go to the above URL, click on the "Clone or Download" button and then
+ *          click on "Download ZIP" button.
+ *       2. Unzip the file, find the "printrboard" directory and then copy it to the
+ *          hardware directory in Arduino.  The Arduino hardware directory will probably
+ *			be located in a path similar to this: C:\Program Files (x86)\Arduino\hardware.
+ *       3. Restart Arduino.
+ *       4. Select "Printrboard" from the 'Tools -> Boards' menu.
+ *
+ *  Marlin_AT90USB - https://github.com/Bob-the-Kuhn/Marlin_AT90USB
+ *    Uses the bootloader from Printerboard above.
+ *
+ *    "Marlin_AT90USB" makes PWM0A available rather than the usual PWM1C. These PWMs share
+ *    the same physical pin. Marlin uses TIMER1 to generate interrupts and sets it up such
+ *    that PWM1A, PWM1B & PWM1C can not be used.
+ *
+ *    Installation:
+ *
+ *       1. In the Arduino IDE, under Files -> Preferences paste the following URL
+ *          https://rawgit.com/Bob-the-Kuhn/Marlin_AT90USB/master/package_MARLIN_AT90USB_index.json
+ *       2. Under Tools -> Board -> Boards manager, scroll to the bottom, click on MARLIN_AT90USB
+ *          and then click on "Install"
+ *       3. Select "AT90USB1286_TEENSYPP" from the 'Tools -> Boards' menu.
+ */
+
+/**
+ *  To burn the bootloader that comes with Printrboard and Marlin_AT90USB:
+ *
+ *   1. Connect your programmer to the board.
+ *   2. In the Arduino IDE select "Printrboard" or "AT90USB1286_TEENSYPP" and then select the programmer.
+ *   3. In the Arduino IDE click on "burn bootloader". Don't worry about the "verify failed at 1F000" error message.
+ *   4. The programmer is no longer needed. Remove it.
+ */
+
 #ifndef __AVR_AT90USB1286__
-  #error "Oops!  Make sure you have 'Brainwave Pro' selected from the 'Tools -> Boards' menu."
+  #error "Oops!  Make sure you have 'Teensy++ 2.0', 'AT90USB1286_TEENSYPP', or 'Printrboard' selected from the 'Tools -> Boards' menu."
 #endif
 
 #include "fastio.h"
 
 #if DISABLED(AT90USBxx_TEENSYPP_ASSIGNMENTS) // use Teensyduino Teensy++2.0 pin assignments instead of Marlin alphabetical.
-  #error "Uncomment #define AT90USBxx_TEENSYPP_ASSIGNMENTS in fastio.h for this config"
+  #error "Uncomment '#define AT90USBxx_TEENSYPP_ASSIGNMENTS' in fastio.h for this config"
 #endif
 
 #define BOARD_NAME         "Brainwave Pro"
diff --git a/Marlin/pins_FELIX2.h b/Marlin/pins_FELIX2.h
index 28894fe97a..5d6765c840 100644
--- a/Marlin/pins_FELIX2.h
+++ b/Marlin/pins_FELIX2.h
@@ -54,3 +54,10 @@
   #define SD_DETECT_PIN 6
 
 #endif // NEWPANEL && ULTRA_LCD
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#undef SPINDLE_LASER_PWM_PIN     // Definitions in pins_RAMPS.h are not valid with this board
+#undef SPINDLE_LASER_ENABLE_PIN
+#undef SPINDLE_DIR_PIN
diff --git a/Marlin/pins_GEN3_MONOLITHIC.h b/Marlin/pins_GEN3_MONOLITHIC.h
index e7a5dfb0d1..dae4046fd2 100644
--- a/Marlin/pins_GEN3_MONOLITHIC.h
+++ b/Marlin/pins_GEN3_MONOLITHIC.h
@@ -24,6 +24,31 @@
  * Gen3 Monolithic Electronics pin assignments
  */
 
+/**
+ * Rev B    26 DEC 2016
+ *
+ * added pointer to a current Arduino IDE extension
+ *
+ */
+
+/**
+ * A useable Arduino IDE extension (board manager) can be found at
+ * https://github.com/Lauszus/Sanguino
+ *
+ * This extension has been tested on Arduino 1.6.12 & 1.8.0
+ *
+ * Here's the JSON path:
+ * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json
+ *
+ * When installing select 1.0.2
+ *
+ * Installation instructions can be found at https://learn.sparkfun.com/pages/CustomBoardsArduino
+ * Just use the above JSON URL instead of Sparkfun's JSON.
+ *
+ * Once installed select the Sanguino board and then select the CPU.
+ *
+ */
+
 #ifndef __AVR_ATmega644P__
   #error "Oops!  Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu."
 #endif
@@ -73,3 +98,4 @@
 #define PS_ON_PIN          14 // Alex, does this work on the card?
 
 // Alex extras from Gen3+
+
diff --git a/Marlin/pins_GEN3_PLUS.h b/Marlin/pins_GEN3_PLUS.h
index b5236d87ea..85c47305b3 100644
--- a/Marlin/pins_GEN3_PLUS.h
+++ b/Marlin/pins_GEN3_PLUS.h
@@ -24,6 +24,32 @@
  * Gen3+ pin assignments
  */
 
+/**
+ * Rev B    26 DEC 2016
+ *
+ * added pointer to a current Arduino IDE extension
+ *
+ */
+
+/**
+ * A useable Arduino IDE extension (board manager) can be found at
+ * https://github.com/Lauszus/Sanguino
+ *
+ * This extension has been tested on Arduino 1.6.12 & 1.8.0
+ *
+ * Here's the JSON path:
+ * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json
+ *
+ * When installing select 1.0.2
+ *
+ * Installation instructions can be found at https://learn.sparkfun.com/pages/CustomBoardsArduino
+ * Just use the above JSON URL instead of Sparkfun's JSON.
+ *
+ * Once installed select the SANGUINO board and then select the CPU.
+ *
+ */
+
+
 #if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega1284P__)
   #error "Oops!  Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu."
 #endif
@@ -73,4 +99,3 @@
 //
 #define SDSS                4
 #define PS_ON_PIN          14
-
diff --git a/Marlin/pins_GEN6.h b/Marlin/pins_GEN6.h
index 9d1e1bcf18..10a285790d 100644
--- a/Marlin/pins_GEN6.h
+++ b/Marlin/pins_GEN6.h
@@ -24,6 +24,33 @@
  * Gen6 pin assignments
  */
 
+ /**
+ * Rev B    26 DEC 2016
+ *
+ * 1) added pointer to a current Arduino IDE extension
+ * 2) added support for M3, M4 & M5 spindle control commands
+ * 3) added case light pin definition
+ *
+ */
+
+/**
+ * A useable Arduino IDE extension (board manager) can be found at
+ * https://github.com/Lauszus/Sanguino
+ *
+ * This extension has been tested on Arduino 1.6.12 & 1.8.0
+ *
+ * Here's the JSON path:
+ * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json
+ *
+ * When installing select 1.0.2
+ *
+ * Installation instructions can be found at https://learn.sparkfun.com/pages/CustomBoardsArduino
+ * Just use the above JSON URL instead of Sparkfun's JSON.
+ *
+ * Once installed select the Sanguino board and then select the CPU.
+ *
+ */
+
 #ifndef __AVR_ATmega644P__
   #ifndef __AVR_ATmega1284P__
     #error "Oops!  Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu."
@@ -80,7 +107,15 @@
 //
 #define SDSS               17
 #define DEBUG_PIN           0
+#define CASE_LIGHT_PIN   16     // MUST BE HARDWARE PWM
 
 // RS485 pins
 #define TX_ENABLE_PIN      12
 #define RX_ENABLE_PIN      13
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#define SPINDLE_LASER_ENABLE_PIN  5     // Pin should have a pullup/pulldown!
+#define SPINDLE_LASER_PWM_PIN    16     // MUST BE HARDWARE PWM
+#define SPINDLE_DIR_PIN           6
diff --git a/Marlin/pins_GEN6_DELUXE.h b/Marlin/pins_GEN6_DELUXE.h
index b1a1037ed9..5834068667 100644
--- a/Marlin/pins_GEN6_DELUXE.h
+++ b/Marlin/pins_GEN6_DELUXE.h
@@ -24,6 +24,32 @@
  * Gen6 Deluxe pin assignments
  */
 
+/**
+ * Rev B    26 DEC 2016
+ *
+ * added pointer to a current Arduino IDE extension
+ *
+ */
+
+/**
+ * A useable Arduino IDE extension (board manager) can be found at
+ * https://github.com/Lauszus/Sanguino
+ *
+ * This extension has been tested on Arduino 1.6.12 & 1.8.0
+ *
+ * Here's the JSON path:
+ * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json
+ *
+ * When installing select 1.0.2
+ *
+ * Installation instructions can be found at https://learn.sparkfun.com/pages/CustomBoardsArduino
+ * Just use the above JSON URL instead of Sparkfun's JSON.
+ *
+ * Once installed select the SANGUINO board and then select the CPU.
+ *
+ */
+
+
 #define BOARD_NAME "Gen6 Deluxe"
 
 #include "pins_GEN6.h"
diff --git a/Marlin/pins_GEN7_12.h b/Marlin/pins_GEN7_12.h
index 53edb32811..b0f178ff34 100644
--- a/Marlin/pins_GEN7_12.h
+++ b/Marlin/pins_GEN7_12.h
@@ -24,8 +24,35 @@
  * Gen7 v1.1, v1.2, v1.3 pin assignments
  */
 
+ /**
+ * Rev B    26 DEC 2016
+ *
+ * 1) added pointer to a current Arduino IDE extension
+ * 2) added support for M3, M4 & M5 spindle control commands
+ * 3) added case light pin definition
+ *
+ */
+
+/**
+ * A useable Arduino IDE extension (board manager) can be found at
+ * https://github.com/Lauszus/Sanguino
+ *
+ * This extension has been tested on Arduino 1.6.12 & 1.8.0
+ *
+ * Here's the JSON path:
+ * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json
+ *
+ * When installing select 1.0.2
+ *
+ * Installation instructions can be found at https://learn.sparkfun.com/pages/CustomBoardsArduino
+ * Just use the above JSON URL instead of Sparkfun's JSON.
+ *
+ * Once installed select the Sanguino board and then select the CPU.
+ *
+ */
+
 #if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) && !defined(__AVR_ATmega1284P__)
-  #error "Oops!  Make sure you have 'Gen7' selected from the 'Tools -> Boards' menu."
+  #error "Oops!  Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu."
 #endif
 
 #ifndef BOARD_NAME
@@ -39,10 +66,13 @@
 //
 // Limit Switches
 //
-#define X_STOP_PIN          7
-#define Y_STOP_PIN          5
+#define X_MIN_PIN           7
+#define Y_MIN_PIN           5
 #define Z_MIN_PIN           1
 #define Z_MAX_PIN           0
+#define Y_MAX_PIN           2
+#define X_MAX_PIN           6
+
 
 //
 // Z Probe (when not Z_MIN_PIN)
@@ -91,6 +121,12 @@
 //
 #define PS_ON_PIN          15
 
+#if GEN7_VERSION < 13
+  #define CASE_LIGHT_PIN   16     // MUST BE HARDWARE PWM
+#else     // Gen7 v1.3 removed the I2C connector & signals so need to get PWM off the PC power supply header
+  #define CASE_LIGHT_PIN   15     // MUST BE HARDWARE PWM
+#endif
+
 // All these generations of Gen7 supply thermistor power
 // via PS_ON, so ignore bad thermistor readings
 #define BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
@@ -101,3 +137,13 @@
 #define TX_ENABLE_PIN      12
 #define RX_ENABLE_PIN      13
 
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#define SPINDLE_LASER_ENABLE_PIN 10  // Pin should have a pullup/pulldown!
+#define SPINDLE_DIR_PIN          11
+#if GEN7_VERSION < 13
+  #define SPINDLE_LASER_PWM_PIN  16  // MUST BE HARDWARE PWM
+#else  // Gen7 v1.3 removed the I2C connector & signals so need to get PWM off the PC power supply header
+  #define SPINDLE_LASER_PWM_PIN  15  // MUST BE HARDWARE PWM
+#endif
diff --git a/Marlin/pins_GEN7_13.h b/Marlin/pins_GEN7_13.h
index 2365ae8be8..03ea131f46 100644
--- a/Marlin/pins_GEN7_13.h
+++ b/Marlin/pins_GEN7_13.h
@@ -24,6 +24,31 @@
  * Gen7 v1.3 pin assignments
  */
 
+ /**
+ * Rev B    26 DEC 2016
+ *
+ * added pointer to a current Arduino IDE extension
+ *
+ */
+
+/**
+ * A useable Arduino IDE extension (board manager) can be found at
+ * https://github.com/Lauszus/Sanguino
+ *
+ * This extension has been tested on Arduino 1.6.12 & 1.8.0
+ *
+ * Here's the JSON path:
+ * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json
+ *
+ * When installing select 1.0.2
+ *
+ * Installation instructions can be found at https://learn.sparkfun.com/pages/CustomBoardsArduino
+ * Just use the above JSON URL instead of Sparkfun's JSON.
+ *
+ * Once installed select the Sanguino board and then select the CPU.
+ *
+ */
+
 #define BOARD_NAME "Gen7 v1.3"
 
 #define GEN7_VERSION 13 // v1.3
diff --git a/Marlin/pins_GEN7_14.h b/Marlin/pins_GEN7_14.h
index d200137b48..9d4e16af33 100644
--- a/Marlin/pins_GEN7_14.h
+++ b/Marlin/pins_GEN7_14.h
@@ -24,8 +24,35 @@
  * Gen7 v1.4 pin assignments
  */
 
+/**
+ * Rev B    26 DEC 2016
+ *
+ * 1) added pointer to a current Arduino IDE extension
+ * 2) added support for M3, M4 & M5 spindle control commands
+ * 3) added case light pin definition
+ *
+ */
+
+/**
+ * A useable Arduino IDE extension (board manager) can be found at
+ * https://github.com/Lauszus/Sanguino
+ *
+ * This extension has been tested on Arduino 1.6.12 & 1.8.0
+ *
+ * Here's the JSON path:
+ * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json
+ *
+ * When installing select 1.0.2
+ *
+ * Installation instructions can be found at https://learn.sparkfun.com/pages/CustomBoardsArduino
+ * Just use the above JSON URL instead of Sparkfun's JSON.
+ *
+ * Once installed select the Sanguino board and then select the CPU.
+ *
+ */
+
 #if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) && !defined(__AVR_ATmega1284P__)
-  #error "Oops!  Make sure you have 'Gen7' selected from the 'Tools -> Boards' menu."
+  #error "Oops!  Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu."
 #endif
 
 #define BOARD_NAME "Gen7 v1.4"
@@ -67,17 +94,25 @@
 //
 // Heaters
 //
-#define HEATER_0_PIN 4
-#define HEATER_BED_PIN 3
+#define HEATER_0_PIN        4
+#define HEATER_BED_PIN      3
 
 //
 // Misc. Functions
 //
-#define PS_ON_PIN 15
+#define PS_ON_PIN          15
+#define CASE_LIGHT_PIN     15    // MUST BE HARDWARE PWM
 
 // A pin for debugging
-#define DEBUG_PIN 0
+#define DEBUG_PIN           0
 
 // RS485 pins
-#define TX_ENABLE_PIN 12
-#define RX_ENABLE_PIN 13
+#define TX_ENABLE_PIN      12
+#define RX_ENABLE_PIN      13
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#define SPINDLE_LASER_ENABLE_PIN 20  // Pin should have a pullup/pulldown!
+#define SPINDLE_LASER_PWM_PIN    16  // MUST BE HARDWARE PWM
+#define SPINDLE_DIR_PIN          21
diff --git a/Marlin/pins_GEN7_CUSTOM.h b/Marlin/pins_GEN7_CUSTOM.h
index 81809d61ae..9b83df9aee 100644
--- a/Marlin/pins_GEN7_CUSTOM.h
+++ b/Marlin/pins_GEN7_CUSTOM.h
@@ -27,8 +27,35 @@
  * Please review the pins and adjust them for your needs.
  */
 
+/**
+ * Rev B    26 DEC 2016
+ *
+ * 1) added pointer to a current Arduino IDE extension
+ * 2) added support for M3, M4 & M5 spindle control commands
+ * 3) added case light pin definition
+ *
+ */
+
+/**
+ * A useable Arduino IDE extension (board manager) can be found at
+ * https://github.com/Lauszus/Sanguino
+ *
+ * This extension has been tested on Arduino 1.6.12 & 1.8.0
+ *
+ * Here's the JSON path:
+ * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json
+ *
+ * When installing select 1.0.2
+ *
+ * Installation instructions can be found at https://learn.sparkfun.com/pages/CustomBoardsArduino
+ * Just use the above JSON URL instead of Sparkfun's JSON.
+ *
+ * Once installed select the Sanguino board and then select the CPU.
+ *
+ */
+
 #if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) && !defined(__AVR_ATmega1284P__)
-  #error "Oops!  Make sure you have 'Gen7' selected from the 'Tools -> Boards' menu."
+  #error "Oops!  Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu."
 #endif
 
 #define BOARD_NAME      "Gen7 Custom"
@@ -76,6 +103,7 @@
 //
 #define SDSS            31  // SCL pin of I2C header || CS Pin for SD Card support
 #define PS_ON_PIN       19
+#define CASE_LIGHT_PIN  15    // MUST BE HARDWARE PWM
 
 // A pin for debugging
 #define DEBUG_PIN       -1
@@ -101,3 +129,10 @@
 // RS485 pins
 //#define TX_ENABLE_PIN   12
 //#define RX_ENABLE_PIN   13
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#define SPINDLE_LASER_ENABLE_PIN  5  // Pin should have a pullup/pulldown!
+#define SPINDLE_LASER_PWM_PIN    16  // MUST BE HARDWARE PWM
+#define SPINDLE_DIR_PIN           6
diff --git a/Marlin/pins_K8400.h b/Marlin/pins_K8400.h
index 1ef8049c13..3e2cd4b212 100644
--- a/Marlin/pins_K8400.h
+++ b/Marlin/pins_K8400.h
@@ -66,3 +66,8 @@
 #undef PS_ON_PIN
 #undef KILL_PIN
 #undef SD_DETECT_PIN
+
+#if Z_STEP_PIN == 26
+  #undef Z_STEP_PIN
+  #define Z_STEP_PIN 32
+#endif
diff --git a/Marlin/pins_MEGACONTROLLER.h b/Marlin/pins_MEGACONTROLLER.h
index c81f3547b8..c4a10705ab 100644
--- a/Marlin/pins_MEGACONTROLLER.h
+++ b/Marlin/pins_MEGACONTROLLER.h
@@ -127,6 +127,7 @@
 //
 #define SDSS               53
 #define LED_PIN            13
+#define CASE_LIGHT_PIN      2
 
 //
 // LCD / Controller
@@ -152,3 +153,10 @@
 
   #define SD_DETECT_PIN    49
 #endif // MINIPANEL
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#define SPINDLE_LASER_PWM_PIN     6  // MUST BE HARDWARE PWM
+#define SPINDLE_LASER_ENABLE_PIN  7  // Pin should have a pullup!
+#define SPINDLE_DIR_PIN           8
diff --git a/Marlin/pins_MEGATRONICS.h b/Marlin/pins_MEGATRONICS.h
index 5b8d41f4f5..ba97fa2556 100644
--- a/Marlin/pins_MEGATRONICS.h
+++ b/Marlin/pins_MEGATRONICS.h
@@ -97,6 +97,7 @@
 #define SDSS               53
 #define LED_PIN            13
 #define PS_ON_PIN          12
+#define CASE_LIGHT_PIN      2
 
 //
 // LCD / Controller
@@ -120,3 +121,10 @@
   #define SD_DETECT_PIN   -1   // RAMPS doesn't use this
 
 #endif // ULTRA_LCD && NEWPANEL
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#define SPINDLE_LASER_PWM_PIN     3  // MUST BE HARDWARE PWM
+#define SPINDLE_LASER_ENABLE_PIN  4  // Pin should have a pullup!
+#define SPINDLE_DIR_PIN          11
diff --git a/Marlin/pins_MEGATRONICS_2.h b/Marlin/pins_MEGATRONICS_2.h
index be3ed4cf4a..0cbb769453 100644
--- a/Marlin/pins_MEGATRONICS_2.h
+++ b/Marlin/pins_MEGATRONICS_2.h
@@ -71,8 +71,8 @@
 #define E1_DIR_PIN         39
 #define E1_ENABLE_PIN      28
 
-#define E2_STEP_PIN        23
-#define E2_DIR_PIN         24
+#define E2_STEP_PIN        23 // ? schematic says 24
+#define E2_DIR_PIN         24 // ? schematic says 23
 #define E2_ENABLE_PIN      22
 
 //
@@ -112,6 +112,7 @@
 #define SDSS               53
 #define LED_PIN            13
 #define PS_ON_PIN          12
+#define CASE_LIGHT_PIN      2
 
 //
 // LCD / Controller
@@ -129,3 +130,10 @@
 #define BTN_EN1            61
 #define BTN_EN2            59
 #define BTN_ENC            43
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#define SPINDLE_LASER_PWM_PIN          3  // MUST BE HARDWARE PWM
+#define SPINDLE_LASER_ENABLE_PIN      16  // Pin should have a pullup!
+#define SPINDLE_DIR_PIN               11
diff --git a/Marlin/pins_MEGATRONICS_3.h b/Marlin/pins_MEGATRONICS_3.h
index 419f80ba59..aa6c40374f 100644
--- a/Marlin/pins_MEGATRONICS_3.h
+++ b/Marlin/pins_MEGATRONICS_3.h
@@ -28,6 +28,8 @@
   #error "Oops!  Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu."
 #endif
 
+#define MEGATRONICS_31
+
 #if ENABLED(MEGATRONICS_31)
   #define BOARD_NAME       "Megatronics v3.1"
 #else
@@ -129,6 +131,7 @@
 #define SDSS               53
 #define LED_PIN            13
 #define PS_ON_PIN          12
+#define CASE_LIGHT_PIN     45 // try the keypad connector
 
 //
 // LCD / Controller
@@ -164,3 +167,27 @@
   #endif
 
 #endif
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#if DISABLED(REPRAPWORLD_KEYPAD)     // try to use the keypad connector first
+  #define SPINDLE_LASER_PWM_PIN         44  // MUST BE HARDWARE PWM
+  #define SPINDLE_LASER_ENABLE_PIN      43  // Pin should have a pullup!
+  #define SPINDLE_DIR_PIN               42
+#elif EXTRUDERS <= 2
+  // try to hijack the last extruder so that we can get the PWM signal off the Y breakout
+  // move all the Y signals to the E2 extruder socket - makes dual Y steppers harder
+  #undef Y_ENABLE_PIN
+  #undef Y_STEP_PIN
+  #undef Y_DIR_PIN
+  #undef E2_STEP_PIN
+  #undef E2_ENABLE_PIN
+  #undef E2_DIR_PIN
+  #define Y_ENABLE_PIN          23
+  #define Y_STEP_PIN            22
+  #define Y_DIR_PIN             60
+  #define SPINDLE_LASER_PWM_PIN          4  // MUST BE HARDWARE PWM
+  #define SPINDLE_LASER_ENABLE_PIN      17  // Pin should have a pullup!
+  #define SPINDLE_DIR_PIN                5
+#endif
diff --git a/Marlin/pins_MIGHTYBOARD_REVE.h b/Marlin/pins_MIGHTYBOARD_REVE.h
index 933486177e..bd13a379d9 100644
--- a/Marlin/pins_MIGHTYBOARD_REVE.h
+++ b/Marlin/pins_MIGHTYBOARD_REVE.h
@@ -41,6 +41,17 @@
  *
  */
 
+/**
+ * Rev B  2 JAN 2017
+ *
+ *  Added pin definitions for:
+ *    M3, M4 & M5 spindle control commands
+ *    case light
+ *
+ *  Corrected pin assignment for MOSFET_B_PIN pin. Changed it from 9 to 11.  The port
+ *  number (B5) agrees with the schematic but B5 is assigned to logical pin 11.
+ */
+
 #if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__)
   #error "Oops! Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu."
 #endif
@@ -140,7 +151,7 @@
 // With no heated bed, an additional 24V fan is possible.
 //
 #define MOSFET_A_PIN     6 // H3
-#define MOSFET_B_PIN    11 // B5
+#define MOSFET_B_PIN    11 // B5 - Rev A of this file had this pin assigned to 9
 #define MOSFET_C_PIN    45 // L4
 #define MOSFET_D_PIN    44 // L5
 
@@ -193,11 +204,11 @@
 #define LED_PIN             13 // B7
 #define CUTOFF_RESET_PIN    16 // H1
 #define CUTOFF_TEST_PIN     17 // H0
+#define CASE_LIGHT_PIN      44 // L5   MUST BE HARDWARE PWM
 
 //
 // LCD / Controller
 //
-
 #ifdef REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
 
   #define LCD_PINS_RS           33 // C4, LCD-STROBE
@@ -246,7 +257,6 @@
 
 #endif
 
-
 //
 // SD Card
 //
@@ -255,7 +265,20 @@
 
 #define MAX_PIN             THERMO_SCK_PIN
 
-//check if all pins are defined in mega/pins_arduino.h
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#define SPINDLE_LASER_ENABLE_PIN 66  // K4   Pin should have a pullup!
+#define SPINDLE_LASER_PWM_PIN     8  // H5   MUST BE HARDWARE PWM
+#define SPINDLE_DIR_PIN          67  // K5
+
+
+
+
+
+
+
+// Check if all pins are defined in mega/pins_arduino.h
 #include <Arduino.h>
 static_assert(NUM_DIGITAL_PINS > MAX_PIN, "add missing pins to [arduino dir]/hardware/arduino/avr/variants/mega/pins_arduino.h based on fastio.h"
                                           "to digital_pin_to_port_PGM, digital_pin_to_bit_mask_PGM, digital_pin_to_timer_PGM, NUM_DIGITAL_PINS, see below");
diff --git a/Marlin/pins_MINIRAMBO.h b/Marlin/pins_MINIRAMBO.h
index 551926a5fa..de3c6b08ae 100644
--- a/Marlin/pins_MINIRAMBO.h
+++ b/Marlin/pins_MINIRAMBO.h
@@ -111,6 +111,7 @@
 //
 #define SDSS               53
 #define LED_PIN            13
+#define CASE_LIGHT_PIN      9
 
 //
 // LCD / Controller
@@ -140,3 +141,12 @@
 
   #endif // NEWPANEL
 #endif // ULTRA_LCD
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+
+// use P1 connector for spindle pins
+#define SPINDLE_LASER_PWM_PIN     9  // MUST BE HARDWARE PWM
+#define SPINDLE_LASER_ENABLE_PIN 18  // Pin should have a pullup!
+#define SPINDLE_DIR_PIN          19
diff --git a/Marlin/pins_MINITRONICS.h b/Marlin/pins_MINITRONICS.h
index d9a03c41fc..43f63ab231 100644
--- a/Marlin/pins_MINITRONICS.h
+++ b/Marlin/pins_MINITRONICS.h
@@ -24,6 +24,13 @@
  * Minitronics v1.0/1.1 pin assignments
  */
 
+/**
+ * Rev B   2 JAN 2017
+ *
+ *  Added pin definitions for M3, M4 & M5 spindle control commands
+ *
+ */
+
 #ifndef __AVR_ATmega1281__
   #error "Oops!  Make sure you have 'Minitronics' selected from the 'Tools -> Boards' menu."
 #endif
@@ -123,3 +130,19 @@
 
   #define SD_DETECT_PIN    -1 // Minitronics doesn't use this
 #endif
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#if ENABLED(SPINDLE_LASER_ENABLE)  // assumes we're only doing CNC work (no 3D printing)
+  #undef HEATER_BED_PIN
+  #undef TEMP_BED_PIN           // need to free up some pins but also need to
+  #undef TEMP_0_PIN             // re-assign them (to unused pins) because Marlin
+  #undef TEMP_1_PIN             // requires the presence of certain pins or else it
+  #define HEATER_BED_PIN      4  // won't compile
+  #define TEMP_BED_PIN       50
+  #define TEMP_0_PIN         51
+  #define SPINDLE_LASER_ENABLE_PIN      52 // using A6 because it already has a pull up on it
+  #define SPINDLE_LASER_PWM_PIN          3 // WARNING - LED & resistor pull up to +12/+24V stepper voltage
+  #define SPINDLE_DIR_PIN               53
+#endif
diff --git a/Marlin/pins_MKS_BASE.h b/Marlin/pins_MKS_BASE.h
index 12bf8b7491..dcf9b90f29 100644
--- a/Marlin/pins_MKS_BASE.h
+++ b/Marlin/pins_MKS_BASE.h
@@ -22,6 +22,8 @@
 
 /**
  * MKS BASE 1.0 – Arduino Mega2560 with RAMPS v1.4 pin assignments
+ *
+ * Rev B - Override pin definitions for CASE_LIGHT and M3/M4/M5 spindle control
  */
 
 #if HOTENDS > 2 || E_STEPPERS > 2
@@ -36,4 +38,13 @@
 // Power outputs EFBF or EFBE
 #define MOSFET_D_PIN 7
 
-#include "pins_RAMPS.h"
\ No newline at end of file
+#define CASE_LIGHT_PIN            2
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#define SPINDLE_LASER_PWM_PIN     2  // MUST BE HARDWARE PWM
+#define SPINDLE_LASER_ENABLE_PIN 15  // Pin should have a pullup!
+#define SPINDLE_DIR_PIN          19
+
+#include "pins_RAMPS.h"
diff --git a/Marlin/pins_OMCA.h b/Marlin/pins_OMCA.h
index 545c8646f2..8715efcd44 100644
--- a/Marlin/pins_OMCA.h
+++ b/Marlin/pins_OMCA.h
@@ -51,6 +51,31 @@
  * REF http://sanguino.cc/hardware
  */
 
+/**
+ * Rev B    26 DEC 2016
+ *
+ * added pointer to a current Arduino IDE extension
+ *
+ */
+
+/**
+ * A useable Arduino IDE extension (board manager) can be found at
+ * https://github.com/Lauszus/Sanguino
+ *
+ * This extension has been tested on Arduino 1.6.12 & 1.8.0
+ *
+ * Here's the JSON path:
+ * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json
+ *
+ * When installing select 1.0.2
+ *
+ * Installation instructions can be found at https://learn.sparkfun.com/pages/CustomBoardsArduino
+ * Just use the above JSON URL instead of Sparkfun's JSON.
+ *
+ * Once installed select the Sanguino board and then select the CPU.
+ *
+ */
+
 #if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__)
   #error "Oops!  Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu. (Final OMCA board)"
 #endif
diff --git a/Marlin/pins_OMCA_A.h b/Marlin/pins_OMCA_A.h
index d325a648d9..3686973c95 100644
--- a/Marlin/pins_OMCA_A.h
+++ b/Marlin/pins_OMCA_A.h
@@ -50,8 +50,33 @@
  *
  */
 
+/**
+ * Rev B    26 DEC 2016
+ *
+ * added pointer to a current Arduino IDE extension
+ *
+ */
+
+/**
+ * A useable Arduino IDE extension (board manager) can be found at
+ * https://github.com/Lauszus/Sanguino
+ *
+ * This extension has been tested on Arduino 1.6.12 & 1.8.0
+ *
+ * Here's the JSON path:
+ * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json
+ *
+ * When installing select 1.0.2
+ *
+ * Installation instructions can be found at https://learn.sparkfun.com/pages/CustomBoardsArduino
+ * Just use the above JSON URL instead of Sparkfun's JSON.
+ *
+ * Once installed select the Sanguino board and then select the CPU.
+ *
+ */
+
 #ifndef __AVR_ATmega644__
-  #error "Oops!  Make sure you have 'SanguinoA' selected from the 'Tools -> Boards' menu."
+  #error "Oops!  Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu."
 #endif
 
 #define BOARD_NAME         "Alpha OMCA"
diff --git a/Marlin/pins_RAMBO.h b/Marlin/pins_RAMBO.h
index e4df16677f..c99cd79233 100644
--- a/Marlin/pins_RAMBO.h
+++ b/Marlin/pins_RAMBO.h
@@ -137,6 +137,7 @@
 #define LED_PIN            13
 #define FILWIDTH_PIN        3   // Analog Input
 #define PS_ON_PIN           4
+#define CASE_LIGHT_PIN     46
 
 //
 // LCD / Controller
@@ -208,3 +209,10 @@
   #endif // !NEWPANEL
 
 #endif // ULTRA_LCD
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#define SPINDLE_LASER_PWM_PIN    45  // MUST BE HARDWARE PWM
+#define SPINDLE_LASER_ENABLE_PIN 31  // Pin should have a pullup!
+#define SPINDLE_DIR_PIN          32
diff --git a/Marlin/pins_RAMPS.h b/Marlin/pins_RAMPS.h
index 767e990857..9bd1a252c3 100644
--- a/Marlin/pins_RAMPS.h
+++ b/Marlin/pins_RAMPS.h
@@ -204,6 +204,16 @@
 
 #define PS_ON_PIN          12
 
+#if !PIN_EXISTS(CASE_LIGHT) && !defined(SPINDLE_LASER_ENABLE_PIN)
+  #undef CASE_LIGHT_PIN
+  #if !defined(NUM_SERVOS) || NUM_SERVOS == 0 // try to use servo connector first
+    #define CASE_LIGHT_PIN   6      // MUST BE HARDWARE PWM
+  #elif !(ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) \
+      && (ENABLED(PANEL_ONE) || ENABLED(VIKI2) || ENABLED(miniVIKI) || ENABLED(MINIPANEL) || ENABLED(REPRAPWORLD_KEYPAD)))  // try to use AUX 2
+    #define CASE_LIGHT_PIN   44     // MUST BE HARDWARE PWM
+  #endif
+#endif
+
 //
 // LCD / Controller
 //
@@ -361,3 +371,19 @@
   #endif // NEWPANEL
 
 #endif // ULTRA_LCD
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#if ENABLED(SPINDLE_LASER_ENABLE) && !PIN_EXISTS(SPINDLE_LASER_ENABLE_PIN)
+  #if !defined(NUM_SERVOS) || NUM_SERVOS == 0 // try to use servo connector first
+    #define SPINDLE_LASER_ENABLE_PIN  4  // Pin should have a pullup/pulldown!
+    #define SPINDLE_LASER_PWM_PIN     6  // MUST BE HARDWARE PWM
+    #define SPINDLE_DIR_PIN           5
+  #elif !(ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL) \
+      && (ENABLED(PANEL_ONE) || ENABLED(VIKI2) || ENABLED(miniVIKI) || ENABLED(MINIPANEL) || ENABLED(REPRAPWORLD_KEYPAD)))  // try to use AUX 2
+    #define SPINDLE_LASER_ENABLE_PIN 40  // Pin should have a pullup/pulldown!
+    #define SPINDLE_LASER_PWM_PIN    44  // MUST BE HARDWARE PWM
+    #define SPINDLE_DIR_PIN          65
+  #endif
+#endif
diff --git a/Marlin/pins_RAMPS_OLD.h b/Marlin/pins_RAMPS_OLD.h
index 29812bbdf4..870f2fbd15 100644
--- a/Marlin/pins_RAMPS_OLD.h
+++ b/Marlin/pins_RAMPS_OLD.h
@@ -101,3 +101,11 @@
 #define SDPOWER            48
 #define SDSS               53
 #define LED_PIN            13
+#define CASE_LIGHT_PIN     45     // MUST BE HARDWARE PWM
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#define SPINDLE_LASER_ENABLE_PIN 41  // Pin should have a pullup/pulldown!
+#define SPINDLE_LASER_PWM_PIN    45  // MUST BE HARDWARE PWM
+#define SPINDLE_DIR_PIN          43
diff --git a/Marlin/pins_RIGIDBOARD.h b/Marlin/pins_RIGIDBOARD.h
index 0e48caf73b..5bd06e40eb 100644
--- a/Marlin/pins_RIGIDBOARD.h
+++ b/Marlin/pins_RIGIDBOARD.h
@@ -82,16 +82,16 @@
 //
 // Heaters / Fans
 //
-#undef  HEATER_BED_PIN
+#undef HEATER_BED_PIN
 #define HEATER_BED_PIN     10
 
-#undef  FAN_PIN
+#undef FAN_PIN
 #define FAN_PIN             8 // Same as RAMPS_13_EEF
 
 //
 // Misc. Functions
 //
-#undef  PS_ON_PIN
+#undef PS_ON_PIN
 #define PS_ON_PIN          -1
 
 //
@@ -110,24 +110,24 @@
   #define BTN_RT           32
 
   // 'R' button
-  #undef  BTN_ENC
+  #undef BTN_ENC
   #define BTN_ENC 31
 
   // Disable encoder
-  #undef  BTN_EN1
+  #undef BTN_EN1
   #define BTN_EN1 -1
-  #undef  BTN_EN2
+  #undef BTN_EN2
   #define BTN_EN2 -1
 
-  #undef  SD_DETECT_PIN
+  #undef SD_DETECT_PIN
   #define SD_DETECT_PIN 22
 
 #elif ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER)
 
-  #undef  SD_DETECT_PIN
+  #undef SD_DETECT_PIN
   #define SD_DETECT_PIN 22
 
-  #undef  KILL_PIN
+  #undef KILL_PIN
   #define KILL_PIN 32
 
 #endif
diff --git a/Marlin/pins_RUMBA.h b/Marlin/pins_RUMBA.h
index 376197c556..23a9c3ad10 100644
--- a/Marlin/pins_RUMBA.h
+++ b/Marlin/pins_RUMBA.h
@@ -100,7 +100,7 @@
 #endif
 
 #if TEMP_SENSOR_2 == -1
-  #define TEMP_2_PIN        7   // Analog Input (connector *K3* on RUMBA thermocouple ADD ON is used <-- this can't be used when TEMP_SENSOR_BED is defined as thermocouple)
+  #define TEMP_2_PIN        7   // Analog Input (connector *K3* on RUMBA thermocouple ADD ON is used <-- this can not be used when TEMP_SENSOR_BED is defined as thermocouple)
 #else
   #define TEMP_2_PIN       13   // Analog Input (default connector for thermistor *T2* on rumba board is used)
 #endif
@@ -109,7 +109,7 @@
 //#define TEMP_X_PIN         12   // Analog Input (default connector for thermistor *T3* on rumba board is used)
 
 #if TEMP_SENSOR_BED == -1
-  #define TEMP_BED_PIN      7   // Analog Input (connector *K3* on RUMBA thermocouple ADD ON is used <-- this can't be used when TEMP_SENSOR_2 is defined as thermocouple)
+  #define TEMP_BED_PIN      7   // Analog Input (connector *K3* on RUMBA thermocouple ADD ON is used <-- this can not be used when TEMP_SENSOR_2 is defined as thermocouple)
 #else
   #define TEMP_BED_PIN     11   // Analog Input (default connector for thermistor *THB* on rumba board is used)
 #endif
@@ -133,6 +133,7 @@
 #define LED_PIN            13
 #define PS_ON_PIN          45
 #define KILL_PIN           46
+#define CASE_LIGHT_PIN     45
 
 //
 // LCD / Controller
@@ -148,3 +149,10 @@
 #define BTN_EN1            11
 #define BTN_EN2            12
 #define BTN_ENC            43
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#define SPINDLE_LASER_PWM_PIN     4  // MUST BE HARDWARE PWM
+#define SPINDLE_LASER_ENABLE_PIN 14  // Pin should have a pullup!
+#define SPINDLE_DIR_PIN          15
diff --git a/Marlin/pins_SANGUINOLOLU_11.h b/Marlin/pins_SANGUINOLOLU_11.h
index 62d92b61e8..6bac9d7a8a 100644
--- a/Marlin/pins_SANGUINOLOLU_11.h
+++ b/Marlin/pins_SANGUINOLOLU_11.h
@@ -24,6 +24,33 @@
  * Sanguinololu board pin assignments
  */
 
+/**
+ * Rev B    26 DEC 2016
+ *
+ * 1) added pointer to a current Arduino IDE extension
+ * 2) added support for M3, M4 & M5 spindle control commands
+ * 3) added case light pin definition
+ *
+ */
+
+/**
+ * A useable Arduino IDE extension (board manager) can be found at
+ * https://github.com/Lauszus/Sanguino
+ *
+ * This extension has been tested on Arduino 1.6.12 & 1.8.0
+ *
+ * Here's the JSON path:
+ * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json
+ *
+ * When installing select 1.0.2
+ *
+ * Installation instructions can be found at https://learn.sparkfun.com/pages/CustomBoardsArduino
+ * Just use the above JSON URL instead of Sparkfun's JSON.
+ *
+ * Once installed select the Sanguino board and then select the CPU.
+ *
+ */
+
 #if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega1284P__)
   #error "Oops!  Make sure you have 'Sanguino' selected from the 'Tools -> Boards' menu."
 #endif
@@ -96,19 +123,26 @@
 //
 // Misc. Functions
 //
+
 /**
- * On some broken versions of the Sanguino libraries the pin definitions are wrong,
- * which then needs SDSS as pin 24. But you should upgrade your Sanguino libraries! See #368.
+ * In some versions of the Sanguino libraries the pin
+ * definitions are wrong, with SDSS = 24 and LED_PIN = 28 (Melzi).
+ * If you encounter issues with these pins, upgrade your
+ * Sanguino libraries! See #368.
  */
 //#define SDSS               24
 #define SDSS               31
 
 #if IS_MELZI
-  #define LED_PIN          27 // On some broken versions of the Sanguino libraries the pin definitions are wrong, so LED_PIN needs to be 28. But you should upgrade your Sanguino libraries! See #368.
+  #define LED_PIN           27
 #elif MB(STB_11)
   #define LCD_BACKLIGHT_PIN 17 // LCD backlight LED
 #endif
 
+#if DISABLED(SPINDLE_LASER_ENABLE) && ENABLED(SANGUINOLOLU_V_1_2) && !(ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL))  // try to use IO Header
+  #define CASE_LIGHT_PIN         4   // MUST BE HARDWARE PWM  - see if IO Header is available
+#endif
+
 //
 // LCD / Controller
 //
@@ -181,14 +215,62 @@
     #else
       #define BTN_ENC           30
     #endif
-  #elif ENABLED(OLED_PANEL_TINYBOY2)
-    #define BTN_ENC             28
-    #define LCD_SDSS            -1
-  #else  // !Panelolu2, !TinyBoy2
+  #else  // !Panelolu2
     #define BTN_ENC             16
     #define LCD_SDSS            28 // Smart Controller SD card reader rather than the Melzi
-  #endif // !Panelolu2, !TinyBoy2
+  #endif // !Panelolu2
 
   #define SD_DETECT_PIN         -1
 
 #endif // ULTRA_LCD && NEWPANEL
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#if ENABLED(SPINDLE_LASER_ENABLE)
+  #if !MB(AZTEEG_X1) && ENABLED(SANGUINOLOLU_V_1_2) && !(ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL))  // try to use IO Header
+
+    #define SPINDLE_LASER_ENABLE_PIN 10  // Pin should have a pullup/pulldown!
+    #define SPINDLE_LASER_PWM_PIN     4  // MUST BE HARDWARE PWM
+    #define SPINDLE_DIR_PIN          11
+
+  #elif !MB(MELZI)  // use X stepper motor socket
+
+    /**
+     *  To control the spindle speed and have an LCD you must sacrifice
+     *  the Extruder and pull some signals off the X stepper driver socket.
+     *
+     *  The following assumes:
+     *   - The X stepper driver socket is empty
+     *   - The extruder driver socket has a driver board plugged into it
+     *   - The X stepper wires are attached the the extruder connector
+     */
+
+    /**
+     *  Where to get the spindle signals
+     *
+     *      spindle signal          socket name       socket name
+     *                                         -------
+     *                               /ENABLE  O|     |O  VMOT
+     *                                   MS1  O|     |O  GND
+     *                                   MS2  O|     |O  2B
+     *                                   MS3  O|     |O  2A
+     *                                /RESET  O|     |O  1A
+     *                                /SLEEP  O|     |O  1B
+     *  SPINDLE_LASER_PWM_PIN  STEP  O|     |O  VDD
+     *  SPINDLE_LASER_ENABLE_PIN         DIR  O|     |O  GND
+     *                                         -------
+     *
+     *  Note: Socket names vary from vendor to vendor.
+     */
+    #undef X_DIR_PIN
+    #undef X_ENABLE_PIN
+    #undef X_STEP_PIN
+    #define X_DIR_PIN                 0
+    #define X_ENABLE_PIN             14
+    #define X_STEP_PIN                1
+    #define SPINDLE_LASER_PWM_PIN    15  // MUST BE HARDWARE PWM
+    #define SPINDLE_LASER_ENABLE_PIN 21  // Pin should have a pullup!
+    #define SPINDLE_DIR_PIN          -1  // No pin available on the socket for the direction pin
+  #endif
+#endif // SPINDLE_LASER_ENABLE
diff --git a/Marlin/pins_SAV_MKI.h b/Marlin/pins_SAV_MKI.h
index 019139d1e2..2048af9251 100644
--- a/Marlin/pins_SAV_MKI.h
+++ b/Marlin/pins_SAV_MKI.h
@@ -115,7 +115,6 @@
 #define EXT_AUX_A4                 4 // Analog
 #define EXT_AUX_A4_IO             44 // Digital IO, 42 (teensy), 44 (marlin)
 
-
 //
 // LCD / Controller
 //
@@ -134,10 +133,23 @@
 #endif // SAV_3DLCD
 
 #if ENABLED(SAV_3DLCD) || ENABLED(SAV_3DGLCD)
+
   #define BTN_EN1            EXT_AUX_A1_IO
   #define BTN_EN2            EXT_AUX_A0_IO
   #define BTN_ENC            EXT_AUX_PWM_D24
 
   #define KILL_PIN           EXT_AUX_A2_IO
   #define HOME_PIN           EXT_AUX_A4_IO
-#endif // SAV_3DLCD || SAV_3DGLCD
+
+#else // Try to use the expansion header for spindle control
+
+  //
+  // M3/M4/M5 - Spindle/Laser Control
+  //
+  #define SPINDLE_LASER_PWM_PIN    24  // 12 AT90USB… pin #
+  #define SPINDLE_LASER_ENABLE_PIN 39  // Pin should have a pullup!   41 AT90USB… pin #
+  #define SPINDLE_DIR_PIN          40  // 42 AT90USB… pin #
+
+  #define CASE_LIGHT_PIN            0  // 24 AT90USB… pin #
+
+#endif
diff --git a/Marlin/pins_SETHI.h b/Marlin/pins_SETHI.h
index 12521f40a1..a05bb9eb27 100644
--- a/Marlin/pins_SETHI.h
+++ b/Marlin/pins_SETHI.h
@@ -24,6 +24,31 @@
  * Sethi 3D_1 pin assignments - www.sethi3d.com.br
  */
 
+/**
+ * Rev B    26 DEC 2016
+ *
+ * added pointer to a current Arduino IDE extension
+ *    this assumes that this board uses the Sanguino pin map
+ */
+
+/**
+ * A useable Arduino IDE extension (board manager) can be found at
+ * https://github.com/Lauszus/Sanguino
+ *
+ * This extension has been tested on Arduino 1.6.12 & 1.8.0
+ *
+ * Here's the JSON path:
+ * https://raw.githubusercontent.com/Lauszus/Sanguino/master/package_lauszus_sanguino_index.json
+ *
+ * When installing select 1.0.2
+ *
+ * Installation instructions can be found at https://learn.sparkfun.com/pages/CustomBoardsArduino
+ * Just use the above JSON URL instead of Sparkfun's JSON.
+ *
+ * Once installed select the Sanguino board and then select the CPU.
+ *
+ */
+
 #if !defined(__AVR_ATmega644P__) && !defined(__AVR_ATmega644__) && !defined(__AVR_ATmega1284P__)
   #error "Oops!  Make sure you have 'Sethi 3D' selected from the 'Tools -> Boards' menu."
 #endif
diff --git a/Marlin/pins_TEENSY2.h b/Marlin/pins_TEENSY2.h
index b7cf484be3..971de27e8b 100644
--- a/Marlin/pins_TEENSY2.h
+++ b/Marlin/pins_TEENSY2.h
@@ -124,6 +124,7 @@
 #define SDSS               20 // 8
 #define LED_PIN             6
 #define PS_ON_PIN          27
+#define CASE_LIGHT_PIN      1 // MUST BE HARDWARE PWM
 
 //
 // LCD / Controller
@@ -139,3 +140,10 @@
   #define BTN_EN2            39
   #define BTN_ENC            40
 #endif
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#define SPINDLE_LASER_ENABLE_PIN  5 // Pin should have a pullup!
+#define SPINDLE_LASER_PWM_PIN     0 // MUST BE HARDWARE PWM
+#define SPINDLE_DIR_PIN           7
diff --git a/Marlin/pins_TEENSYLU.h b/Marlin/pins_TEENSYLU.h
index b0fc8aec5f..d845e312e3 100644
--- a/Marlin/pins_TEENSYLU.h
+++ b/Marlin/pins_TEENSYLU.h
@@ -12,27 +12,82 @@
  *
  * 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
+ * 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/>.
+ * along with this program.   If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 /**
- * Teensylu 0.7 pin assignments (AT90USB1286)
- * Requires the Teensyduino software with Teensy++ 2.0 selected in Arduino IDE!
- * http://www.pjrc.com/teensy/teensyduino.html
- * See http://reprap.org/wiki/Printrboard for more info
+ *  rev B    30 DEC 2016
+ *
+ *  The original version of this file did NOT result in a useful program because:
+ *   1. The pin numbers assumed that the "#define AT90USBxx_TEENSYPP_ASSIGNMENTS" line
+ *      in FASTIO.h was commented out. There wasn't an Arduino IDE 1.6.x extension/package
+ *      that supported this pin map so the latest Marlin wouldn't compile.
+ *   2. The silkscreen for the four end stops don't agree with the schematic. Activating
+ *      the X endstop would tell the software that the Y endstop just went active.
+ *   3. The thermistor inputs also had heater names assigned to them. The result was
+ *      thermistor inputs that were set to digital outputs.
+ *
+ *  Rev B corrects the above problems by:
+ *   1. The "Marlin_AT90USB" extension/package was developed.  This extension enables the
+ *      latest Marlin software to compile using Arduino IDE 1.6.x and 1.80.
+ *   2. The endstop pin numbers in this file were changed to match the silkscreen.  This
+ *      makes it a little confusing when trying to correlate the schematic with the pin
+ *      numbers used in this file.
+ *   3. The offending heater names were deleted.
+ *
+ *  To create a useable image for Teensylu do the following:
+ *   a) Install the Marlin_AT90USB extension with either of the following methods:
+ *        Automatic - paste this URL into preferences and then use Boards manager
+ *            https://rawgit.com/Bob-the-Kuhn/Marlin_AT90USB/master/package_MARLIN_AT90USB_index.json
+ *        Manual:
+ *           1. Copy the following URL into Go to "https://github.com/Bob-the-Kuhn/Marlin_AT90USB",
+ *              click on the "Clone or Download" button and then click on "Download ZIP" button.
+ *           2. Unzip the file, find the "Marlin_AT90USB" directory and then copy it to the
+ *              hardware directory in Arduino.  The Arduino hardware directory will probably be
+ *              located in a path similar to this: C:\Program Files (x86)\Arduino\hardware
+ *   b) Connect the USBtinyISP to the board.
+ *   c) In the Arduino IDE select the "AT90USB1286_STANDARD" board in the of the "Marlin_AT90USB"
+ *      section and select the "USBtinyISP" programmer.
+ *   d) In the Arduino IDE click on "burn bootloader".  Don't worry about the "verify
+ *      failed at 1F000" error message.
+ *   e) The USBtinyISP programmer is no longer needed.  Remove it.
+ *   f) In FASTIO.h comment out the "#define AT90USBxx_TEENSYPP_ASSIGNMENTS" line.
+ *   g) To upload a sketch do the following:
+ *       1. remove the jumper
+ *       2. press reset
+ *       3. click on the "upload" button in the Arduino IDE
+ *       4. wait until the upload finishes (less than a minute)
+ *       5. put the jumper back on
+ *       6. press the reset button
+ *
+ *
+ *  NOTE - the "Marlin_AT90USB" pin maps make PWM0A available rather than the usual PWM1C.
+ *         These PWMs share the same physical pin. Marlin uses TIMER1 to generate
+ *         interrupts and sets it up such that PWM1A, PWM1B & PWM1C can not be used.
  */
 
-#ifndef __AVR_AT90USB1286__
-  #error "Oops!  Make sure you have 'Teensy++ 2.0' selected from the 'Tools -> Boards' menu."
+ /**
+  *  SILKSCREEN ERROR
+  *
+  *  The silkscreen for the endstops do NOT match the schematic.  The silkscreen SHOULD
+  *  read (from left to right) X-STOP, Y-STOP, Z-STOP & E-STOP.  The silkscreen actually
+  *  reads                     E-STOP, X-STOP, Y-STOP & Z-STOP.
+  *
+  *  The pin assignments in this file match the silkscreen.
+  */
+
+
+#if !defined(__AVR_AT90USB1286__) && !defined(__AVR_AT90USB1286P__)
+  #error "Oops!  Make sure you have 'AT90USB1286_STANDARD' selected from the 'Tools -> Boards' menu."
 #endif
 
-#if ENABLED(AT90USBxx_TEENSYPP_ASSIGNMENTS)  // use Teensyduino Teensy++2.0 pin assignments instead of Marlin traditional.
-  #error "These Teensylu assignments depend on traditional Marlin assignments, not AT90USBxx_TEENSYPP_ASSIGNMENTS in fastio.h"
+#if ENABLED(AT90USBxx_TEENSYPP_ASSIGNMENTS)
+  #error "please disable (comment out) the AT90USBxx_TEENSYPP_ASSIGNMENTS flag in FASTIO.h "
 #endif
 
 #define BOARD_NAME         "Teensylu"
@@ -40,74 +95,84 @@
 #define USBCON 1286  // Disable MarlinSerial etc.
 #define LARGE_FLASH        true
 
+
 //
-// Limit Switches
+// Limit Switche definitions that match the SCHEMATIC
 //
-#define X_STOP_PIN         13
-#define Y_STOP_PIN         14
-#define Z_STOP_PIN         15
+//#define X_STOP_PIN              13
+//#define Y_STOP_PIN              14
+//#define Z_STOP_PIN              15
+//#define E_STOP_PIN              36
+
+
+//
+// Limit Switch definitions that match the SILKSCREEN
+//
+#define X_STOP_PIN              14
+#define Y_STOP_PIN              15
+#define Z_STOP_PIN              36
+//#define E_STOP_PIN              13
 
 //
 // Steppers
 //
-#define X_STEP_PIN          0
-#define X_DIR_PIN           1
-#define X_ENABLE_PIN       39
+#define X_STEP_PIN               0
+#define X_DIR_PIN                1
+#define X_ENABLE_PIN            39
 
-#define Y_STEP_PIN          2
-#define Y_DIR_PIN           3
-#define Y_ENABLE_PIN       38
+#define Y_STEP_PIN               2
+#define Y_DIR_PIN                3
+#define Y_ENABLE_PIN            38
 
-#define Z_STEP_PIN          4
-#define Z_DIR_PIN           5
-#define Z_ENABLE_PIN       23
+#define Z_STEP_PIN               4
+#define Z_DIR_PIN                5
+#define Z_ENABLE_PIN            23
+
+#define E0_STEP_PIN              6
+#define E0_DIR_PIN               7
+#define E0_ENABLE_PIN           19
 
-#define E0_STEP_PIN         6
-#define E0_DIR_PIN          7
-#define E0_ENABLE_PIN      19
 
-//
 // Temperature Sensors
-//
-#define TEMP_0_PIN          7   // Analog Input (Extruder)
-#define TEMP_BED_PIN        6   // Analog Input (Bed)
+
+#define TEMP_0_PIN               7  // Analog Input (Extruder)
+#define TEMP_BED_PIN             6  // Analog Input (Bed)
 
 //
 // Heaters / Fans
 //
-#define HEATER_0_PIN       21  // Extruder
-#define HEATER_1_PIN       46
-#define HEATER_2_PIN       47
-#define HEATER_BED_PIN     20
+#define HEATER_0_PIN            21  // Extruder
+#define HEATER_BED_PIN          20
 
-// If soft or fast PWM is off then use Teensyduino pin numbering, Marlin
-// fastio pin numbering otherwise
-#if ENABLED(FAN_SOFT_PWM) || ENABLED(FAST_PWM_FAN)
-  #define FAN_PIN          22
-#else
-  #define FAN_PIN          16
-#endif
+#define FAN_PIN                 22
 
 //
 // Misc. Functions
 //
-#define SDSS                8
+#define SDSS                     8
+#define CASE_LIGHT_PIN          24
 
 //
 // LCD / Controller
 //
 #if ENABLED(ULTRA_LCD) && ENABLED(NEWPANEL)
 
-  #define BEEPER_PIN       -1
+  #define BEEPER_PIN            -1
 
   #if ENABLED(LCD_I2C_PANELOLU2)
-    #define BTN_EN1        27  // RX1 - fastio.h pin mapping 27
-    #define BTN_EN2        26  // TX1 - fastio.h pin mapping 26
-    #define BTN_ENC        43  // A3  - fastio.h pin mapping 43
-    #define SDSS           40  // use SD card on Panelolu2 (Teensyduino pin mapping)
+    #define BTN_EN1             27
+    #define BTN_EN2             26
+    #define BTN_ENC             43
+    #define SDSS                40  // use SD card on Panelolu2
   #endif // LCD_I2C_PANELOLU2
 
-  #define SD_DETECT_PIN    -1
+  #define SD_DETECT_PIN         -1
 
 #endif // ULTRA_LCD && NEWPANEL
 
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#define SPINDLE_LASER_PWM_PIN    12  // MUST BE HARDWARE PWM
+#define SPINDLE_LASER_ENABLE_PIN 41  // Pin should have a pullup!
+#define SPINDLE_DIR_PIN          42
diff --git a/Marlin/pins_ULTIMAIN_2.h b/Marlin/pins_ULTIMAIN_2.h
index 731f6f88fe..d4b99fafc7 100644
--- a/Marlin/pins_ULTIMAIN_2.h
+++ b/Marlin/pins_ULTIMAIN_2.h
@@ -24,6 +24,14 @@
  * Ultiboard v2.0 pin assignments
  */
 
+/**
+ * Rev B   2 JAN 2017
+ *
+ *  Added pin definitions for:
+ *    M3, M4 & M5 spindle control commands
+ *    case light
+ */
+
 #ifndef __AVR_ATmega2560__
   #error "Oops!  Make sure you have 'Arduino Mega 2560' selected from the 'Tools -> Boards' menu."
 #endif
@@ -110,3 +118,16 @@
 #define BTN_EN1            40
 #define BTN_EN2            41
 #define BTN_ENC            19
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#if ENABLED(SPINDLE_LASER_ENABLE)   // use the LED_PIN for spindle speed control or case light
+  #undef LED_PIN
+  #define SPINDLE_DIR_PIN          16
+  #define SPINDLE_LASER_ENABLE_PIN 17  // Pin should have a pullup!
+  #define SPINDLE_LASER_PWM_PIN     8  // MUST BE HARDWARE PWM
+#else
+  #undef LED_PIN
+  #define CASE_LIGHT_PIN            8
+#endif
diff --git a/Marlin/pins_ULTIMAKER.h b/Marlin/pins_ULTIMAKER.h
index 4b4b31ad8c..cb11768071 100644
--- a/Marlin/pins_ULTIMAKER.h
+++ b/Marlin/pins_ULTIMAKER.h
@@ -24,6 +24,14 @@
  * Ultimaker pin assignments
  */
 
+/**
+ * Rev B   2 JAN 2017
+ *
+ *  Added pin definitions for:
+ *    M3, M4 & M5 spindle control commands
+ *    case light
+ */
+
 #if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__)
   #error "Oops!  Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu."
 #endif
@@ -102,6 +110,7 @@
 #define LED_PIN            13
 #define PS_ON_PIN          12
 #define SUICIDE_PIN        54  // PIN that has to be turned on right after start, to keep power flowing.
+#define CASE_LIGHT_PIN      8
 
 //
 // LCD / Controller
@@ -146,3 +155,10 @@
   #endif // !NEWPANEL
 
 #endif // ULTRA_LCD
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#define SPINDLE_LASER_PWM_PIN     9  // MUST BE HARDWARE PWM
+#define SPINDLE_LASER_ENABLE_PIN 10  // Pin should have a pullup!
+#define SPINDLE_DIR_PIN          11  // use the EXP3 PWM header
diff --git a/Marlin/pins_ULTIMAKER_OLD.h b/Marlin/pins_ULTIMAKER_OLD.h
index b42ba69585..5dafda2d39 100644
--- a/Marlin/pins_ULTIMAKER_OLD.h
+++ b/Marlin/pins_ULTIMAKER_OLD.h
@@ -24,6 +24,42 @@
  * Ultimaker pin assignments (Old electronics)
  */
 
+ /**
+ * Rev B   3 JAN 2017
+ *
+ * Details on pin definitions for M3, M4 & M5 spindle control commands and for
+ * the CASE_LIGHT_PIN are at the end of this file.
+ *
+ * This started out as an attempt to add pin definitions for M3, M4 & M5 spindle
+ * control commands but quickly turned into a head scratcher as the sources for
+ * the revisions provided inconsistent information.
+ *
+ * As best I can determine:
+ *   1.5.3 boards should use the pins_ULTIMAKER.h file which means the BOARD_NAME
+ *      define in this file should say 1.5.3 rather than 1.5.4
+ *   This file is meant for 1.1 - 1.3 boards.
+ *   The endstops for the 1.0 boards use different definitions than on the 1.1 - 1.3
+ *      boards.
+ *
+ * I've added sections that have the 1.0 and 1.5.3 + endstop definitions so you can
+ * easily switch if needed.  I've also copied over the 1.5.3 + LCD definitions.
+ *
+ * To be 100% sure of the board you have:
+ *   1. In Configuration_adv.h enable "PINS_DEBUGGING"
+ *   2. Compile & uploade
+ *   3. Enter the command "M43 W1 I1".  This command will report that pin nmumber and
+ *      name of any pin that changes state.
+ *   4. Using a 1k (approximately) resistor pull the endstops and some of the LCD pins
+ *      to ground and see what is reported.
+ *   5. If the reported pin doesn't match the file then try a different board revision
+ *      and repeat steps 2 - 5
+ */
+
+#define board_rev_1_1_TO_1_3
+//#define board_rev_1_0
+//#define board_rev_1_5
+
+
 #if !defined(__AVR_ATmega1280__) && !defined(__AVR_ATmega2560__)
   #error "Oops!  Make sure you have 'Arduino Mega' selected from the 'Tools -> Boards' menu."
 #endif
@@ -37,18 +73,38 @@
 //
 // Limit Switches
 //
-#define X_MIN_PIN          15
-#define X_MAX_PIN          14
-#define Y_MIN_PIN          17
-#define Y_MAX_PIN          16
-#define Z_MIN_PIN          19
-#define Z_MAX_PIN          18
+#if ENABLED(board_rev_1_1_TO_1_3)
+  #define X_MIN_PIN          15  // SW1
+  #define X_MAX_PIN          14  // SW2
+  #define Y_MIN_PIN          17  // SW3
+  #define Y_MAX_PIN          16  // SW4
+  #define Z_MIN_PIN          19  // SW5
+  #define Z_MAX_PIN          18  // SW6
+#endif
+
+#if ENABLED(board_rev_1_0)
+  #define X_MIN_PIN          13  // SW1
+  #define X_MAX_PIN          12  // SW2
+  #define Y_MIN_PIN          11  // SW3
+  #define Y_MAX_PIN          10  // SW4
+  #define Z_MIN_PIN           9  // SW5
+  #define Z_MAX_PIN           8  // SW6
+#endif
+
+#if ENABLED(board_rev_1_5)
+  #define X_MIN_PIN          22
+  #define X_MAX_PIN          24
+  #define Y_MIN_PIN          26
+  #define Y_MAX_PIN          28
+  #define Z_MIN_PIN          30
+  #define Z_MAX_PIN          32
+#endif
 
 //
 // Z Probe (when not Z_MIN_PIN)
 //
 #ifndef Z_MIN_PROBE_PIN
-  #define Z_MIN_PROBE_PIN  18
+  #define Z_MIN_PROBE_PIN  Z_MAX_PIN
 #endif
 
 //
@@ -70,9 +126,9 @@
 #define E0_DIR_PIN         45
 #define E0_ENABLE_PIN      41
 
-#define E1_STEP_PIN        -1
-#define E1_DIR_PIN         -1
-#define E1_ENABLE_PIN      -1
+#define E1_STEP_PIN        -1  // 49
+#define E1_DIR_PIN         -1  // 47
+#define E1_ENABLE_PIN      -1  // 48
 
 //
 // Temperature Sensors
@@ -84,14 +140,144 @@
 // Heaters / Fans
 //
 #define HEATER_0_PIN        2
-#define HEATER_1_PIN        1
+//#define HEATER_1_PIN        3 // used for case light   Rev A said "1"
+#define HEATER_BED_PIN      4
 
 //
 // LCD / Controller
 //
-#define LCD_PINS_RS        24
-#define LCD_PINS_ENABLE    22
-#define LCD_PINS_D4        36
-#define LCD_PINS_D5        34
-#define LCD_PINS_D6        32
-#define LCD_PINS_D7        30
+#if ENABLED(board_rev_1_0) || ENABLED(board_rev_1_1_TO_1_3)
+  #define LCD_PINS_RS        24
+  #define LCD_PINS_ENABLE    22
+  #define LCD_PINS_D4        36
+  #define LCD_PINS_D5        34
+  #define LCD_PINS_D6        32
+  #define LCD_PINS_D7        30
+#elif ENABLED(board_rev_1_5) && ENABLED(ULTRA_LCD)
+
+  #define BEEPER_PIN 18
+
+  #if ENABLED(NEWPANEL)
+
+    #define LCD_PINS_RS 20
+    #define LCD_PINS_ENABLE 17
+    #define LCD_PINS_D4 16
+    #define LCD_PINS_D5 21
+    #define LCD_PINS_D6 5
+    #define LCD_PINS_D7 6
+
+    // buttons are directly attached
+    #define BTN_EN1 40
+    #define BTN_EN2 42
+    #define BTN_ENC 19
+
+    #define SD_DETECT_PIN 38
+
+  #else // !NEWPANEL - Old style panel with shift register
+
+    // buttons are attached to a shift register
+    #define SHIFT_CLK 38
+    #define SHIFT_LD 42
+    #define SHIFT_OUT 40
+    #define SHIFT_EN 17
+
+    #define LCD_PINS_RS 16
+    #define LCD_PINS_ENABLE 5
+    #define LCD_PINS_D4 6
+    #define LCD_PINS_D5 21
+    #define LCD_PINS_D6 20
+    #define LCD_PINS_D7 19
+
+    #define SD_DETECT_PIN -1
+
+  #endif // !NEWPANEL
+
+#endif // ULTRA_LCD
+
+//
+// case light  - see spindle section for more info on available hardware PWMs
+//
+#if !PIN_EXISTS(CASE_LIGHT) && ENABLED(board_rev_1_5)
+  #define CASE_LIGHT_PIN        7  // use PWM -  MUST BE HARDWARE PWM
+#endif
+
+//
+// M3/M4/M5 - Spindle/Laser Control
+//
+#if ENABLED(SPINDLE_LASER_ENABLE)
+
+  #if ENABLED(board_rev_1_0)       // use the last three SW positions
+
+    #undef Z_MIN_PROBE_PIN
+    #undef X_MIN_PIN              // SW1
+    #undef X_MAX_PIN              // SW2
+    #undef Y_MIN_PIN              // SW3
+    #undef Y_MAX_PIN              // SW4
+    #undef Z_MIN_PIN              // SW5
+    #undef Z_MAX_PIN              // SW6
+
+    #define X_STOP_PIN         13  // SW1  (didn't change) - also has a useable hardware PWM
+    #define Y_STOP_PIN         12  // SW2
+    #define Z_STOP_PIN         11  // SW3
+
+    #define SPINDLE_DIR_PIN          10  // SW4
+    #define SPINDLE_LASER_PWM_PIN     9  // SW5  MUST BE HARDWARE PWM
+    #define SPINDLE_LASER_ENABLE_PIN  8  // SW6  Pin should have a pullup!
+
+  #elif ENABLED(board_rev_1_5)      // use the same pins - but now they are on a different connector
+
+    #define SPINDLE_DIR_PIN          10  // EXP3-6 (silkscreen says 10)
+    #define SPINDLE_LASER_PWM_PIN     9  // EXP3-7 (silkscreen says 9) MUST BE HARDWARE PWM
+    #define SPINDLE_LASER_ENABLE_PIN  8  // EXP3-8 (silkscreen says 8) Pin should have a pullup!
+
+  #elif ENABLED(board_rev_1_1_TO_1_3)
+
+    /**
+     *  Only four hardware PWMs physically connected to anything on these boards:
+     *
+     *    HEATER_0_PIN    2  silkscreen varies - usually "PWM 1" or "HEATER1"
+     *    HEATER_1_PIN    3  silkscreen varies - usually "PWM 2" or "HEATER2"
+     *    HEATER_BED_PIN  4  silkscreen varies - usually "PWM 3" or "HEATED BED"
+     *    E0_DIR_PIN     45
+     *
+     *   If one of the heaters is used then special precautions will usually be needed.
+     *   They have an LED and resistor pullup to +24V which could damage 3.3V-5V ICs.
+     */
+    #if EXTRUDERS == 1                     // Move E0 stepper module to the spare and get signals from E0
+      #undef E0_STEP_PIN
+      #undef E0_DIR_PIN
+      #undef E0_ENABLE_PIN
+      #define E0_STEP_PIN              49
+      #define E0_DIR_PIN               47
+      #define E0_ENABLE_PIN            48
+      #define SPINDLE_DIR_PIN          43
+      #define SPINDLE_LASER_PWM_PIN    45  // MUST BE HARDWARE PWM
+      #define SPINDLE_LASER_ENABLE_PIN 41  // Pin should have a pullup!
+    #elif TEMP_SENSOR_BED == 0  // Can't use E0 so see if HEATER_BED_PIN is available
+      #undef HEATER_BED_PIN
+      #define SPINDLE_DIR_PIN          38  // Probably pin 4 on 10 pin connector closest to the E0 socket
+      #define SPINDLE_LASER_PWM_PIN     4  // MUST BE HARDWARE PWM - Special precautions usually needed.
+      #define SPINDLE_LASER_ENABLE_PIN 40  // Pin should have a pullup! (Probably pin 6 on the 10-pin
+                                           // connector closest to the E0 socket)
+    #endif
+  #endif
+#endif
+
+/**
+ *  Where to get the spindle signals on the E0 socket
+ *
+ *         spindle signal     socket name       socket name
+ *                                       -------
+ * SPINDLE_LASER_ENABLE_PIN    /ENABLE  *|     |O  VMOT
+ *                                 MS1  O|     |O  GND
+ *                                 MS2  O|     |O  2B
+ *                                 MS3  O|     |O  2A
+ *                              /RESET  O|     |O  1A
+ *                              /SLEEP  O|     |O  1B
+ *          SPINDLE_DIR_PIN       STEP  O|     |O  VDD
+ *    SPINDLE_LASER_PWM_PIN        DIR  O|     |O  GND
+ *                                       -------
+ *  * - pin closest to MS1, MS2 & MS3 jumpers on the board
+ *
+ *  Note: Socket names vary from vendor to vendor.
+ */

From 55a87da036c48559fabd20246d9b810a3c93b0fe Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 7 Apr 2017 13:52:45 -0500
Subject: [PATCH 3/3] SPINDLE/LASER implementation

---
 Marlin/Marlin_main.cpp | 141 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 141 insertions(+)

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index e6ce386ef2..cb7ec8696e 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -73,6 +73,9 @@
  *
  * M0   - Unconditional stop - Wait for user to press a button on the LCD (Only if ULTRA_LCD is enabled)
  * M1   - Same as M0
+ * M3   - Turn laser/spindle on, set spindle/laser speed/power, set rotation to clockwise
+ * M4   - Turn laser/spindle on, set spindle/laser speed/power, set rotation to counter-clockwise
+ * M5   - Turn laser/spindle off
  * M17  - Enable/Power all stepper motors
  * M18  - Disable all stepper motors; same as M84
  * M20  - List SD card. (Requires SDSUPPORT)
@@ -5611,6 +5614,121 @@ inline void gcode_G92() {
 
 #endif // HAS_RESUME_CONTINUE
 
+#if ENABLED(SPINDLE_LASER_ENABLE)
+  /**
+   * M3: Spindle Clockwise
+   * M4: Spindle Counter-clockwise
+   *
+   *  S0 turns off spindle.
+   *
+   *  If no speed PWM output is defined then M3/M4 just turns it on.
+   *
+   *  At least 12.8KHz (50Hz * 256) is needed for spindle PWM.
+   *  Hardware PWM is required. ISRs are too slow.
+   *
+   * NOTE: WGM for timers 3, 4, and 5 must be either Mode 1 or Mode 5.
+   *       No other settings give a PWM signal that goes from 0 to 5 volts.
+   *
+   *       The system automatically sets WGM to Mode 1, so no special
+   *       initialization is needed.
+   *
+   *       WGM bits for timer 2 are automatically set by the system to
+   *       Mode 1. This produces an acceptable 0 to 5 volt signal.
+   *       No special initialization is needed.
+   *
+   * NOTE: A minimum PWM frequency of 50 Hz is needed. All prescaler
+   *       factors for timers 2, 3, 4, and 5 are acceptable.
+   *
+   *  SPINDLE_LASER_ENABLE_PIN needs an external pullup or it may power on
+   *  the spindle/laser during power-up or when connecting to the host
+   *  (usually goes through a reset which sets all I/O pins to tri-state)
+   *
+   *  PWM duty cycle goes from 0 (off) to 255 (always on).
+   */
+
+  // Wait for spindle to come up to speed
+  inline void delay_for_power_up() {
+    refresh_cmd_timeout();
+    while (PENDING(millis(), SPINDLE_LASER_POWERUP_DELAY + previous_cmd_ms)) idle();
+  }
+
+  // Wait for spindle to stop turning
+  inline void delay_for_power_down() {
+    refresh_cmd_timeout();
+    while (PENDING(millis(), SPINDLE_LASER_POWERDOWN_DELAY + previous_cmd_ms + 1)) idle();
+  }
+
+  /**
+   * ocr_val_mode() is used for debugging and to get the points needed to compute the RPM vs ocr_val line
+   *
+   * it accepts inputs of 0-255
+   */
+
+  inline void ocr_val_mode() {
+    uint8_t spindle_laser_power = code_value_byte();
+    WRITE(SPINDLE_LASER_ENABLE_PIN, SPINDLE_LASER_ENABLE_INVERT); // turn spindle on (active low)
+    if (SPINDLE_LASER_PWM_INVERT) spindle_laser_power = 255 - spindle_laser_power;
+    analogWrite(SPINDLE_LASER_PWM_PIN, spindle_laser_power);
+  }
+
+  inline void gcode_M3_M4(bool is_M3) {
+
+    stepper.synchronize();   // wait until previous movement commands (G0/G0/G2/G3) have completed before playing with the spindle
+    #if SPINDLE_DIR_CHANGE
+      const bool rotation_dir = (is_M3 && !SPINDLE_INVERT_DIR || !is_M3 && SPINDLE_INVERT_DIR) ? HIGH : LOW;
+      if (SPINDLE_STOP_ON_DIR_CHANGE \
+         && READ(SPINDLE_LASER_ENABLE_PIN) == SPINDLE_LASER_ENABLE_INVERT \
+         && READ(SPINDLE_DIR_PIN) != rotation_dir
+      ) {
+        WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT);  // turn spindle off
+        delay_for_power_down();
+      }
+      digitalWrite(SPINDLE_DIR_PIN, rotation_dir);
+    #endif
+
+    /**
+     * Our final value for ocr_val is an unsigned 8 bit value between 0 and 255 which usually means uint8_t.
+     * Went to uint16_t because some of the uint8_t calculations would sometimes give 1000 0000 rather than 1111 1111.
+     * Then needed to AND the uint16_t result with 0x00FF to make sure we only wrote the byte of interest.
+     */
+    #if ENABLED(SPINDLE_LASER_PWM)
+      if (code_seen('O')) ocr_val_mode();
+      else {
+        const float spindle_laser_power = code_seen('S') ? code_value_float() : 0;
+        if (spindle_laser_power == 0) {
+          WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT);                                    // turn spindle off (active low)
+          delay_for_power_down();
+        }
+        else {
+          int16_t ocr_val = (spindle_laser_power - (SPEED_POWER_INTERCEPT)) * (1.0 / (SPEED_POWER_SLOPE));  // convert RPM to PWM duty cycle
+          NOMORE(ocr_val, 255);                                                                             // limit to max the Atmel PWM will support
+          if (spindle_laser_power <= SPEED_POWER_MIN)
+            ocr_val = (SPEED_POWER_MIN - (SPEED_POWER_INTERCEPT)) * (1.0 / (SPEED_POWER_SLOPE));            // minimum setting
+          if (spindle_laser_power >= SPEED_POWER_MAX)
+            ocr_val = (SPEED_POWER_MAX - (SPEED_POWER_INTERCEPT)) * (1.0 / (SPEED_POWER_SLOPE));            // limit to max RPM
+          if (SPINDLE_LASER_PWM_INVERT) ocr_val = 255 - ocr_val;
+          WRITE(SPINDLE_LASER_ENABLE_PIN, SPINDLE_LASER_ENABLE_INVERT);                                     // turn spindle on (active low)
+          analogWrite(SPINDLE_LASER_PWM_PIN, ocr_val & 0xFF);                                               // only write low byte
+          delay_for_power_up();
+        }
+      }
+    #else
+      WRITE(SPINDLE_LASER_ENABLE_PIN, SPINDLE_LASER_ENABLE_INVERT); // turn spindle on (active low) if spindle speed option not enabled
+      delay_for_power_up();
+    #endif
+  }
+
+ /**
+  * M5 turn off spindle
+  */
+  inline void gcode_M5() {
+    stepper.synchronize();
+    WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT);
+    delay_for_power_down();
+  }
+
+#endif // SPINDLE_LASER_ENABLE
+
 /**
  * M17: Enable power on all stepper motors
  */
@@ -5626,6 +5744,7 @@ inline void gcode_M17() {
 #endif
 
 #if ENABLED(PARK_HEAD_ON_PAUSE)
+
   float resume_position[XYZE];
   bool move_away_flag = false;
 
@@ -9946,6 +10065,17 @@ void process_next_command() {
           break;
       #endif // ULTIPANEL
 
+      #if ENABLED(SPINDLE_LASER_ENABLE)
+        case 3:
+          gcode_M3_M4(true);   // M3: turn spindle/laser on, set laser/spindle power/speed, set rotation direction CW
+          break;               // synchronizes with movement commands
+        case 4:
+          gcode_M3_M4(false);  // M4: turn spindle/laser on, set laser/spindle power/speed, set rotation direction CCW
+          break;               // synchronizes with movement commands
+        case 5:
+          gcode_M5();     // M5 - turn spindle/laser off
+          break;          // synchronizes with movement commands
+      #endif
       case 17: // M17: Enable all stepper motors
         gcode_M17();
         break;
@@ -12262,6 +12392,17 @@ void setup() {
     update_case_light();
   #endif
 
+  #if ENABLED(SPINDLE_LASER_ENABLE)
+    OUT_WRITE(SPINDLE_LASER_ENABLE_PIN, !SPINDLE_LASER_ENABLE_INVERT);  // init spindle to off
+    #if SPINDLE_DIR_CHANGE
+      OUT_WRITE(SPINDLE_DIR_PIN, SPINDLE_INVERT_DIR ? 255 : 0);  // init rotation to clockwise (M3)
+    #endif
+    #if ENABLED(SPINDLE_LASER_PWM)
+      SET_OUTPUT(SPINDLE_LASER_PWM_PIN);
+      analogWrite(SPINDLE_LASER_PWM_PIN, SPINDLE_LASER_PWM_INVERT ? 255 : 0);  // set to lowest speed
+    #endif
+  #endif
+
   #if HAS_BED_PROBE
     endstops.enable_z_probe(false);
   #endif