From f179e25cc640135f968ffb12a12fdf4bd0b14212 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <thinkyhead@users.noreply.github.com>
Date: Sun, 24 Oct 2021 23:32:34 -0500
Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20More=20explicit=20allocation=20o?=
 =?UTF-8?q?f=20solenoids?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

In reference to #22887
---
 Marlin/Configuration.h             |  1 -
 Marlin/src/feature/solenoid.cpp    | 40 +++-----------------
 Marlin/src/inc/Conditionals_post.h | 59 ++++++++++++++++++------------
 Marlin/src/inc/SanityCheck.h       |  2 +-
 4 files changed, 41 insertions(+), 61 deletions(-)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index c50af25e63..e90e90b146 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -260,7 +260,6 @@
 
   #define PARKING_EXTRUDER_PARKING_X { -78, 184 }     // X positions for parking the extruders
   #define PARKING_EXTRUDER_GRAB_DISTANCE 1            // (mm) Distance to move beyond the parking point to grab the extruder
-  //#define MANUAL_SOLENOID_CONTROL                   // Manual control of docking solenoids with M380 S / M381
 
   #if ENABLED(PARKING_EXTRUDER)
 
diff --git a/Marlin/src/feature/solenoid.cpp b/Marlin/src/feature/solenoid.cpp
index 623f223caa..b6795d1a1e 100644
--- a/Marlin/src/feature/solenoid.cpp
+++ b/Marlin/src/feature/solenoid.cpp
@@ -34,28 +34,12 @@
   #include "../module/tool_change.h"
 #endif
 
-#define HAS_SOLENOID(N) (HAS_SOLENOID_##N && (ENABLED(MANUAL_SOLENOID_CONTROL) || N < EXTRUDERS))
-
 // Used primarily with MANUAL_SOLENOID_CONTROL
 static void set_solenoid(const uint8_t num, const bool active) {
   const uint8_t value = active ? PE_MAGNET_ON_STATE : !PE_MAGNET_ON_STATE;
+  #define _SOL_CASE(N) case N: TERN_(HAS_SOLENOID_##N, OUT_WRITE(SOL##N##_PIN, value)); break;
   switch (num) {
-    case 0: OUT_WRITE(SOL0_PIN, value); break;
-    #if HAS_SOLENOID(1)
-      case 1: OUT_WRITE(SOL1_PIN, value); break;
-    #endif
-    #if HAS_SOLENOID(2)
-      case 2: OUT_WRITE(SOL2_PIN, value); break;
-    #endif
-    #if HAS_SOLENOID(3)
-      case 3: OUT_WRITE(SOL3_PIN, value); break;
-    #endif
-    #if HAS_SOLENOID(4)
-      case 4: OUT_WRITE(SOL4_PIN, value); break;
-    #endif
-    #if HAS_SOLENOID(5)
-      case 5: OUT_WRITE(SOL5_PIN, value); break;
-    #endif
+    REPEAT(8, _SOL_CASE)
     default: SERIAL_ECHO_MSG(STR_INVALID_SOLENOID); break;
   }
 
@@ -67,25 +51,11 @@ static void set_solenoid(const uint8_t num, const bool active) {
 
 void enable_solenoid(const uint8_t num) { set_solenoid(num, true); }
 void disable_solenoid(const uint8_t num) { set_solenoid(num, false); }
-void enable_solenoid_on_active_extruder() { enable_solenoid(active_extruder); }
+void enable_solenoid_on_active_extruder() {  }
 
 void disable_all_solenoids() {
-  disable_solenoid(0);
-  #if HAS_SOLENOID(1)
-    disable_solenoid(1);
-  #endif
-  #if HAS_SOLENOID(2)
-    disable_solenoid(2);
-  #endif
-  #if HAS_SOLENOID(3)
-    disable_solenoid(3);
-  #endif
-  #if HAS_SOLENOID(4)
-    disable_solenoid(4);
-  #endif
-  #if HAS_SOLENOID(5)
-    disable_solenoid(5);
-  #endif
+  #define _SOL_DISABLE(N) TERN_(HAS_SOLENOID_##N, disable_solenoid(N));
+  REPEAT(8, _SOL_DISABLE)
 }
 
 #endif // EXT_SOLENOID || MANUAL_SOLENOID_CONTROL
diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h
index 1db4208a1f..e9e282c262 100644
--- a/Marlin/src/inc/Conditionals_post.h
+++ b/Marlin/src/inc/Conditionals_post.h
@@ -1633,9 +1633,6 @@
   #if PIN_EXISTS(E0_MS1)
     #define HAS_E0_MS_PINS 1
   #endif
-  #if PIN_EXISTS(SOL0)
-    #define HAS_SOLENOID_0 1
-  #endif
 
   #if E_STEPPERS > 1
     #if PIN_EXISTS(E1_ENABLE) || AXIS_IS_L64XX(E1) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E1))
@@ -1650,9 +1647,6 @@
     #if PIN_EXISTS(E1_MS1)
       #define HAS_E1_MS_PINS 1
     #endif
-    #if PIN_EXISTS(SOL1)
-      #define HAS_SOLENOID_1 1
-    #endif
   #endif
 
   #if E_STEPPERS > 2
@@ -1668,9 +1662,6 @@
     #if PIN_EXISTS(E2_MS1)
       #define HAS_E2_MS_PINS 1
     #endif
-    #if PIN_EXISTS(SOL2)
-      #define HAS_SOLENOID_2 1
-    #endif
   #endif
 
   #if E_STEPPERS > 3
@@ -1686,9 +1677,6 @@
     #if PIN_EXISTS(E3_MS1)
       #define HAS_E3_MS_PINS 1
     #endif
-    #if PIN_EXISTS(SOL3)
-      #define HAS_SOLENOID_3 1
-    #endif
   #endif
 
   #if E_STEPPERS > 4
@@ -1704,9 +1692,6 @@
     #if PIN_EXISTS(E4_MS1)
       #define HAS_E4_MS_PINS 1
     #endif
-    #if PIN_EXISTS(SOL4)
-      #define HAS_SOLENOID_4 1
-    #endif
   #endif
 
   #if E_STEPPERS > 5
@@ -1722,9 +1707,6 @@
     #if PIN_EXISTS(E5_MS1)
       #define HAS_E5_MS_PINS 1
     #endif
-    #if PIN_EXISTS(SOL5)
-      #define HAS_SOLENOID_5 1
-    #endif
   #endif
 
   #if E_STEPPERS > 6
@@ -1740,9 +1722,6 @@
     #if PIN_EXISTS(E6_MS1)
       #define HAS_E6_MS_PINS 1
     #endif
-    #if PIN_EXISTS(SOL6)
-      #define HAS_SOLENOID_6 1
-    #endif
   #endif
 
   #if E_STEPPERS > 7
@@ -1758,9 +1737,6 @@
     #if PIN_EXISTS(E7_MS1)
       #define HAS_E7_MS_PINS 1
     #endif
-    #if PIN_EXISTS(SOL7)
-      #define HAS_SOLENOID_7 1
-    #endif
   #endif
 
   #if !defined(DISABLE_INACTIVE_E) && ENABLED(DISABLE_E)
@@ -1770,6 +1746,41 @@
   #undef DISABLE_INACTIVE_E
 #endif // HAS_EXTRUDERS
 
+/**
+ * Set solenoid flags if any features use solenoids
+ *   - EXT_SOLENOID (M380, M381) to enable/disable the extruder solenoid
+ *   - MANUAL_SOLENOID_CONTROL (M380, M381) to enable/disable solenoids by index
+ *   - PARKING_EXTRUDER uses SOL0_PIN and SOL1_PIN
+ *   - SOLENOID_PROBE uses SOL1_PIN
+ *   - Z_PROBE_SLED uses SOL1_PIN, when defined (unless EXT_SOLENOID is enabled)
+ */
+#if ANY(EXT_SOLENOID, MANUAL_SOLENOID_CONTROL, PARKING_EXTRUDER, SOLENOID_PROBE, Z_PROBE_SLED)
+  #if PIN_EXISTS(SOL0) && (EITHER(MANUAL_SOLENOID_CONTROL, PARKING_EXTRUDER) || BOTH(EXT_SOLENOID, HAS_EXTRUDERS))
+    #define HAS_SOLENOID_0 1
+  #endif
+  #if PIN_EXISTS(SOL1) && (ANY(MANUAL_SOLENOID_CONTROL, PARKING_EXTRUDER, SOLENOID_PROBE, Z_PROBE_SLED) || TERN0(EXT_SOLENOID, E_STEPPERS > 1))
+    #define HAS_SOLENOID_1 1
+  #endif
+  #if PIN_EXISTS(SOL2) && (ENABLED(MANUAL_SOLENOID_CONTROL) || TERN0(EXT_SOLENOID, E_STEPPERS > 2))
+    #define HAS_SOLENOID_2 2
+  #endif
+  #if PIN_EXISTS(SOL3) && (ENABLED(MANUAL_SOLENOID_CONTROL) || TERN0(EXT_SOLENOID, E_STEPPERS > 3))
+    #define HAS_SOLENOID_3 3
+  #endif
+  #if PIN_EXISTS(SOL4) && (ENABLED(MANUAL_SOLENOID_CONTROL) || TERN0(EXT_SOLENOID, E_STEPPERS > 4))
+    #define HAS_SOLENOID_4 4
+  #endif
+  #if PIN_EXISTS(SOL5) && (ENABLED(MANUAL_SOLENOID_CONTROL) || TERN0(EXT_SOLENOID, E_STEPPERS > 5))
+    #define HAS_SOLENOID_5 5
+  #endif
+  #if PIN_EXISTS(SOL6) && (ENABLED(MANUAL_SOLENOID_CONTROL) || TERN0(EXT_SOLENOID, E_STEPPERS > 6))
+    #define HAS_SOLENOID_6 6
+  #endif
+  #if PIN_EXISTS(SOL7) && (ENABLED(MANUAL_SOLENOID_CONTROL) || TERN0(EXT_SOLENOID, E_STEPPERS > 7))
+    #define HAS_SOLENOID_7 7
+  #endif
+#endif
+
 //
 // Trinamic Stepper Drivers
 //
diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h
index abc38c0a5a..856d0c44c7 100644
--- a/Marlin/src/inc/SanityCheck.h
+++ b/Marlin/src/inc/SanityCheck.h
@@ -1239,7 +1239,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
 /**
  * (Magnetic) Parking Extruder requirements
  */
-#if ANY(PARKING_EXTRUDER, MAGNETIC_PARKING_EXTRUDER)
+#if EITHER(PARKING_EXTRUDER, MAGNETIC_PARKING_EXTRUDER)
   #if ENABLED(EXT_SOLENOID)
     #error "(MAGNETIC_)PARKING_EXTRUDER and EXT_SOLENOID are incompatible. (Pins are used twice.)"
   #elif EXTRUDERS != 2