diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index d926d4fc84..afa37cd131 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -106,7 +106,7 @@
/**
* Select a third serial port on the board to use for communication with the host.
- * Currently only supported for AVR, DUE, LPC1768/9 and STM32/STM32F1
+ * Currently supported for AVR, DUE, SAMD51, LPC1768/9, STM32/STM32F1/HC32, and Teensy 4.x
* :[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
*/
//#define SERIAL_PORT_3 1
diff --git a/Marlin/src/HAL/SAMD51/HAL.h b/Marlin/src/HAL/SAMD51/HAL.h
index c96401fd97..c43d1b591b 100644
--- a/Marlin/src/HAL/SAMD51/HAL.h
+++ b/Marlin/src/HAL/SAMD51/HAL.h
@@ -69,6 +69,16 @@
#endif
#endif
+ #ifdef SERIAL_PORT_3
+ #if SERIAL_PORT_3 == -1
+ #define MYSERIAL3 MSerial0
+ #elif WITHIN(SERIAL_PORT_3, 0, 3)
+ #define MYSERIAL3 MSERIAL(SERIAL_PORT_3)
+ #else
+ #error "SERIAL_PORT_3 must be from 0 to 3. You can also use -1 if the board supports Native USB."
+ #endif
+ #endif
+
#ifdef MMU2_SERIAL_PORT
#if MMU2_SERIAL_PORT == -1
#define MMU2_SERIAL MSerial0
diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h
index 633efc1e2f..1d2704d8a6 100644
--- a/Marlin/src/inc/Conditionals_LCD.h
+++ b/Marlin/src/inc/Conditionals_LCD.h
@@ -26,600 +26,37 @@
* Conditionals that need to be set before Configuration_adv.h or pins.h
*/
-#ifndef STRING_CONFIG_H_AUTHOR
- #define STRING_CONFIG_H_AUTHOR "(anonymous)"
-#endif
-
-/**
- * Extruders have some combination of stepper motors and hotends
- * so we separate these concepts into the defines:
- *
- * EXTRUDERS - Number of Selectable Tools
- * HOTENDS - Number of hotends, whether connected or separate
- * E_STEPPERS - Number of actual E stepper motors
- * E_MANUAL - Number of E steppers for LCD move options
- *
- * These defines must be simple constants for use in REPEAT, etc.
- */
-#if EXTRUDERS
- #define HAS_EXTRUDERS 1
- #if EXTRUDERS > 1
- #define HAS_MULTI_EXTRUDER 1
- #endif
- #define E_AXIS_N(E) AxisEnum(E_AXIS + E_INDEX_N(E))
-#else
- #undef EXTRUDERS
- #define EXTRUDERS 0
- #undef TEMP_SENSOR_0
- #undef TEMP_SENSOR_1
- #undef TEMP_SENSOR_2
- #undef TEMP_SENSOR_3
- #undef TEMP_SENSOR_4
- #undef TEMP_SENSOR_5
- #undef TEMP_SENSOR_6
- #undef TEMP_SENSOR_7
- #undef SINGLENOZZLE
- #undef SWITCHING_EXTRUDER
- #undef MECHANICAL_SWITCHING_EXTRUDER
- #undef SWITCHING_NOZZLE
- #undef MECHANICAL_SWITCHING_NOZZLE
- #undef MIXING_EXTRUDER
- #undef HOTEND_IDLE_TIMEOUT
- #undef DISABLE_E
- #undef PREVENT_LENGTHY_EXTRUDE
- #undef FILAMENT_RUNOUT_SENSOR
- #undef FILAMENT_RUNOUT_DISTANCE_MM
- #undef DISABLE_OTHER_EXTRUDERS
- #undef THERMAL_PROTECTION_HYSTERESIS
- #undef THERMAL_PROTECTION_PERIOD
-#endif
-
-#define E_OPTARG(N) OPTARG(HAS_MULTI_EXTRUDER, N)
-#define E_TERN_(N) TERN_(HAS_MULTI_EXTRUDER, N)
-#define E_TERN0(N) TERN0(HAS_MULTI_EXTRUDER, N)
-
-#if ANY(SWITCHING_EXTRUDER, MECHANICAL_SWITCHING_EXTRUDER)
- #define HAS_SWITCHING_EXTRUDER 1
-#endif
-#if ANY(SWITCHING_NOZZLE, MECHANICAL_SWITCHING_NOZZLE)
- #define HAS_SWITCHING_NOZZLE 1
-#endif
-
-/**
- * Multi-Material-Unit supported models
- */
-#ifdef MMU_MODEL
- #define HAS_MMU 1
- #define SINGLENOZZLE
-
- #define _PRUSA_MMU1 1
- #define _PRUSA_MMU2 2
- #define _PRUSA_MMU2S 3
- #define _PRUSA_MMU3 4
- #define _EXTENDABLE_EMU_MMU2 12
- #define _EXTENDABLE_EMU_MMU2S 13
- #define _EXTENDABLE_EMU_MMU3 14
- #define _MMU CAT(_,MMU_MODEL)
-
- #if _MMU == _PRUSA_MMU1
- #define HAS_PRUSA_MMU1 1
- #elif _MMU % 10 == _PRUSA_MMU2
- #define HAS_PRUSA_MMU2 1
- #elif _MMU % 10 == _PRUSA_MMU2S
- #define HAS_PRUSA_MMU2 1
- #define HAS_PRUSA_MMU2S 1
- #elif _MMU % 10 == _PRUSA_MMU3
- #define HAS_PRUSA_MMU3 1
- #endif
- #if _MMU == _EXTENDABLE_EMU_MMU2 || _MMU == _EXTENDABLE_EMU_MMU2S
- #define HAS_EXTENDABLE_MMU 1
- #endif
-
- #undef _MMU
- #undef _PRUSA_MMU1
- #undef _PRUSA_MMU2
- #undef _PRUSA_MMU2S
- #undef _PRUSA_MMU3
- #undef _EXTENDABLE_EMU_MMU2
- #undef _EXTENDABLE_EMU_MMU2S
- #undef _EXTENDABLE_EMU_MMU3
-#endif
-
-#if ENABLED(E_DUAL_STEPPER_DRIVERS) // E0/E1 steppers act in tandem as E0
-
- #define E_STEPPERS 2
- #define E_MANUAL 1
-
-#elif HAS_SWITCHING_EXTRUDER // One stepper for every two EXTRUDERS
-
- #if EXTRUDERS > 4
- #define E_STEPPERS 3
- #elif EXTRUDERS > 2
- #define E_STEPPERS 2
- #else
- #define E_STEPPERS 1
- #endif
-
-#elif ENABLED(MIXING_EXTRUDER) // Multiple feeds are mixed proportionally
-
- #define E_STEPPERS MIXING_STEPPERS
- #define E_MANUAL 1
- #if MIXING_STEPPERS == 2
- #define HAS_DUAL_MIXING 1
- #endif
- #ifndef MIXING_VIRTUAL_TOOLS
- #define MIXING_VIRTUAL_TOOLS 1
- #endif
-
-#elif ENABLED(SWITCHING_TOOLHEAD) // Toolchanger
-
- #define E_STEPPERS EXTRUDERS
- #define E_MANUAL EXTRUDERS
-
-#elif HAS_PRUSA_MMU2 || HAS_PRUSA_MMU3 // Průša Multi-Material Unit v2/v3
-
- #define E_STEPPERS 1
- #define E_MANUAL 1
-
-#endif
-
-// Default E steppers / manual motion is one per extruder
-#ifndef E_STEPPERS
- #define E_STEPPERS EXTRUDERS
-#endif
-#ifndef E_MANUAL
- #define E_MANUAL EXTRUDERS
-#endif
-
-// Number of hotends...
-#if ANY(SINGLENOZZLE, MIXING_EXTRUDER) // Only one for singlenozzle or mixing extruder
- #define HOTENDS 1
-#elif HAS_SWITCHING_EXTRUDER && !HAS_SWITCHING_NOZZLE // One for each pair of abstract "extruders"
- #define HOTENDS E_STEPPERS
-#elif TEMP_SENSOR_0
- #define HOTENDS EXTRUDERS // One per extruder if at least one heater exists
-#else
- #define HOTENDS 0 // A machine with no hotends at all can still extrude
-#endif
-
-// At least one hotend...
-#if HOTENDS
- #define HAS_HOTEND 1
- #ifndef HOTEND_OVERSHOOT
- #define HOTEND_OVERSHOOT 15
- #endif
-#endif
-
-// More than one hotend...
-#if HOTENDS > 1
- #define HAS_MULTI_HOTEND 1
- #define HAS_HOTEND_OFFSET 1
- #ifndef HOTEND_OFFSET_X
- #define HOTEND_OFFSET_X { 0 } // X offsets for each extruder
- #endif
- #ifndef HOTEND_OFFSET_Y
- #define HOTEND_OFFSET_Y { 0 } // Y offsets for each extruder
- #endif
- #ifndef HOTEND_OFFSET_Z
- #define HOTEND_OFFSET_Z { 0 } // Z offsets for each extruder
- #endif
-#else
- #undef HOTEND_OFFSET_X
- #undef HOTEND_OFFSET_Y
- #undef HOTEND_OFFSET_Z
-#endif
-
-//
-// Remove irrelevant Configuration.h settings
-//
-
-// Clean up E-stepper-based settings...
-#if E_STEPPERS <= 7
- #undef INVERT_E7_DIR
- #undef E7_DRIVER_TYPE
- #if E_STEPPERS <= 6
- #undef INVERT_E6_DIR
- #undef E6_DRIVER_TYPE
- #if E_STEPPERS <= 5
- #undef INVERT_E5_DIR
- #undef E5_DRIVER_TYPE
- #if E_STEPPERS <= 4
- #undef INVERT_E4_DIR
- #undef E4_DRIVER_TYPE
- #if E_STEPPERS <= 3
- #undef INVERT_E3_DIR
- #undef E3_DRIVER_TYPE
- #if E_STEPPERS <= 2
- #undef INVERT_E2_DIR
- #undef E2_DRIVER_TYPE
- #if E_STEPPERS <= 1
- #undef INVERT_E1_DIR
- #undef E1_DRIVER_TYPE
- #if E_STEPPERS == 0
- #undef INVERT_E0_DIR
- #undef E0_DRIVER_TYPE
- #endif
- #endif
- #endif
- #endif
- #endif
- #endif
- #endif
-#endif
-
-// Clean up unused temperature sensors and sub-options
-
-#if !TEMP_SENSOR_0
- #undef TEMP_SENSOR_0
-#endif
-#if !TEMP_SENSOR_1
- #undef TEMP_SENSOR_1
-#endif
-#if !TEMP_SENSOR_2
- #undef TEMP_SENSOR_2
-#endif
-#if !TEMP_SENSOR_3
- #undef TEMP_SENSOR_3
-#endif
-#if !TEMP_SENSOR_4
- #undef TEMP_SENSOR_4
-#endif
-#if !TEMP_SENSOR_5
- #undef TEMP_SENSOR_5
-#endif
-#if !TEMP_SENSOR_6
- #undef TEMP_SENSOR_6
-#endif
-#if !TEMP_SENSOR_7
- #undef TEMP_SENSOR_7
-#endif
-
-#if TEMP_SENSOR_BED
- #define HAS_HEATED_BED 1
-#else
- #undef TEMP_SENSOR_BED
- #undef THERMAL_PROTECTION_BED_HYSTERESIS
- #undef THERMAL_PROTECTION_BED_PERIOD
- #undef MAX_BED_POWER
-#endif
-#if !TEMP_SENSOR_CHAMBER
- #undef TEMP_SENSOR_CHAMBER
- #undef THERMAL_PROTECTION_CHAMBER_HYSTERESIS
- #undef THERMAL_PROTECTION_CHAMBER_PERIOD
- #undef CHAMBER_AUTO_FAN_PIN
- #undef CHAMBER_AUTO_FAN_SPEED
- #undef CHAMBER_AUTO_FAN_TEMPERATURE
- #undef MAX_CHAMBER_POWER
-#endif
-#if !TEMP_SENSOR_COOLER
- #undef TEMP_SENSOR_COOLER
- #undef COOLER_AUTO_FAN_PIN
- #undef COOLER_AUTO_FAN_SPEED
- #undef COOLER_AUTO_FAN_TEMPERATURE
-#endif
-#if !TEMP_SENSOR_PROBE
- #undef TEMP_SENSOR_PROBE
-#endif
-#if !TEMP_SENSOR_REDUNDANT
- #undef TEMP_SENSOR_REDUNDANT
-#endif
-#if !TEMP_SENSOR_BOARD
- #undef TEMP_SENSOR_BOARD
-#endif
-#if !TEMP_SENSOR_SOC
- #undef TEMP_SENSOR_SOC
-#endif
-#if !SOFT_PWM_SCALE
- #undef SOFT_PWM_SCALE
-#endif
-
-/**
- * Number of Linear Axes (e.g., XYZIJKUVW)
- * All the logical axes except for the tool (E) axis
- */
-#ifdef NUM_AXES
- #undef NUM_AXES
- #define NUM_AXES_WARNING 1
-#endif
-
-#ifdef W_DRIVER_TYPE
- #define NUM_AXES 9
-#elif defined(V_DRIVER_TYPE)
- #define NUM_AXES 8
-#elif defined(U_DRIVER_TYPE)
- #define NUM_AXES 7
-#elif defined(K_DRIVER_TYPE)
- #define NUM_AXES 6
-#elif defined(J_DRIVER_TYPE)
- #define NUM_AXES 5
-#elif defined(I_DRIVER_TYPE)
- #define NUM_AXES 4
-#elif defined(Z_DRIVER_TYPE)
- #define NUM_AXES 3
-#elif defined(Y_DRIVER_TYPE)
- #define NUM_AXES 2
-#elif defined(X_DRIVER_TYPE)
- #define NUM_AXES 1
-#else
- #define NUM_AXES 0
-#endif
-#if NUM_AXES >= 1
- #define HAS_X_AXIS 1
- #define HAS_A_AXIS 1
- #if NUM_AXES >= XY
- #define HAS_Y_AXIS 1
- #define HAS_B_AXIS 1
- #if NUM_AXES >= XYZ
- #define HAS_Z_AXIS 1
- #define HAS_C_AXIS 1
- #if NUM_AXES >= 4
- #define HAS_I_AXIS 1
- #if NUM_AXES >= 5
- #define HAS_J_AXIS 1
- #if NUM_AXES >= 6
- #define HAS_K_AXIS 1
- #if NUM_AXES >= 7
- #define HAS_U_AXIS 1
- #if NUM_AXES >= 8
- #define HAS_V_AXIS 1
- #if NUM_AXES >= 9
- #define HAS_W_AXIS 1
- #endif
- #endif
- #endif
- #endif
- #endif
- #endif
- #endif
- #endif
-#endif
-
-#if HAS_Z_AXIS
- #ifdef Z4_DRIVER_TYPE
- #define NUM_Z_STEPPERS 4
- #elif defined(Z3_DRIVER_TYPE)
- #define NUM_Z_STEPPERS 3
- #elif defined(Z2_DRIVER_TYPE)
- #define NUM_Z_STEPPERS 2
- #else
- #define NUM_Z_STEPPERS 1
- #endif
-#endif
-
-#if !HAS_X_AXIS
- #undef AVOID_OBSTACLES
- #undef X2_DRIVER_TYPE
- #undef X_ENABLE_ON
- #undef DISABLE_X
- #undef INVERT_X_DIR
- #undef X_HOME_DIR
- #undef X_MIN_POS
- #undef X_MAX_POS
- #undef MANUAL_X_HOME_POS
- #undef MIN_SOFTWARE_ENDSTOPS
- #undef MAX_SOFTWARE_ENDSTOPS
- #undef MIN_SOFTWARE_ENDSTOP_X
- #undef MAX_SOFTWARE_ENDSTOP_X
-#endif
-
-#if !HAS_Y_AXIS
- #undef AVOID_OBSTACLES
- #undef Y2_DRIVER_TYPE
- #undef Y_ENABLE_ON
- #undef DISABLE_Y
- #undef INVERT_Y_DIR
- #undef Y_HOME_DIR
- #undef Y_MIN_POS
- #undef Y_MAX_POS
- #undef MANUAL_Y_HOME_POS
- #undef MIN_SOFTWARE_ENDSTOP_Y
- #undef MAX_SOFTWARE_ENDSTOP_Y
-#endif
-
-#if !HAS_Z_AXIS
- #undef Z2_DRIVER_TYPE
- #undef Z3_DRIVER_TYPE
- #undef Z4_DRIVER_TYPE
- #undef Z_ENABLE_ON
- #undef DISABLE_Z
- #undef INVERT_Z_DIR
- #undef Z_HOME_DIR
- #undef Z_MIN_POS
- #undef Z_MAX_POS
- #undef MANUAL_Z_HOME_POS
- #undef Z_SAFE_HOMING
- #undef MIN_SOFTWARE_ENDSTOP_Z
- #undef MAX_SOFTWARE_ENDSTOP_Z
-#endif
-
-#if !HAS_I_AXIS
- #undef I_ENABLE_ON
- #undef DISABLE_I
- #undef INVERT_I_DIR
- #undef I_HOME_DIR
- #undef I_MIN_POS
- #undef I_MAX_POS
- #undef MANUAL_I_HOME_POS
- #undef MIN_SOFTWARE_ENDSTOP_I
- #undef MAX_SOFTWARE_ENDSTOP_I
-#endif
-
-#if !HAS_J_AXIS
- #undef J_ENABLE_ON
- #undef DISABLE_J
- #undef INVERT_J_DIR
- #undef J_HOME_DIR
- #undef J_MIN_POS
- #undef J_MAX_POS
- #undef MANUAL_J_HOME_POS
- #undef MIN_SOFTWARE_ENDSTOP_J
- #undef MAX_SOFTWARE_ENDSTOP_J
-#endif
-
-#if !HAS_K_AXIS
- #undef K_ENABLE_ON
- #undef DISABLE_K
- #undef INVERT_K_DIR
- #undef K_HOME_DIR
- #undef K_MIN_POS
- #undef K_MAX_POS
- #undef MANUAL_K_HOME_POS
- #undef MIN_SOFTWARE_ENDSTOP_K
- #undef MAX_SOFTWARE_ENDSTOP_K
-#endif
-
-#if !HAS_U_AXIS
- #undef U_ENABLE_ON
- #undef DISABLE_U
- #undef INVERT_U_DIR
- #undef U_HOME_DIR
- #undef U_MIN_POS
- #undef U_MAX_POS
- #undef MANUAL_U_HOME_POS
- #undef MIN_SOFTWARE_ENDSTOP_U
- #undef MAX_SOFTWARE_ENDSTOP_U
-#endif
-
-#if !HAS_V_AXIS
- #undef V_ENABLE_ON
- #undef DISABLE_V
- #undef INVERT_V_DIR
- #undef V_HOME_DIR
- #undef V_MIN_POS
- #undef V_MAX_POS
- #undef MANUAL_V_HOME_POS
- #undef MIN_SOFTWARE_ENDSTOP_V
- #undef MAX_SOFTWARE_ENDSTOP_V
-#endif
-
-#if !HAS_W_AXIS
- #undef W_ENABLE_ON
- #undef DISABLE_W
- #undef INVERT_W_DIR
- #undef W_HOME_DIR
- #undef W_MIN_POS
- #undef W_MAX_POS
- #undef MANUAL_W_HOME_POS
- #undef MIN_SOFTWARE_ENDSTOP_W
- #undef MAX_SOFTWARE_ENDSTOP_W
-#endif
-
-#define _OR_HAS_DA(A) ENABLED(DISABLE_##A) ||
-#if MAP(_OR_HAS_DA, X, Y, Z, I, J, K, U, V, W) 0
- #define HAS_DISABLE_MAIN_AXES 1
-#endif
-#if HAS_DISABLE_MAIN_AXES || ENABLED(DISABLE_E)
- #define HAS_DISABLE_AXES 1
-#endif
-#undef _OR_HAS_DA
-
-#ifdef X2_DRIVER_TYPE
- #define HAS_X2_STEPPER 1
-#endif
-#ifdef Y2_DRIVER_TYPE
- #define HAS_Y2_STEPPER 1
-#endif
-
-/**
- * Number of Primary Linear Axes (e.g., XYZ)
- * X, XY, or XYZ axes. Excluding duplicate axes (X2, Y2, Z2, Z3, Z4)
- */
-#if NUM_AXES >= 3
- #define PRIMARY_LINEAR_AXES 3
-#else
- #define PRIMARY_LINEAR_AXES NUM_AXES
-#endif
-
-/**
- * Number of Secondary Axes (e.g., IJKUVW)
- * All linear/rotational axes between XYZ and E.
- */
-#define SECONDARY_AXES SUB3(NUM_AXES)
-
-/**
- * Number of Rotational Axes (e.g., IJK)
- * All axes for which AXIS*_ROTATES is defined.
- * For these axes, positions are specified in angular degrees.
- */
-#if ENABLED(AXIS9_ROTATES)
- #define ROTATIONAL_AXES 6
-#elif ENABLED(AXIS8_ROTATES)
- #define ROTATIONAL_AXES 5
-#elif ENABLED(AXIS7_ROTATES)
- #define ROTATIONAL_AXES 4
-#elif ENABLED(AXIS6_ROTATES)
- #define ROTATIONAL_AXES 3
-#elif ENABLED(AXIS5_ROTATES)
- #define ROTATIONAL_AXES 2
-#elif ENABLED(AXIS4_ROTATES)
- #define ROTATIONAL_AXES 1
-#else
- #define ROTATIONAL_AXES 0
-#endif
-
-#if ROTATIONAL_AXES
- #define HAS_ROTATIONAL_AXES 1
-#endif
-
-/**
- * Number of Secondary Linear Axes (e.g., UVW)
- * All secondary axes for which AXIS*_ROTATES is not defined.
- * Excluding primary axes and excluding duplicate axes (X2, Y2, Z2, Z3, Z4)
- */
-#define SECONDARY_LINEAR_AXES (NUM_AXES - PRIMARY_LINEAR_AXES - ROTATIONAL_AXES)
-
-/**
- * Number of Logical Axes (e.g., XYZIJKUVWE)
- * All logical axes that can be commanded directly by G-code.
- * Delta maps stepper-specific values to ABC steppers.
- */
-#if HAS_EXTRUDERS
- #define LOGICAL_AXES INCREMENT(NUM_AXES)
-#else
- #define LOGICAL_AXES NUM_AXES
-#endif
-
-/**
- * DISTINCT_E_FACTORS is set to give extruders (some) individual settings.
- *
- * DISTINCT_AXES is the number of distinct addressable axes (not steppers).
- * Includes all linear axes plus all distinguished extruders.
- * The default behavior is to treat all extruders as a single E axis
- * with shared motion and temperature settings.
- *
- * DISTINCT_E is the number of distinguished extruders. By default this
- * will be 1 which indicates all extruders share the same settings.
- *
- * E_INDEX_N(E) should be used to get the E index of any item that might be
- * distinguished.
- */
-#if ENABLED(DISTINCT_E_FACTORS) && E_STEPPERS > 1
- #define DISTINCT_AXES (NUM_AXES + E_STEPPERS)
- #define DISTINCT_E E_STEPPERS
- #define E_INDEX_N(E) (E)
-#else
- #undef DISTINCT_E_FACTORS
- #define DISTINCT_AXES LOGICAL_AXES
- #define DISTINCT_E 1
- #define E_INDEX_N(E) 0
-#endif
-
-// Helper macros for extruder and hotend arrays
-#define _EXTRUDER_LOOP(E) for (int8_t E = 0; E < EXTRUDERS; E++)
-#define EXTRUDER_LOOP() _EXTRUDER_LOOP(e)
-#define _HOTEND_LOOP(H) for (int8_t H = 0; H < HOTENDS; H++)
-#define HOTEND_LOOP() _HOTEND_LOOP(e)
-
-#define ARRAY_BY_EXTRUDERS(V...) ARRAY_N(EXTRUDERS, V)
-#define ARRAY_BY_EXTRUDERS1(v1) ARRAY_N_1(EXTRUDERS, v1)
-#define ARRAY_BY_HOTENDS(V...) ARRAY_N(HOTENDS, V)
-#define ARRAY_BY_HOTENDS1(v1) ARRAY_N_1(HOTENDS, v1)
-
// Support for SD Card and other file storage
#if ENABLED(SDSUPPORT)
#define HAS_MEDIA 1
#endif
+//
+// Serial Port Info
+//
+#ifdef SERIAL_PORT_2
+ #define HAS_MULTI_SERIAL 1
+ #ifdef SERIAL_PORT_3
+ #define NUM_SERIAL 3
+ #else
+ #define NUM_SERIAL 2
+ #endif
+#elif defined(SERIAL_PORT)
+ #define NUM_SERIAL 1
+#else
+ #define NUM_SERIAL 0
+ #undef BAUD_RATE_GCODE
+#endif
+#if SERIAL_PORT == -1 || SERIAL_PORT_2 == -1 || SERIAL_PORT_3 == -1
+ #define HAS_USB_SERIAL 1
+#endif
+#ifdef RS485_SERIAL_PORT
+ #define HAS_RS485_SERIAL 1
+#endif
+#if SERIAL_PORT_2 == -2
+ #define HAS_ETHERNET 1
+#endif
+
/**
* Conditionals for the configured LCD / Controller
*/
@@ -1209,508 +646,8 @@
#if NONE(HAS_MARLINUI_U8GLIB, HAS_TFT_LVGL_UI, DGUS_LCD_UI_E3S1PRO)
#undef LCD_LANGUAGE
#endif
-
-/**
- * Disable unused SINGLENOZZLE sub-options
- */
-#if DISABLED(SINGLENOZZLE)
- #undef SINGLENOZZLE_STANDBY_TEMP
-#endif
-#if !ALL(HAS_FAN, SINGLENOZZLE)
- #undef SINGLENOZZLE_STANDBY_FAN
-#endif
-
-// No inactive extruders with SWITCHING_NOZZLE or Průša MMU1 or just 1 E stepper exists
-#if HAS_SWITCHING_NOZZLE || HAS_PRUSA_MMU1 || E_STEPPERS < 2
- #undef DISABLE_OTHER_EXTRUDERS
-#endif
-
-// Switching extruder has its own servo?
-#if ENABLED(SWITCHING_EXTRUDER) && (!HAS_SWITCHING_NOZZLE || SWITCHING_EXTRUDER_SERVO_NR != SWITCHING_NOZZLE_SERVO_NR)
- #define DO_SWITCH_EXTRUDER 1
-#endif
-
-/**
- * The BLTouch Probe emulates a servo probe
- * and uses "special" angles for its state.
- */
-#if ENABLED(BLTOUCH) && !defined(Z_PROBE_SERVO_NR)
- #define Z_PROBE_SERVO_NR 0
-#endif
-
-/**
- * Set a flag for a servo probe (or BLTouch)
- */
-#ifdef Z_PROBE_SERVO_NR
- #define HAS_Z_SERVO_PROBE 1
-#endif
-#if ANY(HAS_Z_SERVO_PROBE, SWITCHING_EXTRUDER, SWITCHING_NOZZLE)
- #define HAS_SERVO_ANGLES 1
-#endif
-#if !HAS_SERVO_ANGLES
- #undef EDITABLE_SERVO_ANGLES
-#endif
-
-/**
- * Set flags for any form of bed probe
- */
-#if ANY(TOUCH_MI_PROBE, Z_PROBE_ALLEN_KEY, HAS_Z_SERVO_PROBE, SOLENOID_PROBE, Z_PROBE_SLED, RACK_AND_PINION_PROBE, SENSORLESS_PROBING, MAGLEV4, MAG_MOUNTED_PROBE, BIQU_MICROPROBE_V1, BIQU_MICROPROBE_V2)
- #define HAS_STOWABLE_PROBE 1
-#endif
-#if ANY(HAS_STOWABLE_PROBE, FIX_MOUNTED_PROBE, BD_SENSOR, NOZZLE_AS_PROBE)
- #define HAS_BED_PROBE 1
-#endif
-
-// Probing tool change
-#if !HAS_MULTI_EXTRUDER
- #undef PROBING_TOOL
-#endif
-#if HAS_BED_PROBE && defined(PROBING_TOOL)
- #define DO_TOOLCHANGE_FOR_PROBING 1
-#endif
-
-/**
- * Fill in undefined Filament Sensor options
- */
-#if ENABLED(FILAMENT_RUNOUT_SENSOR)
- #if NUM_RUNOUT_SENSORS >= 1
- #ifndef FIL_RUNOUT1_STATE
- #define FIL_RUNOUT1_STATE FIL_RUNOUT_STATE
- #endif
- #ifndef FIL_RUNOUT1_PULLUP
- #define FIL_RUNOUT1_PULLUP FIL_RUNOUT_PULLUP
- #endif
- #ifndef FIL_RUNOUT1_PULLDOWN
- #define FIL_RUNOUT1_PULLDOWN FIL_RUNOUT_PULLDOWN
- #endif
- #endif
- #if NUM_RUNOUT_SENSORS >= 2
- #ifndef FIL_RUNOUT2_STATE
- #define FIL_RUNOUT2_STATE FIL_RUNOUT_STATE
- #endif
- #ifndef FIL_RUNOUT2_PULLUP
- #define FIL_RUNOUT2_PULLUP FIL_RUNOUT_PULLUP
- #endif
- #ifndef FIL_RUNOUT2_PULLDOWN
- #define FIL_RUNOUT2_PULLDOWN FIL_RUNOUT_PULLDOWN
- #endif
- #endif
- #if NUM_RUNOUT_SENSORS >= 3
- #ifndef FIL_RUNOUT3_STATE
- #define FIL_RUNOUT3_STATE FIL_RUNOUT_STATE
- #endif
- #ifndef FIL_RUNOUT3_PULLUP
- #define FIL_RUNOUT3_PULLUP FIL_RUNOUT_PULLUP
- #endif
- #ifndef FIL_RUNOUT3_PULLDOWN
- #define FIL_RUNOUT3_PULLDOWN FIL_RUNOUT_PULLDOWN
- #endif
- #endif
- #if NUM_RUNOUT_SENSORS >= 4
- #ifndef FIL_RUNOUT4_STATE
- #define FIL_RUNOUT4_STATE FIL_RUNOUT_STATE
- #endif
- #ifndef FIL_RUNOUT4_PULLUP
- #define FIL_RUNOUT4_PULLUP FIL_RUNOUT_PULLUP
- #endif
- #ifndef FIL_RUNOUT4_PULLDOWN
- #define FIL_RUNOUT4_PULLDOWN FIL_RUNOUT_PULLDOWN
- #endif
- #endif
- #if NUM_RUNOUT_SENSORS >= 5
- #ifndef FIL_RUNOUT5_STATE
- #define FIL_RUNOUT5_STATE FIL_RUNOUT_STATE
- #endif
- #ifndef FIL_RUNOUT5_PULLUP
- #define FIL_RUNOUT5_PULLUP FIL_RUNOUT_PULLUP
- #endif
- #ifndef FIL_RUNOUT5_PULLDOWN
- #define FIL_RUNOUT5_PULLDOWN FIL_RUNOUT_PULLDOWN
- #endif
- #endif
- #if NUM_RUNOUT_SENSORS >= 6
- #ifndef FIL_RUNOUT6_STATE
- #define FIL_RUNOUT6_STATE FIL_RUNOUT_STATE
- #endif
- #ifndef FIL_RUNOUT6_PULLUP
- #define FIL_RUNOUT6_PULLUP FIL_RUNOUT_PULLUP
- #endif
- #ifndef FIL_RUNOUT6_PULLDOWN
- #define FIL_RUNOUT6_PULLDOWN FIL_RUNOUT_PULLDOWN
- #endif
- #endif
- #if NUM_RUNOUT_SENSORS >= 7
- #ifndef FIL_RUNOUT7_STATE
- #define FIL_RUNOUT7_STATE FIL_RUNOUT_STATE
- #endif
- #ifndef FIL_RUNOUT7_PULLUP
- #define FIL_RUNOUT7_PULLUP FIL_RUNOUT_PULLUP
- #endif
- #ifndef FIL_RUNOUT7_PULLDOWN
- #define FIL_RUNOUT7_PULLDOWN FIL_RUNOUT_PULLDOWN
- #endif
- #endif
- #if NUM_RUNOUT_SENSORS >= 8
- #ifndef FIL_RUNOUT8_STATE
- #define FIL_RUNOUT8_STATE FIL_RUNOUT_STATE
- #endif
- #ifndef FIL_RUNOUT8_PULLUP
- #define FIL_RUNOUT8_PULLUP FIL_RUNOUT_PULLUP
- #endif
- #ifndef FIL_RUNOUT8_PULLDOWN
- #define FIL_RUNOUT8_PULLDOWN FIL_RUNOUT_PULLDOWN
- #endif
- #endif
-#endif // FILAMENT_RUNOUT_SENSOR
-
-#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
- #if NUM_MOTION_SENSORS >= 1
- #ifndef FIL_MOTION1_STATE
- #define FIL_MOTION1_STATE FIL_RUNOUT_STATE
- #endif
- #ifndef FIL_MOTION1_PULLUP
- #define FIL_MOTION1_PULLUP FIL_RUNOUT_PULLUP
- #endif
- #ifndef FIL_MOTION1_PULLDOWN
- #define FIL_MOTION1_PULLDOWN FIL_RUNOUT_PULLDOWN
- #endif
- #endif
- #if NUM_MOTION_SENSORS >= 2
- #ifndef FIL_MOTION2_STATE
- #define FIL_MOTION2_STATE FIL_RUNOUT_STATE
- #endif
- #ifndef FIL_MOTION2_PULLUP
- #define FIL_MOTION2_PULLUP FIL_RUNOUT_PULLUP
- #endif
- #ifndef FIL_MOTION2_PULLDOWN
- #define FIL_MOTION2_PULLDOWN FIL_RUNOUT_PULLDOWN
- #endif
- #endif
- #if NUM_MOTION_SENSORS >= 3
- #ifndef FIL_MOTION3_STATE
- #define FIL_MOTION3_STATE FIL_RUNOUT_STATE
- #endif
- #ifndef FIL_MOTION3_PULLUP
- #define FIL_MOTION3_PULLUP FIL_RUNOUT_PULLUP
- #endif
- #ifndef FIL_MOTION3_PULLDOWN
- #define FIL_MOTION3_PULLDOWN FIL_RUNOUT_PULLDOWN
- #endif
- #endif
- #if NUM_MOTION_SENSORS >= 4
- #ifndef FIL_MOTION4_STATE
- #define FIL_MOTION4_STATE FIL_RUNOUT_STATE
- #endif
- #ifndef FIL_MOTION4_PULLUP
- #define FIL_MOTION4_PULLUP FIL_RUNOUT_PULLUP
- #endif
- #ifndef FIL_MOTION4_PULLDOWN
- #define FIL_MOTION4_PULLDOWN FIL_RUNOUT_PULLDOWN
- #endif
- #endif
- #if NUM_MOTION_SENSORS >= 5
- #ifndef FIL_MOTION5_STATE
- #define FIL_MOTION5_STATE FIL_RUNOUT_STATE
- #endif
- #ifndef FIL_MOTION5_PULLUP
- #define FIL_MOTION5_PULLUP FIL_RUNOUT_PULLUP
- #endif
- #ifndef FIL_MOTION5_PULLDOWN
- #define FIL_MOTION5_PULLDOWN FIL_RUNOUT_PULLDOWN
- #endif
- #endif
- #if NUM_MOTION_SENSORS >= 6
- #ifndef FIL_MOTION6_STATE
- #define FIL_MOTION6_STATE FIL_RUNOUT_STATE
- #endif
- #ifndef FIL_MOTION6_PULLUP
- #define FIL_MOTION6_PULLUP FIL_RUNOUT_PULLUP
- #endif
- #ifndef FIL_MOTION6_PULLDOWN
- #define FIL_MOTION6_PULLDOWN FIL_RUNOUT_PULLDOWN
- #endif
- #endif
- #if NUM_MOTION_SENSORS >= 7
- #ifndef FIL_MOTION7_STATE
- #define FIL_MOTION7_STATE FIL_RUNOUT_STATE
- #endif
- #ifndef FIL_MOTION7_PULLUP
- #define FIL_MOTION7_PULLUP FIL_RUNOUT_PULLUP
- #endif
- #ifndef FIL_MOTION7_PULLDOWN
- #define FIL_MOTION7_PULLDOWN FIL_RUNOUT_PULLDOWN
- #endif
- #endif
- #if NUM_MOTION_SENSORS >= 8
- #ifndef FIL_MOTION8_STATE
- #define FIL_MOTION8_STATE FIL_RUNOUT_STATE
- #endif
- #ifndef FIL_MOTION8_PULLUP
- #define FIL_MOTION8_PULLUP FIL_RUNOUT_PULLUP
- #endif
- #ifndef FIL_MOTION8_PULLDOWN
- #define FILMOTION8_PULLDOWN FIL_RUNOUT_PULLDOWN
- #endif
- #endif
-#endif // FILAMENT_SWITCH_AND_MOTION
-
-// Homing to Min or Max
-#if HAS_X_AXIS
- #if X_HOME_DIR > 0
- #define X_HOME_TO_MAX 1
- #elif X_HOME_DIR < 0
- #define X_HOME_TO_MIN 1
- #endif
-#endif
-#if HAS_Y_AXIS
- #if Y_HOME_DIR > 0
- #define Y_HOME_TO_MAX 1
- #elif Y_HOME_DIR < 0
- #define Y_HOME_TO_MIN 1
- #endif
-#endif
-#if HAS_Z_AXIS
- #if Z_HOME_DIR > 0
- #define Z_HOME_TO_MAX 1
- #elif Z_HOME_DIR < 0
- #define Z_HOME_TO_MIN 1
- #endif
-#endif
-#if HAS_I_AXIS
- #if I_HOME_DIR > 0
- #define I_HOME_TO_MAX 1
- #elif I_HOME_DIR < 0
- #define I_HOME_TO_MIN 1
- #endif
-#endif
-#if HAS_J_AXIS
- #if J_HOME_DIR > 0
- #define J_HOME_TO_MAX 1
- #elif J_HOME_DIR < 0
- #define J_HOME_TO_MIN 1
- #endif
-#endif
-#if HAS_K_AXIS
- #if K_HOME_DIR > 0
- #define K_HOME_TO_MAX 1
- #elif K_HOME_DIR < 0
- #define K_HOME_TO_MIN 1
- #endif
-#endif
-#if HAS_U_AXIS
- #if U_HOME_DIR > 0
- #define U_HOME_TO_MAX 1
- #elif U_HOME_DIR < 0
- #define U_HOME_TO_MIN 1
- #endif
-#endif
-#if HAS_V_AXIS
- #if V_HOME_DIR > 0
- #define V_HOME_TO_MAX 1
- #elif V_HOME_DIR < 0
- #define V_HOME_TO_MIN 1
- #endif
-#endif
-#if HAS_W_AXIS
- #if W_HOME_DIR > 0
- #define W_HOME_TO_MAX 1
- #elif W_HOME_DIR < 0
- #define W_HOME_TO_MIN 1
- #endif
-#endif
-
-/**
- * Conditionals based on the type of Bed Probe
- */
-#if HAS_BED_PROBE
- #if ALL(DELTA, SENSORLESS_PROBING)
- #define HAS_DELTA_SENSORLESS_PROBING 1
- #else
- #define HAS_REAL_BED_PROBE 1
- #endif
- #if HAS_REAL_BED_PROBE && NONE(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, Z_SPI_SENSORLESS)
- #define NEED_Z_MIN_PROBE_PIN 1
- #endif
- #if Z_HOME_TO_MIN && (!NEED_Z_MIN_PROBE_PIN || ENABLED(USE_PROBE_FOR_Z_HOMING))
- #define HOMING_Z_WITH_PROBE 1
- #endif
- #if DISABLED(NOZZLE_AS_PROBE)
- #define HAS_PROBE_XY_OFFSET 1
- #endif
- #if ANY(Z_PROBE_ALLEN_KEY, MAG_MOUNTED_PROBE)
- #define PROBE_TRIGGERED_WHEN_STOWED_TEST 1 // Extra test for Allen Key Probe
- #endif
- #ifndef Z_PROBE_ERROR_TOLERANCE
- #define Z_PROBE_ERROR_TOLERANCE Z_CLEARANCE_MULTI_PROBE
- #endif
- #if MULTIPLE_PROBING > 1
- #if EXTRA_PROBING > 0
- #define TOTAL_PROBING (MULTIPLE_PROBING + EXTRA_PROBING)
- #else
- #define TOTAL_PROBING MULTIPLE_PROBING
- #endif
- #endif
-#else
- // Clear probe pin settings when no probe is selected
- #undef Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN
- #undef USE_PROBE_FOR_Z_HOMING
- #undef Z_MIN_PROBE_REPEATABILITY_TEST
- #undef HOMING_Z_WITH_PROBE
- #undef Z_CLEARANCE_MULTI_PROBE
- #undef Z_PROBE_ERROR_TOLERANCE
- #undef Z_AFTER_PROBING
- #undef Z_PROBE_LOW_POINT
- #undef MULTIPLE_PROBING
- #undef EXTRA_PROBING
- #undef PROBE_OFFSET_ZMIN
- #undef PROBE_OFFSET_ZMAX
- #undef PAUSE_BEFORE_DEPLOY_STOW
- #undef PAUSE_PROBE_DEPLOY_WHEN_TRIGGERED
- #undef PROBING_HEATERS_OFF
- #undef WAIT_FOR_BED_HEATER
- #undef WAIT_FOR_HOTEND
- #undef PROBING_FANS_OFF
- #undef PROBING_ESTEPPERS_OFF
- #undef PROBING_STEPPERS_OFF
- #undef DELAY_BEFORE_PROBING
- #undef PREHEAT_BEFORE_PROBING
- #undef PROBING_NOZZLE_TEMP
- #undef PROBING_BED_TEMP
- #undef NOZZLE_TO_PROBE_OFFSET
-#endif
-
-#if ENABLED(BELTPRINTER) && !defined(HOME_Y_BEFORE_X)
- #define HOME_Y_BEFORE_X
-#endif
-
-#if Z_HOME_TO_MAX && DISABLED(Z_SAFE_HOMING)
- #define HOME_Z_FIRST // If homing away from BED do Z first
-#endif
-
-/**
- * Conditionals based on the type of Bed Leveling
- */
-#if ENABLED(AUTO_BED_LEVELING_UBL)
- #undef LCD_BED_LEVELING
- #if ANY(DELTA, SEGMENT_LEVELED_MOVES)
- #define UBL_SEGMENTED 1
- #endif
-#endif
-#if ANY(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT)
- #define ABL_PLANAR 1
-#endif
-#if ANY(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR)
- #define ABL_USES_GRID 1
-#endif
-#if ANY(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_3POINT)
- #define HAS_ABL_NOT_UBL 1
-#endif
-#if ANY(AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_UBL, MESH_BED_LEVELING)
- #define HAS_MESH 1
-#endif
-#if ANY(AUTO_BED_LEVELING_UBL, AUTO_BED_LEVELING_3POINT)
- #define NEEDS_THREE_PROBE_POINTS 1
-#endif
-#if ANY(HAS_ABL_NOT_UBL, AUTO_BED_LEVELING_UBL)
- #define HAS_ABL_OR_UBL 1
- #if DISABLED(PROBE_MANUALLY)
- #define HAS_AUTOLEVEL 1
- #endif
-#endif
-#if ANY(HAS_ABL_OR_UBL, MESH_BED_LEVELING)
- #define HAS_LEVELING 1
- #if DISABLED(AUTO_BED_LEVELING_UBL)
- #define PLANNER_LEVELING 1
- #endif
-#endif
-#if !HAS_LEVELING
- #undef RESTORE_LEVELING_AFTER_G28
- #undef ENABLE_LEVELING_AFTER_G28
- #undef G29_RETRY_AND_RECOVER
-#endif
-#if !HAS_LEVELING || ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL)
- #undef PROBE_MANUALLY
-#endif
-#if ANY(HAS_BED_PROBE, PROBE_MANUALLY, MESH_BED_LEVELING)
- #define PROBE_SELECTED 1
-#endif
-
-#if !HAS_MESH
- #undef MESH_INSET
-#endif
-
-#if NONE(PROBE_SELECTED, AUTO_BED_LEVELING_UBL)
- #undef Z_CLEARANCE_BETWEEN_PROBES
-#endif
-
-#if NONE(PROBE_SELECTED, DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
- #undef PROBING_MARGIN
- #undef PROBING_MARGIN_LEFT
- #undef PROBING_MARGIN_RIGHT
- #undef PROBING_MARGIN_FRONT
- #undef PROBING_MARGIN_BACK
- #undef XY_PROBE_FEEDRATE
-#endif
-
-#if !(ANY(HAS_BED_PROBE, HAS_LEVELING) || ALL(AUTO_BED_LEVELING_UBL, HAS_MARLINUI_MENU))
- #undef Z_CLEARANCE_DEPLOY_PROBE
-#endif
-
-#if !(ANY(HAS_BED_PROBE, BACKLASH_GCODE) || (ENABLED(EXTENSIBLE_UI) && ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL)))
- #undef Z_PROBE_FEEDRATE_FAST
- #undef Z_PROBE_FEEDRATE_SLOW
-#endif
-
-/**
- * Z_CLEARANCE_FOR_HOMING
- */
-#ifndef Z_CLEARANCE_FOR_HOMING
- #ifdef Z_CLEARANCE_BETWEEN_PROBES
- #define Z_CLEARANCE_FOR_HOMING Z_CLEARANCE_BETWEEN_PROBES
- #else
- #define Z_CLEARANCE_FOR_HOMING 5
- #endif
-#endif
-
-/**
- * Z_CLEARANCE_BETWEEN_PROBES
- */
-#if PROBE_SELECTED || (HAS_MARLINUI_MENU && ANY(DELTA_CALIBRATION_MENU, DELTA_AUTO_CALIBRATION))
- #ifndef Z_CLEARANCE_BETWEEN_PROBES
- #define Z_CLEARANCE_BETWEEN_PROBES Z_CLEARANCE_FOR_HOMING
- #endif
-#endif
-
-/**
- * Z_CLEARANCE_BETWEEN_MANUAL_PROBES / Z_CLEARANCE_MULTI_PROBE
- */
-#if PROBE_SELECTED
- #if ANY(MESH_BED_LEVELING, PROBE_MANUALLY)
- #if Z_CLEARANCE_BETWEEN_PROBES > Z_CLEARANCE_FOR_HOMING
- #define Z_CLEARANCE_BETWEEN_MANUAL_PROBES Z_CLEARANCE_BETWEEN_PROBES
- #else
- #define Z_CLEARANCE_BETWEEN_MANUAL_PROBES Z_CLEARANCE_FOR_HOMING
- #endif
- #endif
- #ifndef Z_CLEARANCE_MULTI_PROBE
- #ifdef Z_CLEARANCE_BETWEEN_PROBES
- #define Z_CLEARANCE_MULTI_PROBE Z_CLEARANCE_BETWEEN_PROBES
- #else
- #define Z_CLEARANCE_MULTI_PROBE 5
- #endif
- #endif
-#endif
-#if TOTAL_PROBING < 2
- #undef Z_CLEARANCE_MULTI_PROBE
-#endif
-
-#if DISABLED(ENABLE_LEVELING_FADE_HEIGHT)
- #undef DEFAULT_LEVELING_FADE_HEIGHT
-#endif
-
-#ifdef GRID_MAX_POINTS_X
- #define GRID_MAX_POINTS ((GRID_MAX_POINTS_X) * (GRID_MAX_POINTS_Y))
- #define GRID_LOOP(A,B) for (uint8_t A = 0; A < GRID_MAX_POINTS_X; ++A) for (uint8_t B = 0; B < GRID_MAX_POINTS_Y; ++B)
+#if DISABLED(MPC_AUTOTUNE)
+ #undef MPC_AUTOTUNE_MENU
#endif
// Slim menu optimizations
@@ -1726,99 +663,6 @@
#define HAS_FEEDRATE_EDIT 1
#endif
-/**
- * CoreXY, CoreXZ, and CoreYZ - and their reverse
- */
-#if ANY(COREXY, COREYX)
- #define CORE_IS_XY 1
-#endif
-#if ANY(COREXZ, COREZX)
- #define CORE_IS_XZ 1
-#endif
-#if ANY(COREYZ, COREZY)
- #define CORE_IS_YZ 1
-#endif
-#if CORE_IS_XY || CORE_IS_XZ || CORE_IS_YZ
- #define IS_CORE 1
- #if CORE_IS_XY
- #define CORE_AXIS_1 A_AXIS
- #define CORE_AXIS_2 B_AXIS
- #define NORMAL_AXIS Z_AXIS
- #elif CORE_IS_XZ
- #define CORE_AXIS_1 A_AXIS
- #define NORMAL_AXIS Y_AXIS
- #define CORE_AXIS_2 C_AXIS
- #elif CORE_IS_YZ
- #define NORMAL_AXIS X_AXIS
- #define CORE_AXIS_1 B_AXIS
- #define CORE_AXIS_2 C_AXIS
- #endif
- #define CORESIGN(n) (ANY(COREYX, COREZX, COREZY) ? (-(n)) : (n))
-#elif ANY(MARKFORGED_XY, MARKFORGED_YX)
- // Markforged kinematics
- #define CORE_AXIS_1 A_AXIS
- #define CORE_AXIS_2 B_AXIS
- #define NORMAL_AXIS Z_AXIS
-#endif
-
-#if ANY(MORGAN_SCARA, MP_SCARA, AXEL_TPARA)
- #define IS_SCARA 1
- #define IS_KINEMATIC 1
-#elif ANY(DELTA, POLARGRAPH, POLAR)
- #define IS_KINEMATIC 1
-#else
- #define IS_CARTESIAN 1
- #if !IS_CORE
- #define IS_FULL_CARTESIAN 1
- #endif
-#endif
-
-#if DISABLED(DELTA)
- #undef DELTA_HOME_TO_SAFE_ZONE
-#endif
-
-//
-// Serial Port Info
-//
-#ifdef SERIAL_PORT_2
- #define HAS_MULTI_SERIAL 1
- #ifdef SERIAL_PORT_3
- #define NUM_SERIAL 3
- #else
- #define NUM_SERIAL 2
- #endif
-#elif defined(SERIAL_PORT)
- #define NUM_SERIAL 1
-#else
- #define NUM_SERIAL 0
- #undef BAUD_RATE_GCODE
-#endif
-#if SERIAL_PORT == -1 || SERIAL_PORT_2 == -1 || SERIAL_PORT_3 == -1
- #define HAS_USB_SERIAL 1
-#endif
-#ifdef RS485_SERIAL_PORT
- #define HAS_RS485_SERIAL 1
-#endif
-#if SERIAL_PORT_2 == -2
- #define HAS_ETHERNET 1
-#endif
-
-/**
- * This setting is also used by M109 when trying to calculate
- * a ballpark safe margin to prevent wait-forever situation.
- */
-#ifndef EXTRUDE_MINTEMP
- #define EXTRUDE_MINTEMP 170
-#endif
-
-#if ANY(PID_DEBUG, PID_BED_DEBUG, PID_CHAMBER_DEBUG)
- #define HAS_PID_DEBUG 1
-#endif
-
-#if DISABLED(MPC_AUTOTUNE)
- #undef MPC_AUTOTUNE_MENU
-#endif
-
/**
* TFT Displays
*
@@ -2031,7 +875,3 @@
#if LED_POWEROFF_TIMEOUT > 0
#define HAS_LED_POWEROFF_TIMEOUT 1
#endif
-
-#if ALL(SPI_FLASH, HAS_MEDIA, MARLIN_DEV_MODE)
- #define SPI_FLASH_BACKUP 1
-#endif
diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h
index 4675051c5f..234f146e7b 100644
--- a/Marlin/src/inc/Conditionals_adv.h
+++ b/Marlin/src/inc/Conditionals_adv.h
@@ -108,7 +108,6 @@
//#define LCD_SHOW_E_TOTAL
#define NO_WORKSPACE_OFFSETS
#define NO_HOME_OFFSETS
- #undef AUTOTEMP
#undef CALIBRATION_MEASURE_LEFT
#undef CALIBRATION_MEASURE_RIGHT
#undef CALIBRATION_MEASURE_XMAX
@@ -295,17 +294,9 @@
#undef HEATER_1_MAXTEMP
#undef HEATER_1_MINTEMP
#if HOTENDS < 1
- #undef AUTOTEMP
#undef E0_AUTO_FAN_PIN
#undef HEATER_0_MAXTEMP
#undef HEATER_0_MINTEMP
- #undef PID_PARAMS_PER_HOTEND
- #undef PIDTEMP
- #undef MPCTEMP
- #undef PREVENT_COLD_EXTRUSION
- #undef THERMAL_PROTECTION_HOTENDS
- #undef THERMAL_PROTECTION_PERIOD
- #undef WATCH_TEMP_PERIOD
#endif
#endif
#endif
@@ -825,44 +816,50 @@
#undef TEMP_SENSOR_AD8495_OFFSET
#endif
-#if !HAS_HOTEND
+#if !ALL(HAS_X_AXIS, HAS_HOTEND)
+ #undef AUTOTEMP
+#endif
+#if DISABLED(THERMAL_PROTECTION_HOTENDS)
#undef THERMAL_PROTECTION_PERIOD
#undef THERMAL_PROTECTION_HYSTERESIS
#undef WATCH_TEMP_PERIOD
#undef WATCH_TEMP_INCREASE
- #undef ADAPTIVE_FAN_SLOWING
- #undef REPORT_ADAPTIVE_FAN_SLOWING
- #undef TEMP_TUNING_MAINTAIN_FAN
+#endif
+#if !ALL(HAS_HOTEND, PIDTEMP)
+ #undef PID_PARAMS_PER_HOTEND
#endif
#if !TEMP_SENSOR_BED
- #undef THERMAL_PROTECTION_BED
+ #undef BED_MINTEMP
+ #undef BED_MAXTEMP
+#endif
+#if DISABLED(THERMAL_PROTECTION_BED)
#undef THERMAL_PROTECTION_BED_PERIOD
#undef THERMAL_PROTECTION_BED_HYSTERESIS
#undef WATCH_BED_TEMP_PERIOD
#undef WATCH_BED_TEMP_INCREASE
- #undef BED_MINTEMP
- #undef BED_MAXTEMP
#endif
#if !TEMP_SENSOR_CHAMBER
- #undef THERMAL_PROTECTION_CHAMBER
+ #undef CHAMBER_MINTEMP
+ #undef CHAMBER_MAXTEMP
+#endif
+#if DISABLED(THERMAL_PROTECTION_CHAMBER)
#undef THERMAL_PROTECTION_CHAMBER_PERIOD
#undef THERMAL_PROTECTION_CHAMBER_HYSTERESIS
#undef WATCH_CHAMBER_TEMP_PERIOD
#undef WATCH_CHAMBER_TEMP_INCREASE
- #undef CHAMBER_MINTEMP
- #undef CHAMBER_MAXTEMP
#endif
#if !TEMP_SENSOR_COOLER
- #undef THERMAL_PROTECTION_COOLER
+ #undef COOLER_MINTEMP
+ #undef COOLER_MAXTEMP
+#endif
+#if DISABLED(THERMAL_PROTECTION_COOLER)
#undef THERMAL_PROTECTION_COOLER_PERIOD
#undef THERMAL_PROTECTION_COOLER_HYSTERESIS
#undef WATCH_COOLER_TEMP_PERIOD
#undef WATCH_COOLER_TEMP_INCREASE
- #undef COOLER_MINTEMP
- #undef COOLER_MAXTEMP
#endif
#if HAS_MULTI_EXTRUDER || HAS_MULTI_HOTEND || HAS_PRUSA_MMU2 || HAS_PRUSA_MMU3 || (ENABLED(MIXING_EXTRUDER) && MIXING_VIRTUAL_TOOLS > 1)
@@ -1406,31 +1403,6 @@
#endif
#endif
-// Toolchange Event G-code
-#if !HAS_MULTI_EXTRUDER || !(defined(EVENT_GCODE_TOOLCHANGE_T0) || defined(EVENT_GCODE_TOOLCHANGE_T1) || defined(EVENT_GCODE_TOOLCHANGE_T2) || defined(EVENT_GCODE_TOOLCHANGE_T3) || defined(EVENT_GCODE_TOOLCHANGE_T4) || defined(EVENT_GCODE_TOOLCHANGE_T5) || defined(EVENT_GCODE_TOOLCHANGE_T6) || defined(EVENT_GCODE_TOOLCHANGE_T7))
- #undef TC_GCODE_USE_GLOBAL_X
- #undef TC_GCODE_USE_GLOBAL_Y
- #undef TC_GCODE_USE_GLOBAL_Z
-#endif
-
-// TOOLCHANGE_MIGRATION_FEATURE - Clean up after sloppy auto config
-#if DISABLED(TOOLCHANGE_MIGRATION_FEATURE)
- #undef MIGRATION_ZRAISE
- #undef MIGRATION_FS_EXTRA_PRIME
- #undef MIGRATION_FS_WIPE_RETRACT
- #undef MIGRATION_FS_FAN_SPEED
- #undef MIGRATION_FS_FAN_TIME
- #undef TOOLCHANGE_MIGRATION_DO_PARK
-#endif
-// TOOLCHANGE_PARK - Clean up after sloppy auto config
-#if DISABLED(TOOLCHANGE_PARK)
- #undef TOOLCHANGE_PARK_XY
- #undef TOOLCHANGE_PARK_XY_FEEDRATE
- #undef TOOLCHANGE_PARK_X_ONLY
- #undef TOOLCHANGE_PARK_Y_ONLY
- #undef TOOLCHANGE_MIGRATION_DO_PARK
-#endif
-
// Multi-Stepping Limit
#ifndef MULTISTEPPING_LIMIT
#define MULTISTEPPING_LIMIT 128
@@ -1442,16 +1414,6 @@
#define NUM_REDUNDANT_FANS 1
#endif
-// Clean up if only mm units are used
-#if DISABLED(INCH_MODE_SUPPORT)
- #undef MANUAL_MOVE_DISTANCE_IN
-#endif
-
-// Clean up if no rotational axes exist
-#if !HAS_ROTATIONAL_AXES
- #undef MANUAL_MOVE_DISTANCE_DEG
-#endif
-
// Power-Loss Recovery
#if ENABLED(POWER_LOSS_RECOVERY)
#ifdef PLR_BED_THRESHOLD
@@ -1461,3 +1423,39 @@
#define HAS_PLR_UI_FLAG 1 // recovery.ui_flag_resume
#endif
#endif
+
+// Toolchange Event G-code
+#if !HAS_MULTI_EXTRUDER || !(defined(EVENT_GCODE_TOOLCHANGE_T0) || defined(EVENT_GCODE_TOOLCHANGE_T1) || defined(EVENT_GCODE_TOOLCHANGE_T2) || defined(EVENT_GCODE_TOOLCHANGE_T3) || defined(EVENT_GCODE_TOOLCHANGE_T4) || defined(EVENT_GCODE_TOOLCHANGE_T5) || defined(EVENT_GCODE_TOOLCHANGE_T6) || defined(EVENT_GCODE_TOOLCHANGE_T7))
+ #undef TC_GCODE_USE_GLOBAL_X
+ #undef TC_GCODE_USE_GLOBAL_Y
+ #undef TC_GCODE_USE_GLOBAL_Z
+#endif
+
+// Clean up for TOOLCHANGE_MIGRATION_FEATURE
+#if DISABLED(TOOLCHANGE_MIGRATION_FEATURE)
+ #undef MIGRATION_ZRAISE
+ #undef MIGRATION_FS_EXTRA_PRIME
+ #undef MIGRATION_FS_WIPE_RETRACT
+ #undef MIGRATION_FS_FAN_SPEED
+ #undef MIGRATION_FS_FAN_TIME
+ #undef TOOLCHANGE_MIGRATION_DO_PARK
+#endif
+
+// Clean up for TOOLCHANGE_PARK
+#if DISABLED(TOOLCHANGE_PARK)
+ #undef TOOLCHANGE_PARK_XY
+ #undef TOOLCHANGE_PARK_XY_FEEDRATE
+ #undef TOOLCHANGE_PARK_X_ONLY
+ #undef TOOLCHANGE_PARK_Y_ONLY
+ #undef TOOLCHANGE_MIGRATION_DO_PARK
+#endif
+
+// Clean up if only mm units are used
+#if DISABLED(INCH_MODE_SUPPORT)
+ #undef MANUAL_MOVE_DISTANCE_IN
+#endif
+
+// Clean up if no rotational axes exist
+#if !HAS_ROTATIONAL_AXES
+ #undef MANUAL_MOVE_DISTANCE_DEG
+#endif
diff --git a/Marlin/src/inc/Conditionals_axes.h b/Marlin/src/inc/Conditionals_axes.h
new file mode 100644
index 0000000000..5a79d2f3eb
--- /dev/null
+++ b/Marlin/src/inc/Conditionals_axes.h
@@ -0,0 +1,698 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+/**
+ * Conditionals_axes.h
+ * Conditionals that need to be set before Configuration_adv.h or pins.h
+ */
+
+/**
+ * Extruders have some combination of stepper motors and hotends
+ * so we separate these concepts into the defines:
+ *
+ * EXTRUDERS - Number of Selectable Tools
+ * HOTENDS - Number of hotends, whether connected or separate
+ * E_STEPPERS - Number of actual E stepper motors
+ * E_MANUAL - Number of E steppers for LCD move options
+ *
+ * These defines must be simple constants for use in REPEAT, etc.
+ */
+#if EXTRUDERS
+ #define HAS_EXTRUDERS 1
+ #if EXTRUDERS > 1
+ #define HAS_MULTI_EXTRUDER 1
+ #endif
+ #define E_AXIS_N(E) AxisEnum(E_AXIS + E_INDEX_N(E))
+#else
+ #undef EXTRUDERS
+ #define EXTRUDERS 0
+#endif
+
+#define E_OPTARG(N) OPTARG(HAS_MULTI_EXTRUDER, N)
+#define E_TERN_(N) TERN_(HAS_MULTI_EXTRUDER, N)
+#define E_TERN0(N) TERN0(HAS_MULTI_EXTRUDER, N)
+
+#if ANY(SWITCHING_EXTRUDER, MECHANICAL_SWITCHING_EXTRUDER)
+ #define HAS_SWITCHING_EXTRUDER 1
+#endif
+#if ANY(SWITCHING_NOZZLE, MECHANICAL_SWITCHING_NOZZLE)
+ #define HAS_SWITCHING_NOZZLE 1
+#endif
+
+/**
+ * Multi-Material-Unit supported models
+ */
+#ifdef MMU_MODEL
+ #define HAS_MMU 1
+ #define SINGLENOZZLE
+
+ #define _PRUSA_MMU1 1
+ #define _PRUSA_MMU2 2
+ #define _PRUSA_MMU2S 3
+ #define _PRUSA_MMU3 4
+ #define _EXTENDABLE_EMU_MMU2 12
+ #define _EXTENDABLE_EMU_MMU2S 13
+ #define _EXTENDABLE_EMU_MMU3 14
+ #define _MMU CAT(_,MMU_MODEL)
+
+ #if _MMU == _PRUSA_MMU1
+ #define HAS_PRUSA_MMU1 1
+ #elif _MMU % 10 == _PRUSA_MMU2
+ #define HAS_PRUSA_MMU2 1
+ #elif _MMU % 10 == _PRUSA_MMU2S
+ #define HAS_PRUSA_MMU2 1
+ #define HAS_PRUSA_MMU2S 1
+ #elif _MMU % 10 == _PRUSA_MMU3
+ #define HAS_PRUSA_MMU3 1
+ #endif
+ #if _MMU == _EXTENDABLE_EMU_MMU2 || _MMU == _EXTENDABLE_EMU_MMU2S
+ #define HAS_EXTENDABLE_MMU 1
+ #endif
+
+ #undef _MMU
+ #undef _PRUSA_MMU1
+ #undef _PRUSA_MMU2
+ #undef _PRUSA_MMU2S
+ #undef _PRUSA_MMU3
+ #undef _EXTENDABLE_EMU_MMU2
+ #undef _EXTENDABLE_EMU_MMU2S
+ #undef _EXTENDABLE_EMU_MMU3
+#endif
+
+#if ENABLED(E_DUAL_STEPPER_DRIVERS) // E0/E1 steppers act in tandem as E0
+
+ #define E_STEPPERS 2
+ #define E_MANUAL 1
+
+#elif HAS_SWITCHING_EXTRUDER // One stepper for every two EXTRUDERS
+
+ #if EXTRUDERS > 4
+ #define E_STEPPERS 3
+ #elif EXTRUDERS > 2
+ #define E_STEPPERS 2
+ #else
+ #define E_STEPPERS 1
+ #endif
+
+#elif ENABLED(MIXING_EXTRUDER) // Multiple feeds are mixed proportionally
+
+ #define E_STEPPERS MIXING_STEPPERS
+ #define E_MANUAL 1
+ #if MIXING_STEPPERS == 2
+ #define HAS_DUAL_MIXING 1
+ #endif
+ #ifndef MIXING_VIRTUAL_TOOLS
+ #define MIXING_VIRTUAL_TOOLS 1
+ #endif
+
+#elif ENABLED(SWITCHING_TOOLHEAD) // Toolchanger
+
+ #define E_STEPPERS EXTRUDERS
+ #define E_MANUAL EXTRUDERS
+
+#elif HAS_PRUSA_MMU2 || HAS_PRUSA_MMU3 // Průša Multi-Material Unit v2/v3
+
+ #define E_STEPPERS 1
+ #define E_MANUAL 1
+
+#endif
+
+// Default E steppers / manual motion is one per extruder
+#ifndef E_STEPPERS
+ #define E_STEPPERS EXTRUDERS
+#endif
+#ifndef E_MANUAL
+ #define E_MANUAL EXTRUDERS
+#endif
+
+// Number of hotends...
+#if ANY(SINGLENOZZLE, MIXING_EXTRUDER) // Only one for singlenozzle or mixing extruder
+ #define HOTENDS 1
+#elif HAS_SWITCHING_EXTRUDER && !HAS_SWITCHING_NOZZLE // One for each pair of abstract "extruders"
+ #define HOTENDS E_STEPPERS
+#elif TEMP_SENSOR_0
+ #define HOTENDS EXTRUDERS // One per extruder if at least one heater exists
+#else
+ #define HOTENDS 0 // A machine with no hotends at all can still extrude
+#endif
+
+// At least one hotend...
+#if HOTENDS
+ #define HAS_HOTEND 1
+ #ifndef HOTEND_OVERSHOOT
+ #define HOTEND_OVERSHOOT 15
+ #endif
+#endif
+
+// More than one hotend...
+#if HOTENDS > 1
+ #define HAS_MULTI_HOTEND 1
+ #define HAS_HOTEND_OFFSET 1
+ #ifndef HOTEND_OFFSET_X
+ #define HOTEND_OFFSET_X { 0 } // X offsets for each extruder
+ #endif
+ #ifndef HOTEND_OFFSET_Y
+ #define HOTEND_OFFSET_Y { 0 } // Y offsets for each extruder
+ #endif
+ #ifndef HOTEND_OFFSET_Z
+ #define HOTEND_OFFSET_Z { 0 } // Z offsets for each extruder
+ #endif
+#endif
+
+/**
+ * Number of Linear Axes (e.g., XYZIJKUVW)
+ * All the logical axes except for the tool (E) axis
+ */
+#ifdef NUM_AXES
+ #undef NUM_AXES
+ #define NUM_AXES_WARNING 1
+#endif
+
+#ifdef W_DRIVER_TYPE
+ #define NUM_AXES 9
+#elif defined(V_DRIVER_TYPE)
+ #define NUM_AXES 8
+#elif defined(U_DRIVER_TYPE)
+ #define NUM_AXES 7
+#elif defined(K_DRIVER_TYPE)
+ #define NUM_AXES 6
+#elif defined(J_DRIVER_TYPE)
+ #define NUM_AXES 5
+#elif defined(I_DRIVER_TYPE)
+ #define NUM_AXES 4
+#elif defined(Z_DRIVER_TYPE)
+ #define NUM_AXES 3
+#elif defined(Y_DRIVER_TYPE)
+ #define NUM_AXES 2
+#elif defined(X_DRIVER_TYPE)
+ #define NUM_AXES 1
+#else
+ #define NUM_AXES 0
+#endif
+#if NUM_AXES >= 1
+ #define HAS_X_AXIS 1
+ #define HAS_A_AXIS 1
+ #if NUM_AXES >= XY
+ #define HAS_Y_AXIS 1
+ #define HAS_B_AXIS 1
+ #if NUM_AXES >= XYZ
+ #define HAS_Z_AXIS 1
+ #define HAS_C_AXIS 1
+ #if NUM_AXES >= 4
+ #define HAS_I_AXIS 1
+ #if NUM_AXES >= 5
+ #define HAS_J_AXIS 1
+ #if NUM_AXES >= 6
+ #define HAS_K_AXIS 1
+ #if NUM_AXES >= 7
+ #define HAS_U_AXIS 1
+ #if NUM_AXES >= 8
+ #define HAS_V_AXIS 1
+ #if NUM_AXES >= 9
+ #define HAS_W_AXIS 1
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+#endif
+
+#if HAS_Z_AXIS
+ #ifdef Z4_DRIVER_TYPE
+ #define NUM_Z_STEPPERS 4
+ #elif defined(Z3_DRIVER_TYPE)
+ #define NUM_Z_STEPPERS 3
+ #elif defined(Z2_DRIVER_TYPE)
+ #define NUM_Z_STEPPERS 2
+ #else
+ #define NUM_Z_STEPPERS 1
+ #endif
+#endif
+
+#if !HAS_X_AXIS
+ #undef AVOID_OBSTACLES
+ #undef X2_DRIVER_TYPE
+ #undef X_ENABLE_ON
+ #undef DISABLE_X
+ #undef INVERT_X_DIR
+ #undef X_HOME_DIR
+ #undef X_MIN_POS
+ #undef X_MAX_POS
+ #undef MANUAL_X_HOME_POS
+ #undef MIN_SOFTWARE_ENDSTOPS
+ #undef MAX_SOFTWARE_ENDSTOPS
+ #undef MIN_SOFTWARE_ENDSTOP_X
+ #undef MAX_SOFTWARE_ENDSTOP_X
+#endif
+
+#if !HAS_Y_AXIS
+ #undef AVOID_OBSTACLES
+ #undef Y2_DRIVER_TYPE
+ #undef Y_ENABLE_ON
+ #undef DISABLE_Y
+ #undef INVERT_Y_DIR
+ #undef Y_HOME_DIR
+ #undef Y_MIN_POS
+ #undef Y_MAX_POS
+ #undef MANUAL_Y_HOME_POS
+ #undef MIN_SOFTWARE_ENDSTOP_Y
+ #undef MAX_SOFTWARE_ENDSTOP_Y
+#endif
+
+#if !HAS_Z_AXIS
+ #undef Z2_DRIVER_TYPE
+ #undef Z3_DRIVER_TYPE
+ #undef Z4_DRIVER_TYPE
+ #undef Z_ENABLE_ON
+ #undef DISABLE_Z
+ #undef INVERT_Z_DIR
+ #undef Z_HOME_DIR
+ #undef Z_MIN_POS
+ #undef Z_MAX_POS
+ #undef MANUAL_Z_HOME_POS
+ #undef Z_SAFE_HOMING
+ #undef MIN_SOFTWARE_ENDSTOP_Z
+ #undef MAX_SOFTWARE_ENDSTOP_Z
+#endif
+
+#if !HAS_I_AXIS
+ #undef I_ENABLE_ON
+ #undef DISABLE_I
+ #undef INVERT_I_DIR
+ #undef I_HOME_DIR
+ #undef I_MIN_POS
+ #undef I_MAX_POS
+ #undef MANUAL_I_HOME_POS
+ #undef MIN_SOFTWARE_ENDSTOP_I
+ #undef MAX_SOFTWARE_ENDSTOP_I
+#endif
+
+#if !HAS_J_AXIS
+ #undef J_ENABLE_ON
+ #undef DISABLE_J
+ #undef INVERT_J_DIR
+ #undef J_HOME_DIR
+ #undef J_MIN_POS
+ #undef J_MAX_POS
+ #undef MANUAL_J_HOME_POS
+ #undef MIN_SOFTWARE_ENDSTOP_J
+ #undef MAX_SOFTWARE_ENDSTOP_J
+#endif
+
+#if !HAS_K_AXIS
+ #undef K_ENABLE_ON
+ #undef DISABLE_K
+ #undef INVERT_K_DIR
+ #undef K_HOME_DIR
+ #undef K_MIN_POS
+ #undef K_MAX_POS
+ #undef MANUAL_K_HOME_POS
+ #undef MIN_SOFTWARE_ENDSTOP_K
+ #undef MAX_SOFTWARE_ENDSTOP_K
+#endif
+
+#if !HAS_U_AXIS
+ #undef U_ENABLE_ON
+ #undef DISABLE_U
+ #undef INVERT_U_DIR
+ #undef U_HOME_DIR
+ #undef U_MIN_POS
+ #undef U_MAX_POS
+ #undef MANUAL_U_HOME_POS
+ #undef MIN_SOFTWARE_ENDSTOP_U
+ #undef MAX_SOFTWARE_ENDSTOP_U
+#endif
+
+#if !HAS_V_AXIS
+ #undef V_ENABLE_ON
+ #undef DISABLE_V
+ #undef INVERT_V_DIR
+ #undef V_HOME_DIR
+ #undef V_MIN_POS
+ #undef V_MAX_POS
+ #undef MANUAL_V_HOME_POS
+ #undef MIN_SOFTWARE_ENDSTOP_V
+ #undef MAX_SOFTWARE_ENDSTOP_V
+#endif
+
+#if !HAS_W_AXIS
+ #undef W_ENABLE_ON
+ #undef DISABLE_W
+ #undef INVERT_W_DIR
+ #undef W_HOME_DIR
+ #undef W_MIN_POS
+ #undef W_MAX_POS
+ #undef MANUAL_W_HOME_POS
+ #undef MIN_SOFTWARE_ENDSTOP_W
+ #undef MAX_SOFTWARE_ENDSTOP_W
+#endif
+
+// Clean up E-stepper-based settings...
+#if E_STEPPERS <= 7
+ #undef INVERT_E7_DIR
+ #undef E7_DRIVER_TYPE
+ #if E_STEPPERS <= 6
+ #undef INVERT_E6_DIR
+ #undef E6_DRIVER_TYPE
+ #if E_STEPPERS <= 5
+ #undef INVERT_E5_DIR
+ #undef E5_DRIVER_TYPE
+ #if E_STEPPERS <= 4
+ #undef INVERT_E4_DIR
+ #undef E4_DRIVER_TYPE
+ #if E_STEPPERS <= 3
+ #undef INVERT_E3_DIR
+ #undef E3_DRIVER_TYPE
+ #if E_STEPPERS <= 2
+ #undef INVERT_E2_DIR
+ #undef E2_DRIVER_TYPE
+ #if E_STEPPERS <= 1
+ #undef INVERT_E1_DIR
+ #undef E1_DRIVER_TYPE
+ #if E_STEPPERS == 0
+ #undef INVERT_E0_DIR
+ #undef E0_DRIVER_TYPE
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+#endif
+
+#define _OR_HAS_DA(A) ENABLED(DISABLE_##A) ||
+#if MAP(_OR_HAS_DA, X, Y, Z, I, J, K, U, V, W) 0
+ #define HAS_DISABLE_MAIN_AXES 1
+#endif
+#if HAS_DISABLE_MAIN_AXES || ENABLED(DISABLE_E)
+ #define HAS_DISABLE_AXES 1
+#endif
+#undef _OR_HAS_DA
+
+#ifdef X2_DRIVER_TYPE
+ #define HAS_X2_STEPPER 1
+#endif
+#ifdef Y2_DRIVER_TYPE
+ #define HAS_Y2_STEPPER 1
+#endif
+
+/**
+ * Number of Primary Linear Axes (e.g., XYZ)
+ * X, XY, or XYZ axes. Excluding duplicate axes (X2, Y2, Z2, Z3, Z4)
+ */
+#if NUM_AXES >= 3
+ #define PRIMARY_LINEAR_AXES 3
+#else
+ #define PRIMARY_LINEAR_AXES NUM_AXES
+#endif
+
+/**
+ * Number of Secondary Axes (e.g., IJKUVW)
+ * All linear/rotational axes between XYZ and E.
+ */
+#define SECONDARY_AXES SUB3(NUM_AXES)
+
+/**
+ * Number of Rotational Axes (e.g., IJK)
+ * All axes for which AXIS*_ROTATES is defined.
+ * For these axes, positions are specified in angular degrees.
+ */
+#if ENABLED(AXIS9_ROTATES)
+ #define ROTATIONAL_AXES 6
+#elif ENABLED(AXIS8_ROTATES)
+ #define ROTATIONAL_AXES 5
+#elif ENABLED(AXIS7_ROTATES)
+ #define ROTATIONAL_AXES 4
+#elif ENABLED(AXIS6_ROTATES)
+ #define ROTATIONAL_AXES 3
+#elif ENABLED(AXIS5_ROTATES)
+ #define ROTATIONAL_AXES 2
+#elif ENABLED(AXIS4_ROTATES)
+ #define ROTATIONAL_AXES 1
+#else
+ #define ROTATIONAL_AXES 0
+#endif
+
+#if ROTATIONAL_AXES
+ #define HAS_ROTATIONAL_AXES 1
+#endif
+
+/**
+ * Number of Secondary Linear Axes (e.g., UVW)
+ * All secondary axes for which AXIS*_ROTATES is not defined.
+ * Excluding primary axes and excluding duplicate axes (X2, Y2, Z2, Z3, Z4)
+ */
+#define SECONDARY_LINEAR_AXES (NUM_AXES - PRIMARY_LINEAR_AXES - ROTATIONAL_AXES)
+
+/**
+ * Number of Logical Axes (e.g., XYZIJKUVWE)
+ * All logical axes that can be commanded directly by G-code.
+ * Delta maps stepper-specific values to ABC steppers.
+ */
+#if HAS_EXTRUDERS
+ #define LOGICAL_AXES INCREMENT(NUM_AXES)
+#else
+ #define LOGICAL_AXES NUM_AXES
+#endif
+
+/**
+ * DISTINCT_E_FACTORS is set to give extruders (some) individual settings.
+ *
+ * DISTINCT_AXES is the number of distinct addressable axes (not steppers).
+ * Includes all linear axes plus all distinguished extruders.
+ * The default behavior is to treat all extruders as a single E axis
+ * with shared motion and temperature settings.
+ *
+ * DISTINCT_E is the number of distinguished extruders. By default this
+ * will be 1 which indicates all extruders share the same settings.
+ *
+ * E_INDEX_N(E) should be used to get the E index of any item that might be
+ * distinguished.
+ */
+#if ENABLED(DISTINCT_E_FACTORS) && E_STEPPERS > 1
+ #define DISTINCT_AXES (NUM_AXES + E_STEPPERS)
+ #define DISTINCT_E E_STEPPERS
+ #define E_INDEX_N(E) (E)
+#else
+ #undef DISTINCT_E_FACTORS
+ #define DISTINCT_AXES LOGICAL_AXES
+ #define DISTINCT_E 1
+ #define E_INDEX_N(E) 0
+#endif
+
+// Helper macros for extruder and hotend arrays
+#define _EXTRUDER_LOOP(E) for (int8_t E = 0; E < EXTRUDERS; E++)
+#define EXTRUDER_LOOP() _EXTRUDER_LOOP(e)
+#define _HOTEND_LOOP(H) for (int8_t H = 0; H < HOTENDS; H++)
+#define HOTEND_LOOP() _HOTEND_LOOP(e)
+
+#define ARRAY_BY_EXTRUDERS(V...) ARRAY_N(EXTRUDERS, V)
+#define ARRAY_BY_EXTRUDERS1(v1) ARRAY_N_1(EXTRUDERS, v1)
+#define ARRAY_BY_HOTENDS(V...) ARRAY_N(HOTENDS, V)
+#define ARRAY_BY_HOTENDS1(v1) ARRAY_N_1(HOTENDS, v1)
+
+/**
+ * Extruders have some combination of stepper motors and hotends
+ * so we separate these concepts into the defines:
+ *
+ * EXTRUDERS - Number of Selectable Tools
+ * HOTENDS - Number of hotends, whether connected or separate
+ * E_STEPPERS - Number of actual E stepper motors
+ * E_MANUAL - Number of E steppers for LCD move options
+ *
+ * These defines must be simple constants for use in REPEAT, etc.
+ */
+#if EXTRUDERS
+ #define HAS_EXTRUDERS 1
+ #if EXTRUDERS > 1
+ #define HAS_MULTI_EXTRUDER 1
+ #endif
+ #define E_AXIS_N(E) AxisEnum(E_AXIS + E_INDEX_N(E))
+#else
+ #undef EXTRUDERS
+ #define EXTRUDERS 0
+ #undef TEMP_SENSOR_0
+ #undef TEMP_SENSOR_1
+ #undef TEMP_SENSOR_2
+ #undef TEMP_SENSOR_3
+ #undef TEMP_SENSOR_4
+ #undef TEMP_SENSOR_5
+ #undef TEMP_SENSOR_6
+ #undef TEMP_SENSOR_7
+ #undef SINGLENOZZLE
+ #undef SWITCHING_EXTRUDER
+ #undef MECHANICAL_SWITCHING_EXTRUDER
+ #undef SWITCHING_NOZZLE
+ #undef MECHANICAL_SWITCHING_NOZZLE
+ #undef MIXING_EXTRUDER
+ #undef HOTEND_IDLE_TIMEOUT
+ #undef DISABLE_E
+ #undef PREVENT_LENGTHY_EXTRUDE
+ #undef FILAMENT_RUNOUT_SENSOR
+ #undef FILAMENT_RUNOUT_DISTANCE_MM
+ #undef DISABLE_OTHER_EXTRUDERS
+#endif
+
+#define E_OPTARG(N) OPTARG(HAS_MULTI_EXTRUDER, N)
+#define E_TERN_(N) TERN_(HAS_MULTI_EXTRUDER, N)
+#define E_TERN0(N) TERN0(HAS_MULTI_EXTRUDER, N)
+
+#if ANY(SWITCHING_EXTRUDER, MECHANICAL_SWITCHING_EXTRUDER)
+ #define HAS_SWITCHING_EXTRUDER 1
+#endif
+#if ANY(SWITCHING_NOZZLE, MECHANICAL_SWITCHING_NOZZLE)
+ #define HAS_SWITCHING_NOZZLE 1
+#endif
+
+/**
+ * Multi-Material-Unit supported models
+ */
+#ifdef MMU_MODEL
+ #define HAS_MMU 1
+ #define SINGLENOZZLE
+
+ #define _PRUSA_MMU1 1
+ #define _PRUSA_MMU2 2
+ #define _PRUSA_MMU2S 3
+ #define _PRUSA_MMU3 4
+ #define _EXTENDABLE_EMU_MMU2 12
+ #define _EXTENDABLE_EMU_MMU2S 13
+ #define _EXTENDABLE_EMU_MMU3 14
+ #define _MMU CAT(_,MMU_MODEL)
+
+ #if _MMU == _PRUSA_MMU1
+ #define HAS_PRUSA_MMU1 1
+ #elif _MMU % 10 == _PRUSA_MMU2
+ #define HAS_PRUSA_MMU2 1
+ #elif _MMU % 10 == _PRUSA_MMU2S
+ #define HAS_PRUSA_MMU2 1
+ #define HAS_PRUSA_MMU2S 1
+ #elif _MMU % 10 == _PRUSA_MMU3
+ #define HAS_PRUSA_MMU3 1
+ #endif
+ #if _MMU == _EXTENDABLE_EMU_MMU2 || _MMU == _EXTENDABLE_EMU_MMU2S
+ #define HAS_EXTENDABLE_MMU 1
+ #endif
+
+ #undef _MMU
+ #undef _PRUSA_MMU1
+ #undef _PRUSA_MMU2
+ #undef _PRUSA_MMU2S
+ #undef _PRUSA_MMU3
+ #undef _EXTENDABLE_EMU_MMU2
+ #undef _EXTENDABLE_EMU_MMU2S
+ #undef _EXTENDABLE_EMU_MMU3
+#endif
+
+#if ENABLED(E_DUAL_STEPPER_DRIVERS) // E0/E1 steppers act in tandem as E0
+
+ #define E_STEPPERS 2
+ #define E_MANUAL 1
+
+#elif HAS_SWITCHING_EXTRUDER // One stepper for every two EXTRUDERS
+
+ #if EXTRUDERS > 4
+ #define E_STEPPERS 3
+ #elif EXTRUDERS > 2
+ #define E_STEPPERS 2
+ #else
+ #define E_STEPPERS 1
+ #endif
+
+#elif ENABLED(MIXING_EXTRUDER) // Multiple feeds are mixed proportionally
+
+ #define E_STEPPERS MIXING_STEPPERS
+ #define E_MANUAL 1
+ #if MIXING_STEPPERS == 2
+ #define HAS_DUAL_MIXING 1
+ #endif
+ #ifndef MIXING_VIRTUAL_TOOLS
+ #define MIXING_VIRTUAL_TOOLS 1
+ #endif
+
+#elif ENABLED(SWITCHING_TOOLHEAD) // Toolchanger
+
+ #define E_STEPPERS EXTRUDERS
+ #define E_MANUAL EXTRUDERS
+
+#elif HAS_PRUSA_MMU2 || HAS_PRUSA_MMU3 // Průša Multi-Material Unit v2/v3
+
+ #define E_STEPPERS 1
+ #define E_MANUAL 1
+
+#endif
+
+// Default E steppers / manual motion is one per extruder
+#ifndef E_STEPPERS
+ #define E_STEPPERS EXTRUDERS
+#endif
+#ifndef E_MANUAL
+ #define E_MANUAL EXTRUDERS
+#endif
+
+// Number of hotends...
+#if ANY(SINGLENOZZLE, MIXING_EXTRUDER) // Only one for singlenozzle or mixing extruder
+ #define HOTENDS 1
+#elif HAS_SWITCHING_EXTRUDER && !HAS_SWITCHING_NOZZLE // One for each pair of abstract "extruders"
+ #define HOTENDS E_STEPPERS
+#elif TEMP_SENSOR_0
+ #define HOTENDS EXTRUDERS // One per extruder if at least one heater exists
+#else
+ #define HOTENDS 0 // A machine with no hotends at all can still extrude
+#endif
+
+// At least one hotend...
+#if HOTENDS
+ #define HAS_HOTEND 1
+ #ifndef HOTEND_OVERSHOOT
+ #define HOTEND_OVERSHOOT 15
+ #endif
+#else
+ #undef MPCTEMP
+ #undef PIDTEMP
+ #undef PREVENT_COLD_EXTRUSION
+ #undef THERMAL_PROTECTION_HOTENDS
+#endif
+
+// More than one hotend...
+#if HOTENDS > 1
+ #define HAS_MULTI_HOTEND 1
+ #define HAS_HOTEND_OFFSET 1
+ #ifndef HOTEND_OFFSET_X
+ #define HOTEND_OFFSET_X { 0 } // X offsets for each extruder
+ #endif
+ #ifndef HOTEND_OFFSET_Y
+ #define HOTEND_OFFSET_Y { 0 } // Y offsets for each extruder
+ #endif
+ #ifndef HOTEND_OFFSET_Z
+ #define HOTEND_OFFSET_Z { 0 } // Z offsets for each extruder
+ #endif
+#else
+ #undef HOTEND_OFFSET_X
+ #undef HOTEND_OFFSET_Y
+ #undef HOTEND_OFFSET_Z
+#endif
diff --git a/Marlin/src/inc/Conditionals_etc.h b/Marlin/src/inc/Conditionals_etc.h
new file mode 100644
index 0000000000..90002af3c8
--- /dev/null
+++ b/Marlin/src/inc/Conditionals_etc.h
@@ -0,0 +1,664 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+#pragma once
+
+/**
+ * Conditionals_etc.h
+ * Conditionals that need to be set before Configuration_adv.h or pins.h
+ */
+
+#ifndef STRING_CONFIG_H_AUTHOR
+ #define STRING_CONFIG_H_AUTHOR "(anonymous)"
+#endif
+
+//
+// Remove irrelevant Configuration.h settings
+//
+
+// Clean up unused temperature sensors and sub-options
+
+#if !TEMP_SENSOR_0
+ #undef TEMP_SENSOR_0
+#endif
+#if !TEMP_SENSOR_1
+ #undef TEMP_SENSOR_1
+#endif
+#if !TEMP_SENSOR_2
+ #undef TEMP_SENSOR_2
+#endif
+#if !TEMP_SENSOR_3
+ #undef TEMP_SENSOR_3
+#endif
+#if !TEMP_SENSOR_4
+ #undef TEMP_SENSOR_4
+#endif
+#if !TEMP_SENSOR_5
+ #undef TEMP_SENSOR_5
+#endif
+#if !TEMP_SENSOR_6
+ #undef TEMP_SENSOR_6
+#endif
+#if !TEMP_SENSOR_7
+ #undef TEMP_SENSOR_7
+#endif
+
+#if !TEMP_SENSOR_BED
+ #undef TEMP_SENSOR_BED
+ #undef THERMAL_PROTECTION_BED
+ #undef MAX_BED_POWER
+#endif
+#if !TEMP_SENSOR_CHAMBER
+ #undef TEMP_SENSOR_CHAMBER
+ #undef THERMAL_PROTECTION_CHAMBER
+ #undef CHAMBER_AUTO_FAN_PIN
+ #undef MAX_CHAMBER_POWER
+#endif
+#if !TEMP_SENSOR_COOLER
+ #undef TEMP_SENSOR_COOLER
+ #undef THERMAL_PROTECTION_COOLER
+ #undef COOLER_AUTO_FAN_PIN
+#endif
+#if !TEMP_SENSOR_PROBE
+ #undef TEMP_SENSOR_PROBE
+#endif
+#if !TEMP_SENSOR_REDUNDANT
+ #undef TEMP_SENSOR_REDUNDANT
+#endif
+#if !TEMP_SENSOR_BOARD
+ #undef TEMP_SENSOR_BOARD
+#endif
+#if !TEMP_SENSOR_SOC
+ #undef TEMP_SENSOR_SOC
+#endif
+#if !SOFT_PWM_SCALE
+ #undef SOFT_PWM_SCALE
+#endif
+
+/**
+ * Disable unused SINGLENOZZLE sub-options
+ */
+#if DISABLED(SINGLENOZZLE)
+ #undef SINGLENOZZLE_STANDBY_TEMP
+#endif
+#if !ALL(HAS_FAN, SINGLENOZZLE)
+ #undef SINGLENOZZLE_STANDBY_FAN
+#endif
+
+// No inactive extruders with SWITCHING_NOZZLE or Průša MMU1 or just 1 E stepper exists
+#if HAS_SWITCHING_NOZZLE || HAS_PRUSA_MMU1 || E_STEPPERS < 2
+ #undef DISABLE_OTHER_EXTRUDERS
+#endif
+
+// Switching extruder has its own servo?
+#if ENABLED(SWITCHING_EXTRUDER) && (!HAS_SWITCHING_NOZZLE || SWITCHING_EXTRUDER_SERVO_NR != SWITCHING_NOZZLE_SERVO_NR)
+ #define DO_SWITCH_EXTRUDER 1
+#endif
+
+/**
+ * The BLTouch Probe emulates a servo probe
+ * and uses "special" angles for its state.
+ */
+#if ENABLED(BLTOUCH) && !defined(Z_PROBE_SERVO_NR)
+ #define Z_PROBE_SERVO_NR 0
+#endif
+
+/**
+ * Set a flag for a servo probe (or BLTouch)
+ */
+#ifdef Z_PROBE_SERVO_NR
+ #define HAS_Z_SERVO_PROBE 1
+#endif
+#if ANY(HAS_Z_SERVO_PROBE, SWITCHING_EXTRUDER, SWITCHING_NOZZLE)
+ #define HAS_SERVO_ANGLES 1
+#endif
+#if !HAS_SERVO_ANGLES
+ #undef EDITABLE_SERVO_ANGLES
+#endif
+
+/**
+ * Set flags for any form of bed probe
+ */
+#if ANY(TOUCH_MI_PROBE, Z_PROBE_ALLEN_KEY, HAS_Z_SERVO_PROBE, SOLENOID_PROBE, Z_PROBE_SLED, RACK_AND_PINION_PROBE, SENSORLESS_PROBING, MAGLEV4, MAG_MOUNTED_PROBE, BIQU_MICROPROBE_V1, BIQU_MICROPROBE_V2)
+ #define HAS_STOWABLE_PROBE 1
+#endif
+#if ANY(HAS_STOWABLE_PROBE, FIX_MOUNTED_PROBE, BD_SENSOR, NOZZLE_AS_PROBE)
+ #define HAS_BED_PROBE 1
+#endif
+
+// Probing tool change
+#if !HAS_MULTI_EXTRUDER
+ #undef PROBING_TOOL
+#endif
+#if HAS_BED_PROBE && defined(PROBING_TOOL)
+ #define DO_TOOLCHANGE_FOR_PROBING 1
+#endif
+
+/**
+ * Fill in undefined Filament Sensor options
+ */
+#if ENABLED(FILAMENT_RUNOUT_SENSOR)
+ #if NUM_RUNOUT_SENSORS >= 1
+ #ifndef FIL_RUNOUT1_STATE
+ #define FIL_RUNOUT1_STATE FIL_RUNOUT_STATE
+ #endif
+ #ifndef FIL_RUNOUT1_PULLUP
+ #define FIL_RUNOUT1_PULLUP FIL_RUNOUT_PULLUP
+ #endif
+ #ifndef FIL_RUNOUT1_PULLDOWN
+ #define FIL_RUNOUT1_PULLDOWN FIL_RUNOUT_PULLDOWN
+ #endif
+ #endif
+ #if NUM_RUNOUT_SENSORS >= 2
+ #ifndef FIL_RUNOUT2_STATE
+ #define FIL_RUNOUT2_STATE FIL_RUNOUT_STATE
+ #endif
+ #ifndef FIL_RUNOUT2_PULLUP
+ #define FIL_RUNOUT2_PULLUP FIL_RUNOUT_PULLUP
+ #endif
+ #ifndef FIL_RUNOUT2_PULLDOWN
+ #define FIL_RUNOUT2_PULLDOWN FIL_RUNOUT_PULLDOWN
+ #endif
+ #endif
+ #if NUM_RUNOUT_SENSORS >= 3
+ #ifndef FIL_RUNOUT3_STATE
+ #define FIL_RUNOUT3_STATE FIL_RUNOUT_STATE
+ #endif
+ #ifndef FIL_RUNOUT3_PULLUP
+ #define FIL_RUNOUT3_PULLUP FIL_RUNOUT_PULLUP
+ #endif
+ #ifndef FIL_RUNOUT3_PULLDOWN
+ #define FIL_RUNOUT3_PULLDOWN FIL_RUNOUT_PULLDOWN
+ #endif
+ #endif
+ #if NUM_RUNOUT_SENSORS >= 4
+ #ifndef FIL_RUNOUT4_STATE
+ #define FIL_RUNOUT4_STATE FIL_RUNOUT_STATE
+ #endif
+ #ifndef FIL_RUNOUT4_PULLUP
+ #define FIL_RUNOUT4_PULLUP FIL_RUNOUT_PULLUP
+ #endif
+ #ifndef FIL_RUNOUT4_PULLDOWN
+ #define FIL_RUNOUT4_PULLDOWN FIL_RUNOUT_PULLDOWN
+ #endif
+ #endif
+ #if NUM_RUNOUT_SENSORS >= 5
+ #ifndef FIL_RUNOUT5_STATE
+ #define FIL_RUNOUT5_STATE FIL_RUNOUT_STATE
+ #endif
+ #ifndef FIL_RUNOUT5_PULLUP
+ #define FIL_RUNOUT5_PULLUP FIL_RUNOUT_PULLUP
+ #endif
+ #ifndef FIL_RUNOUT5_PULLDOWN
+ #define FIL_RUNOUT5_PULLDOWN FIL_RUNOUT_PULLDOWN
+ #endif
+ #endif
+ #if NUM_RUNOUT_SENSORS >= 6
+ #ifndef FIL_RUNOUT6_STATE
+ #define FIL_RUNOUT6_STATE FIL_RUNOUT_STATE
+ #endif
+ #ifndef FIL_RUNOUT6_PULLUP
+ #define FIL_RUNOUT6_PULLUP FIL_RUNOUT_PULLUP
+ #endif
+ #ifndef FIL_RUNOUT6_PULLDOWN
+ #define FIL_RUNOUT6_PULLDOWN FIL_RUNOUT_PULLDOWN
+ #endif
+ #endif
+ #if NUM_RUNOUT_SENSORS >= 7
+ #ifndef FIL_RUNOUT7_STATE
+ #define FIL_RUNOUT7_STATE FIL_RUNOUT_STATE
+ #endif
+ #ifndef FIL_RUNOUT7_PULLUP
+ #define FIL_RUNOUT7_PULLUP FIL_RUNOUT_PULLUP
+ #endif
+ #ifndef FIL_RUNOUT7_PULLDOWN
+ #define FIL_RUNOUT7_PULLDOWN FIL_RUNOUT_PULLDOWN
+ #endif
+ #endif
+ #if NUM_RUNOUT_SENSORS >= 8
+ #ifndef FIL_RUNOUT8_STATE
+ #define FIL_RUNOUT8_STATE FIL_RUNOUT_STATE
+ #endif
+ #ifndef FIL_RUNOUT8_PULLUP
+ #define FIL_RUNOUT8_PULLUP FIL_RUNOUT_PULLUP
+ #endif
+ #ifndef FIL_RUNOUT8_PULLDOWN
+ #define FIL_RUNOUT8_PULLDOWN FIL_RUNOUT_PULLDOWN
+ #endif
+ #endif
+#endif // FILAMENT_RUNOUT_SENSOR
+
+#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
+ #if NUM_MOTION_SENSORS >= 1
+ #ifndef FIL_MOTION1_STATE
+ #define FIL_MOTION1_STATE FIL_RUNOUT_STATE
+ #endif
+ #ifndef FIL_MOTION1_PULLUP
+ #define FIL_MOTION1_PULLUP FIL_RUNOUT_PULLUP
+ #endif
+ #ifndef FIL_MOTION1_PULLDOWN
+ #define FIL_MOTION1_PULLDOWN FIL_RUNOUT_PULLDOWN
+ #endif
+ #endif
+ #if NUM_MOTION_SENSORS >= 2
+ #ifndef FIL_MOTION2_STATE
+ #define FIL_MOTION2_STATE FIL_RUNOUT_STATE
+ #endif
+ #ifndef FIL_MOTION2_PULLUP
+ #define FIL_MOTION2_PULLUP FIL_RUNOUT_PULLUP
+ #endif
+ #ifndef FIL_MOTION2_PULLDOWN
+ #define FIL_MOTION2_PULLDOWN FIL_RUNOUT_PULLDOWN
+ #endif
+ #endif
+ #if NUM_MOTION_SENSORS >= 3
+ #ifndef FIL_MOTION3_STATE
+ #define FIL_MOTION3_STATE FIL_RUNOUT_STATE
+ #endif
+ #ifndef FIL_MOTION3_PULLUP
+ #define FIL_MOTION3_PULLUP FIL_RUNOUT_PULLUP
+ #endif
+ #ifndef FIL_MOTION3_PULLDOWN
+ #define FIL_MOTION3_PULLDOWN FIL_RUNOUT_PULLDOWN
+ #endif
+ #endif
+ #if NUM_MOTION_SENSORS >= 4
+ #ifndef FIL_MOTION4_STATE
+ #define FIL_MOTION4_STATE FIL_RUNOUT_STATE
+ #endif
+ #ifndef FIL_MOTION4_PULLUP
+ #define FIL_MOTION4_PULLUP FIL_RUNOUT_PULLUP
+ #endif
+ #ifndef FIL_MOTION4_PULLDOWN
+ #define FIL_MOTION4_PULLDOWN FIL_RUNOUT_PULLDOWN
+ #endif
+ #endif
+ #if NUM_MOTION_SENSORS >= 5
+ #ifndef FIL_MOTION5_STATE
+ #define FIL_MOTION5_STATE FIL_RUNOUT_STATE
+ #endif
+ #ifndef FIL_MOTION5_PULLUP
+ #define FIL_MOTION5_PULLUP FIL_RUNOUT_PULLUP
+ #endif
+ #ifndef FIL_MOTION5_PULLDOWN
+ #define FIL_MOTION5_PULLDOWN FIL_RUNOUT_PULLDOWN
+ #endif
+ #endif
+ #if NUM_MOTION_SENSORS >= 6
+ #ifndef FIL_MOTION6_STATE
+ #define FIL_MOTION6_STATE FIL_RUNOUT_STATE
+ #endif
+ #ifndef FIL_MOTION6_PULLUP
+ #define FIL_MOTION6_PULLUP FIL_RUNOUT_PULLUP
+ #endif
+ #ifndef FIL_MOTION6_PULLDOWN
+ #define FIL_MOTION6_PULLDOWN FIL_RUNOUT_PULLDOWN
+ #endif
+ #endif
+ #if NUM_MOTION_SENSORS >= 7
+ #ifndef FIL_MOTION7_STATE
+ #define FIL_MOTION7_STATE FIL_RUNOUT_STATE
+ #endif
+ #ifndef FIL_MOTION7_PULLUP
+ #define FIL_MOTION7_PULLUP FIL_RUNOUT_PULLUP
+ #endif
+ #ifndef FIL_MOTION7_PULLDOWN
+ #define FIL_MOTION7_PULLDOWN FIL_RUNOUT_PULLDOWN
+ #endif
+ #endif
+ #if NUM_MOTION_SENSORS >= 8
+ #ifndef FIL_MOTION8_STATE
+ #define FIL_MOTION8_STATE FIL_RUNOUT_STATE
+ #endif
+ #ifndef FIL_MOTION8_PULLUP
+ #define FIL_MOTION8_PULLUP FIL_RUNOUT_PULLUP
+ #endif
+ #ifndef FIL_MOTION8_PULLDOWN
+ #define FILMOTION8_PULLDOWN FIL_RUNOUT_PULLDOWN
+ #endif
+ #endif
+#endif // FILAMENT_SWITCH_AND_MOTION
+
+// Homing to Min or Max
+#if HAS_X_AXIS
+ #if X_HOME_DIR > 0
+ #define X_HOME_TO_MAX 1
+ #elif X_HOME_DIR < 0
+ #define X_HOME_TO_MIN 1
+ #endif
+#endif
+#if HAS_Y_AXIS
+ #if Y_HOME_DIR > 0
+ #define Y_HOME_TO_MAX 1
+ #elif Y_HOME_DIR < 0
+ #define Y_HOME_TO_MIN 1
+ #endif
+#endif
+#if HAS_Z_AXIS
+ #if Z_HOME_DIR > 0
+ #define Z_HOME_TO_MAX 1
+ #elif Z_HOME_DIR < 0
+ #define Z_HOME_TO_MIN 1
+ #endif
+#endif
+#if HAS_I_AXIS
+ #if I_HOME_DIR > 0
+ #define I_HOME_TO_MAX 1
+ #elif I_HOME_DIR < 0
+ #define I_HOME_TO_MIN 1
+ #endif
+#endif
+#if HAS_J_AXIS
+ #if J_HOME_DIR > 0
+ #define J_HOME_TO_MAX 1
+ #elif J_HOME_DIR < 0
+ #define J_HOME_TO_MIN 1
+ #endif
+#endif
+#if HAS_K_AXIS
+ #if K_HOME_DIR > 0
+ #define K_HOME_TO_MAX 1
+ #elif K_HOME_DIR < 0
+ #define K_HOME_TO_MIN 1
+ #endif
+#endif
+#if HAS_U_AXIS
+ #if U_HOME_DIR > 0
+ #define U_HOME_TO_MAX 1
+ #elif U_HOME_DIR < 0
+ #define U_HOME_TO_MIN 1
+ #endif
+#endif
+#if HAS_V_AXIS
+ #if V_HOME_DIR > 0
+ #define V_HOME_TO_MAX 1
+ #elif V_HOME_DIR < 0
+ #define V_HOME_TO_MIN 1
+ #endif
+#endif
+#if HAS_W_AXIS
+ #if W_HOME_DIR > 0
+ #define W_HOME_TO_MAX 1
+ #elif W_HOME_DIR < 0
+ #define W_HOME_TO_MIN 1
+ #endif
+#endif
+
+/**
+ * Conditionals based on the type of Bed Probe
+ */
+#if HAS_BED_PROBE
+ #if ALL(DELTA, SENSORLESS_PROBING)
+ #define HAS_DELTA_SENSORLESS_PROBING 1
+ #else
+ #define HAS_REAL_BED_PROBE 1
+ #endif
+ #if HAS_REAL_BED_PROBE && NONE(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, Z_SPI_SENSORLESS)
+ #define NEED_Z_MIN_PROBE_PIN 1
+ #endif
+ #if Z_HOME_TO_MIN && (!NEED_Z_MIN_PROBE_PIN || ENABLED(USE_PROBE_FOR_Z_HOMING))
+ #define HOMING_Z_WITH_PROBE 1
+ #endif
+ #if DISABLED(NOZZLE_AS_PROBE)
+ #define HAS_PROBE_XY_OFFSET 1
+ #endif
+ #if ANY(Z_PROBE_ALLEN_KEY, MAG_MOUNTED_PROBE)
+ #define PROBE_TRIGGERED_WHEN_STOWED_TEST 1 // Extra test for Allen Key Probe
+ #endif
+ #ifndef Z_PROBE_ERROR_TOLERANCE
+ #define Z_PROBE_ERROR_TOLERANCE Z_CLEARANCE_MULTI_PROBE
+ #endif
+ #if MULTIPLE_PROBING > 1
+ #if EXTRA_PROBING > 0
+ #define TOTAL_PROBING (MULTIPLE_PROBING + EXTRA_PROBING)
+ #else
+ #define TOTAL_PROBING MULTIPLE_PROBING
+ #endif
+ #endif
+#else
+ // Clear probe pin settings when no probe is selected
+ #undef Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN
+ #undef USE_PROBE_FOR_Z_HOMING
+ #undef Z_MIN_PROBE_REPEATABILITY_TEST
+ #undef HOMING_Z_WITH_PROBE
+ #undef Z_CLEARANCE_MULTI_PROBE
+ #undef Z_PROBE_ERROR_TOLERANCE
+ #undef Z_AFTER_PROBING
+ #undef Z_PROBE_LOW_POINT
+ #undef MULTIPLE_PROBING
+ #undef EXTRA_PROBING
+ #undef PROBE_OFFSET_ZMIN
+ #undef PROBE_OFFSET_ZMAX
+ #undef PAUSE_BEFORE_DEPLOY_STOW
+ #undef PAUSE_PROBE_DEPLOY_WHEN_TRIGGERED
+ #undef PROBING_HEATERS_OFF
+ #undef WAIT_FOR_BED_HEATER
+ #undef WAIT_FOR_HOTEND
+ #undef PROBING_FANS_OFF
+ #undef PROBING_ESTEPPERS_OFF
+ #undef PROBING_STEPPERS_OFF
+ #undef DELAY_BEFORE_PROBING
+ #undef PREHEAT_BEFORE_PROBING
+ #undef PROBING_NOZZLE_TEMP
+ #undef PROBING_BED_TEMP
+ #undef NOZZLE_TO_PROBE_OFFSET
+#endif
+
+#if ENABLED(BELTPRINTER) && !defined(HOME_Y_BEFORE_X)
+ #define HOME_Y_BEFORE_X
+#endif
+
+#if Z_HOME_TO_MAX && DISABLED(Z_SAFE_HOMING)
+ #define HOME_Z_FIRST // If homing away from BED do Z first
+#endif
+
+/**
+ * Conditionals based on the type of Bed Leveling
+ */
+#if ENABLED(AUTO_BED_LEVELING_UBL)
+ #undef LCD_BED_LEVELING
+ #if ANY(DELTA, SEGMENT_LEVELED_MOVES)
+ #define UBL_SEGMENTED 1
+ #endif
+#endif
+#if ANY(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT)
+ #define ABL_PLANAR 1
+#endif
+#if ANY(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR)
+ #define ABL_USES_GRID 1
+#endif
+#if ANY(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_3POINT)
+ #define HAS_ABL_NOT_UBL 1
+#endif
+#if ANY(AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_UBL, MESH_BED_LEVELING)
+ #define HAS_MESH 1
+#endif
+#if ANY(AUTO_BED_LEVELING_UBL, AUTO_BED_LEVELING_3POINT)
+ #define NEEDS_THREE_PROBE_POINTS 1
+#endif
+#if ANY(HAS_ABL_NOT_UBL, AUTO_BED_LEVELING_UBL)
+ #define HAS_ABL_OR_UBL 1
+ #if DISABLED(PROBE_MANUALLY)
+ #define HAS_AUTOLEVEL 1
+ #endif
+#endif
+#if ANY(HAS_ABL_OR_UBL, MESH_BED_LEVELING)
+ #define HAS_LEVELING 1
+ #if DISABLED(AUTO_BED_LEVELING_UBL)
+ #define PLANNER_LEVELING 1
+ #endif
+#endif
+#if !HAS_LEVELING
+ #undef RESTORE_LEVELING_AFTER_G28
+ #undef ENABLE_LEVELING_AFTER_G28
+ #undef G29_RETRY_AND_RECOVER
+#endif
+#if !HAS_LEVELING || ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL)
+ #undef PROBE_MANUALLY
+#endif
+#if ANY(HAS_BED_PROBE, PROBE_MANUALLY, MESH_BED_LEVELING)
+ #define PROBE_SELECTED 1
+#endif
+
+#if !HAS_MESH
+ #undef MESH_INSET
+#endif
+
+#if NONE(PROBE_SELECTED, AUTO_BED_LEVELING_UBL)
+ #undef Z_CLEARANCE_BETWEEN_PROBES
+#endif
+
+#if NONE(PROBE_SELECTED, DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
+ #undef PROBING_MARGIN
+ #undef PROBING_MARGIN_LEFT
+ #undef PROBING_MARGIN_RIGHT
+ #undef PROBING_MARGIN_FRONT
+ #undef PROBING_MARGIN_BACK
+ #undef XY_PROBE_FEEDRATE
+#endif
+
+#if !(ANY(HAS_BED_PROBE, HAS_LEVELING) || ALL(AUTO_BED_LEVELING_UBL, HAS_MARLINUI_MENU))
+ #undef Z_CLEARANCE_DEPLOY_PROBE
+#endif
+
+#if !(ANY(HAS_BED_PROBE, BACKLASH_GCODE) || (ENABLED(EXTENSIBLE_UI) && ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL)))
+ #undef Z_PROBE_FEEDRATE_FAST
+ #undef Z_PROBE_FEEDRATE_SLOW
+#endif
+
+/**
+ * Z_CLEARANCE_FOR_HOMING
+ */
+#ifndef Z_CLEARANCE_FOR_HOMING
+ #ifdef Z_CLEARANCE_BETWEEN_PROBES
+ #define Z_CLEARANCE_FOR_HOMING Z_CLEARANCE_BETWEEN_PROBES
+ #else
+ #define Z_CLEARANCE_FOR_HOMING 5
+ #endif
+#endif
+
+/**
+ * Z_CLEARANCE_BETWEEN_PROBES
+ */
+#if PROBE_SELECTED || (HAS_MARLINUI_MENU && ANY(DELTA_CALIBRATION_MENU, DELTA_AUTO_CALIBRATION))
+ #ifndef Z_CLEARANCE_BETWEEN_PROBES
+ #define Z_CLEARANCE_BETWEEN_PROBES Z_CLEARANCE_FOR_HOMING
+ #endif
+#endif
+
+/**
+ * Z_CLEARANCE_BETWEEN_MANUAL_PROBES / Z_CLEARANCE_MULTI_PROBE
+ */
+#if PROBE_SELECTED
+ #if ANY(MESH_BED_LEVELING, PROBE_MANUALLY)
+ #if Z_CLEARANCE_BETWEEN_PROBES > Z_CLEARANCE_FOR_HOMING
+ #define Z_CLEARANCE_BETWEEN_MANUAL_PROBES Z_CLEARANCE_BETWEEN_PROBES
+ #else
+ #define Z_CLEARANCE_BETWEEN_MANUAL_PROBES Z_CLEARANCE_FOR_HOMING
+ #endif
+ #endif
+ #ifndef Z_CLEARANCE_MULTI_PROBE
+ #ifdef Z_CLEARANCE_BETWEEN_PROBES
+ #define Z_CLEARANCE_MULTI_PROBE Z_CLEARANCE_BETWEEN_PROBES
+ #else
+ #define Z_CLEARANCE_MULTI_PROBE 5
+ #endif
+ #endif
+#endif
+#if TOTAL_PROBING < 2
+ #undef Z_CLEARANCE_MULTI_PROBE
+#endif
+
+#if DISABLED(ENABLE_LEVELING_FADE_HEIGHT)
+ #undef DEFAULT_LEVELING_FADE_HEIGHT
+#endif
+
+#ifdef GRID_MAX_POINTS_X
+ #define GRID_MAX_POINTS ((GRID_MAX_POINTS_X) * (GRID_MAX_POINTS_Y))
+ #define GRID_LOOP(A,B) for (uint8_t A = 0; A < GRID_MAX_POINTS_X; ++A) for (uint8_t B = 0; B < GRID_MAX_POINTS_Y; ++B)
+#endif
+
+/**
+ * CoreXY, CoreXZ, and CoreYZ - and their reverse
+ */
+#if ANY(COREXY, COREYX)
+ #define CORE_IS_XY 1
+#endif
+#if ANY(COREXZ, COREZX)
+ #define CORE_IS_XZ 1
+#endif
+#if ANY(COREYZ, COREZY)
+ #define CORE_IS_YZ 1
+#endif
+#if CORE_IS_XY || CORE_IS_XZ || CORE_IS_YZ
+ #define IS_CORE 1
+ #if CORE_IS_XY
+ #define CORE_AXIS_1 A_AXIS
+ #define CORE_AXIS_2 B_AXIS
+ #define NORMAL_AXIS Z_AXIS
+ #elif CORE_IS_XZ
+ #define CORE_AXIS_1 A_AXIS
+ #define NORMAL_AXIS Y_AXIS
+ #define CORE_AXIS_2 C_AXIS
+ #elif CORE_IS_YZ
+ #define NORMAL_AXIS X_AXIS
+ #define CORE_AXIS_1 B_AXIS
+ #define CORE_AXIS_2 C_AXIS
+ #endif
+ #define CORESIGN(n) (ANY(COREYX, COREZX, COREZY) ? (-(n)) : (n))
+#elif ANY(MARKFORGED_XY, MARKFORGED_YX)
+ // Markforged kinematics
+ #define CORE_AXIS_1 A_AXIS
+ #define CORE_AXIS_2 B_AXIS
+ #define NORMAL_AXIS Z_AXIS
+#endif
+
+#if ANY(MORGAN_SCARA, MP_SCARA, AXEL_TPARA)
+ #define IS_SCARA 1
+ #define IS_KINEMATIC 1
+#elif ANY(DELTA, POLARGRAPH, POLAR)
+ #define IS_KINEMATIC 1
+#else
+ #define IS_CARTESIAN 1
+ #if !IS_CORE
+ #define IS_FULL_CARTESIAN 1
+ #endif
+#endif
+
+#if DISABLED(DELTA)
+ #undef DELTA_HOME_TO_SAFE_ZONE
+#endif
+
+/**
+ * This setting is also used by M109 when trying to calculate
+ * a ballpark safe margin to prevent wait-forever situation.
+ */
+#ifndef EXTRUDE_MINTEMP
+ #define EXTRUDE_MINTEMP 170
+#endif
+
+#if ANY(PID_DEBUG, PID_BED_DEBUG, PID_CHAMBER_DEBUG)
+ #define HAS_PID_DEBUG 1
+#endif
+
+#if ALL(SPI_FLASH, HAS_MEDIA, MARLIN_DEV_MODE)
+ #define SPI_FLASH_BACKUP 1
+#endif
diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h
index 1028814c31..5724b3bc8b 100644
--- a/Marlin/src/inc/Conditionals_post.h
+++ b/Marlin/src/inc/Conditionals_post.h
@@ -2643,10 +2643,6 @@
#endif
// Thermal protection
-#if !HAS_HEATED_BED
- #undef THERMAL_PROTECTION_BED
- #undef THERMAL_PROTECTION_BED_PERIOD
-#endif
#if ENABLED(THERMAL_PROTECTION_HOTENDS) && WATCH_TEMP_PERIOD > 0
#define WATCH_HOTENDS 1
#endif
@@ -3194,8 +3190,13 @@
/**
* Heater, Fan, and Probe interactions
*/
-#if !HAS_FAN
+#if !ALL(HAS_HOTEND, HAS_FAN)
#undef ADAPTIVE_FAN_SLOWING
+#endif
+#if DISABLED(ADAPTIVE_FAN_SLOWING)
+ #undef REPORT_ADAPTIVE_FAN_SLOWING
+#endif
+#if DISABLED(ADAPTIVE_FAN_SLOWING) || NONE(MPCTEMP, PIDTEMP)
#undef TEMP_TUNING_MAINTAIN_FAN
#endif
#if !ALL(HAS_BED_PROBE, HAS_FAN)
diff --git a/Marlin/src/inc/MarlinConfigPre.h b/Marlin/src/inc/MarlinConfigPre.h
index 5ea7a49944..5ded14f703 100644
--- a/Marlin/src/inc/MarlinConfigPre.h
+++ b/Marlin/src/inc/MarlinConfigPre.h
@@ -55,7 +55,9 @@
#include "Version.h"
+#include "Conditionals_axes.h"
#include "Conditionals_LCD.h"
+#include "Conditionals_etc.h"
#ifndef __MARLIN_DEPS__
#include HAL_PATH(.., inc/Conditionals_LCD.h)