🏗️ Support for up to 6 linear axes (#19112)

Co-authored-by: Scott Lahteine <github@thinkyhead.com>
This commit is contained in:
DerAndere
2021-06-05 09:18:47 +02:00
committed by Scott Lahteine
parent d3c56a76e7
commit c1fca91103
98 changed files with 5040 additions and 2256 deletions

View File

@ -612,6 +612,12 @@
#ifndef LINEAR_AXES
#define LINEAR_AXES XYZ
#endif
#if LINEAR_AXES >= XY
#define HAS_Y_AXIS 1
#if LINEAR_AXES >= XYZ
#define HAS_Z_AXIS 1
#endif
#endif
/**
* Number of Logical Axes (e.g., XYZE)
@ -624,10 +630,6 @@
#define LOGICAL_AXES LINEAR_AXES
#endif
#if LINEAR_AXES >= XYZ
#define HAS_Z_AXIS 1
#endif
/**
* DISTINCT_E_FACTORS is set to give extruders (some) individual settings.
*
@ -852,6 +854,21 @@
#elif Z_HOME_DIR < 0
#define Z_HOME_TO_MIN 1
#endif
#if I_HOME_DIR > 0
#define I_HOME_TO_MAX 1
#elif I_HOME_DIR < 0
#define I_HOME_TO_MIN 1
#endif
#if J_HOME_DIR > 0
#define J_HOME_TO_MAX 1
#elif J_HOME_DIR < 0
#define J_HOME_TO_MIN 1
#endif
#if K_HOME_DIR > 0
#define K_HOME_TO_MAX 1
#elif K_HOME_DIR < 0
#define K_HOME_TO_MIN 1
#endif
/**
* Conditionals based on the type of Bed Probe
@ -1110,13 +1127,22 @@
#ifndef INVERT_X_DIR
#define INVERT_X_DIR false
#endif
#ifndef INVERT_Y_DIR
#if HAS_Y_AXIS && !defined(INVERT_Y_DIR)
#define INVERT_Y_DIR false
#endif
#ifndef INVERT_Z_DIR
#if HAS_Z_AXIS && !defined(INVERT_Z_DIR)
#define INVERT_Z_DIR false
#endif
#ifndef INVERT_E_DIR
#if LINEAR_AXES >= 4 && !defined(INVERT_I_DIR)
#define INVERT_I_DIR false
#endif
#if LINEAR_AXES >= 5 && !defined(INVERT_J_DIR)
#define INVERT_J_DIR false
#endif
#if LINEAR_AXES >= 6 && !defined(INVERT_K_DIR)
#define INVERT_K_DIR false
#endif
#if HAS_EXTRUDERS && !defined(INVERT_E_DIR)
#define INVERT_E_DIR false
#endif

View File

@ -26,6 +26,10 @@
* Defines that depend on advanced configuration.
*/
#ifndef AXIS_RELATIVE_MODES
#define AXIS_RELATIVE_MODES {}
#endif
#ifdef SWITCHING_NOZZLE_E1_SERVO_NR
#define SWITCHING_NOZZLE_TWO_SERVOS 1
#endif
@ -488,12 +492,26 @@
// Remove unused STEALTHCHOP flags
#if LINEAR_AXES < 6
#undef STEALTHCHOP_K
#undef CALIBRATION_MEASURE_KMIN
#undef CALIBRATION_MEASURE_KMAX
#if LINEAR_AXES < 5
#undef STEALTHCHOP_J
#undef CALIBRATION_MEASURE_JMIN
#undef CALIBRATION_MEASURE_JMAX
#if LINEAR_AXES < 4
#undef STEALTHCHOP_I
#undef CALIBRATION_MEASURE_IMIN
#undef CALIBRATION_MEASURE_IMAX
#if LINEAR_AXES < 3
#undef Z_IDLE_HEIGHT
#undef STEALTHCHOP_Z
#undef Z_PROBE_SLED
#undef Z_SAFE_HOMING
#undef HOME_Z_FIRST
#undef HOMING_Z_WITH_PROBE
#undef ENABLE_LEVELING_FADE_HEIGHT
#undef NUM_Z_STEPPER_DRIVERS
#undef CNC_WORKSPACE_PLANES
#if LINEAR_AXES < 2
#undef STEALTHCHOP_Y
#endif

View File

@ -78,17 +78,49 @@
/**
* Axis lengths and center
*/
#ifndef AXIS4_NAME
#define AXIS4_NAME 'A'
#endif
#ifndef AXIS5_NAME
#define AXIS5_NAME 'B'
#endif
#ifndef AXIS6_NAME
#define AXIS6_NAME 'C'
#endif
#define X_MAX_LENGTH (X_MAX_POS - (X_MIN_POS))
#define Y_MAX_LENGTH (Y_MAX_POS - (Y_MIN_POS))
#define Z_MAX_LENGTH (Z_MAX_POS - (Z_MIN_POS))
#if HAS_Y_AXIS
#define Y_MAX_LENGTH (Y_MAX_POS - (Y_MIN_POS))
#endif
#if HAS_Z_AXIS
#define Z_MAX_LENGTH (Z_MAX_POS - (Z_MIN_POS))
#endif
#if LINEAR_AXES >= 4
#define I_MAX_LENGTH (I_MAX_POS - (I_MIN_POS))
#endif
#if LINEAR_AXES >= 5
#define J_MAX_LENGTH (J_MAX_POS - (J_MIN_POS))
#endif
#if LINEAR_AXES >= 6
#define K_MAX_LENGTH (K_MAX_POS - (K_MIN_POS))
#endif
// Defined only if the sanity-check is bypassed
#ifndef X_BED_SIZE
#define X_BED_SIZE X_MAX_LENGTH
#endif
#ifndef Y_BED_SIZE
#if HAS_Y_AXIS && !defined(Y_BED_SIZE)
#define Y_BED_SIZE Y_MAX_LENGTH
#endif
#if LINEAR_AXES >= 4 && !defined(I_BED_SIZE)
#define I_BED_SIZE I_MAX_LENGTH
#endif
#if LINEAR_AXES >= 5 && !defined(J_BED_SIZE)
#define J_BED_SIZE J_MAX_LENGTH
#endif
#if LINEAR_AXES >= 6 && !defined(K_BED_SIZE)
#define K_BED_SIZE K_MAX_LENGTH
#endif
// Require 0,0 bed center for Delta and SCARA
#if IS_KINEMATIC
@ -97,16 +129,53 @@
// Define center values for future use
#define _X_HALF_BED ((X_BED_SIZE) / 2)
#define _Y_HALF_BED ((Y_BED_SIZE) / 2)
#if HAS_Y_AXIS
#define _Y_HALF_BED ((Y_BED_SIZE) / 2)
#endif
#if LINEAR_AXES >= 4
#define _I_HALF_IMAX ((I_BED_SIZE) / 2)
#endif
#if LINEAR_AXES >= 5
#define _J_HALF_JMAX ((J_BED_SIZE) / 2)
#endif
#if LINEAR_AXES >= 6
#define _K_HALF_KMAX ((K_BED_SIZE) / 2)
#endif
#define X_CENTER TERN(BED_CENTER_AT_0_0, 0, _X_HALF_BED)
#define Y_CENTER TERN(BED_CENTER_AT_0_0, 0, _Y_HALF_BED)
#define XY_CENTER { X_CENTER, Y_CENTER }
#if HAS_Y_AXIS
#define Y_CENTER TERN(BED_CENTER_AT_0_0, 0, _Y_HALF_BED)
#define XY_CENTER { X_CENTER, Y_CENTER }
#endif
#if LINEAR_AXES >= 4
#define I_CENTER TERN(BED_CENTER_AT_0_0, 0, _I_HALF_BED)
#endif
#if LINEAR_AXES >= 5
#define J_CENTER TERN(BED_CENTER_AT_0_0, 0, _J_HALF_BED)
#endif
#if LINEAR_AXES >= 6
#define K_CENTER TERN(BED_CENTER_AT_0_0, 0, _K_HALF_BED)
#endif
// Get the linear boundaries of the bed
#define X_MIN_BED (X_CENTER - _X_HALF_BED)
#define X_MAX_BED (X_MIN_BED + X_BED_SIZE)
#define Y_MIN_BED (Y_CENTER - _Y_HALF_BED)
#define Y_MAX_BED (Y_MIN_BED + Y_BED_SIZE)
#if HAS_Y_AXIS
#define Y_MIN_BED (Y_CENTER - _Y_HALF_BED)
#define Y_MAX_BED (Y_MIN_BED + Y_BED_SIZE)
#endif
#if LINEAR_AXES >= 4
#define I_MINIM (I_CENTER - _I_HALF_BED_SIZE)
#define I_MAXIM (I_MINIM + I_BED_SIZE)
#endif
#if LINEAR_AXES >= 5
#define J_MINIM (J_CENTER - _J_HALF_BED_SIZE)
#define J_MAXIM (J_MINIM + J_BED_SIZE)
#endif
#if LINEAR_AXES >= 6
#define K_MINIM (K_CENTER - _K_HALF_BED_SIZE)
#define K_MAXIM (K_MINIM + K_BED_SIZE)
#endif
/**
* Dual X Carriage
@ -163,14 +232,16 @@
#endif
#endif
#ifdef MANUAL_Y_HOME_POS
#define Y_HOME_POS MANUAL_Y_HOME_POS
#else
#define Y_END_POS TERN(Y_HOME_TO_MIN, Y_MIN_POS, Y_MAX_POS)
#if ENABLED(BED_CENTER_AT_0_0)
#define Y_HOME_POS TERN(DELTA, 0, Y_END_POS)
#if HAS_Y_AXIS
#ifdef MANUAL_Y_HOME_POS
#define Y_HOME_POS MANUAL_Y_HOME_POS
#else
#define Y_HOME_POS TERN(DELTA, Y_MIN_POS + (Y_BED_SIZE) * 0.5, Y_END_POS)
#define Y_END_POS TERN(Y_HOME_TO_MIN, Y_MIN_POS, Y_MAX_POS)
#if ENABLED(BED_CENTER_AT_0_0)
#define Y_HOME_POS TERN(DELTA, 0, Y_END_POS)
#else
#define Y_HOME_POS TERN(DELTA, Y_MIN_POS + (Y_BED_SIZE) * 0.5, Y_END_POS)
#endif
#endif
#endif
@ -180,6 +251,28 @@
#define Z_HOME_POS TERN(Z_HOME_TO_MIN, Z_MIN_POS, Z_MAX_POS)
#endif
#if LINEAR_AXES >= 4
#ifdef MANUAL_I_HOME_POS
#define I_HOME_POS MANUAL_I_HOME_POS
#else
#define I_HOME_POS TERN(I_HOME_TO_MIN, I_MIN_POS, I_MAX_POS)
#endif
#endif
#if LINEAR_AXES >= 5
#ifdef MANUAL_J_HOME_POS
#define J_HOME_POS MANUAL_J_HOME_POS
#else
#define J_HOME_POS TERN(J_HOME_TO_MIN, J_MIN_POS, J_MAX_POS)
#endif
#endif
#if LINEAR_AXES >= 6
#ifdef MANUAL_K_HOME_POS
#define K_HOME_POS MANUAL_K_HOME_POS
#else
#define K_HOME_POS TERN(K_HOME_TO_MIN, K_MIN_POS, K_MAX_POS)
#endif
#endif
/**
* If DELTA_HEIGHT isn't defined use the old setting
*/
@ -374,15 +467,24 @@
#ifndef DISABLE_INACTIVE_X
#define DISABLE_INACTIVE_X DISABLE_X
#endif
#ifndef DISABLE_INACTIVE_Y
#if HAS_Y_AXIS && !defined(DISABLE_INACTIVE_Y)
#define DISABLE_INACTIVE_Y DISABLE_Y
#endif
#ifndef DISABLE_INACTIVE_Z
#if HAS_Z_AXIS && !defined(DISABLE_INACTIVE_Z)
#define DISABLE_INACTIVE_Z DISABLE_Z
#endif
#ifndef DISABLE_INACTIVE_E
#define DISABLE_INACTIVE_E DISABLE_E
#endif
#if LINEAR_AXES >= 4 && !defined(DISABLE_INACTIVE_I)
#define DISABLE_INACTIVE_I DISABLE_I
#endif
#if LINEAR_AXES >= 5 && !defined(DISABLE_INACTIVE_J)
#define DISABLE_INACTIVE_J DISABLE_J
#endif
#if LINEAR_AXES >= 6 && !defined(DISABLE_INACTIVE_K)
#define DISABLE_INACTIVE_K DISABLE_K
#endif
/**
* Power Supply
@ -1418,6 +1520,15 @@
#if ENABLED(USE_ZMAX_PLUG)
#define ENDSTOPPULLUP_ZMAX
#endif
#if ENABLED(USE_IMAX_PLUG)
#define ENDSTOPPULLUP_IMAX
#endif
#if ENABLED(USE_JMAX_PLUG)
#define ENDSTOPPULLUP_JMAX
#endif
#if ENABLED(USE_KMAX_PLUG)
#define ENDSTOPPULLUP_KMAX
#endif
#if ENABLED(USE_XMIN_PLUG)
#define ENDSTOPPULLUP_XMIN
#endif
@ -1427,6 +1538,15 @@
#if ENABLED(USE_ZMIN_PLUG)
#define ENDSTOPPULLUP_ZMIN
#endif
#if ENABLED(USE_IMIN_PLUG)
#define ENDSTOPPULLUP_IMIN
#endif
#if ENABLED(USE_JMIN_PLUG)
#define ENDSTOPPULLUP_JMIN
#endif
#if ENABLED(USE_KMIN_PLUG)
#define ENDSTOPPULLUP_KMIN
#endif
#endif
/**
@ -1484,82 +1604,137 @@
#define HAS_X2_MS_PINS 1
#endif
#if PIN_EXISTS(Y_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Y))
#define HAS_Y_ENABLE 1
#endif
#if PIN_EXISTS(Y_DIR)
#define HAS_Y_DIR 1
#endif
#if PIN_EXISTS(Y_STEP)
#define HAS_Y_STEP 1
#endif
#if PIN_EXISTS(Y_MS1)
#define HAS_Y_MS_PINS 1
#if HAS_Y_AXIS
#if PIN_EXISTS(Y_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Y))
#define HAS_Y_ENABLE 1
#endif
#if PIN_EXISTS(Y_DIR)
#define HAS_Y_DIR 1
#endif
#if PIN_EXISTS(Y_STEP)
#define HAS_Y_STEP 1
#endif
#if PIN_EXISTS(Y_MS1)
#define HAS_Y_MS_PINS 1
#endif
#if PIN_EXISTS(Y2_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Y2))
#define HAS_Y2_ENABLE 1
#endif
#if PIN_EXISTS(Y2_DIR)
#define HAS_Y2_DIR 1
#endif
#if PIN_EXISTS(Y2_STEP)
#define HAS_Y2_STEP 1
#endif
#if PIN_EXISTS(Y2_MS1)
#define HAS_Y2_MS_PINS 1
#endif
#endif
#if PIN_EXISTS(Y2_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Y2))
#define HAS_Y2_ENABLE 1
#endif
#if PIN_EXISTS(Y2_DIR)
#define HAS_Y2_DIR 1
#endif
#if PIN_EXISTS(Y2_STEP)
#define HAS_Y2_STEP 1
#endif
#if PIN_EXISTS(Y2_MS1)
#define HAS_Y2_MS_PINS 1
#if HAS_Z_AXIS
#if PIN_EXISTS(Z_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z))
#define HAS_Z_ENABLE 1
#endif
#if PIN_EXISTS(Z_DIR)
#define HAS_Z_DIR 1
#endif
#if PIN_EXISTS(Z_STEP)
#define HAS_Z_STEP 1
#endif
#if PIN_EXISTS(Z_MS1)
#define HAS_Z_MS_PINS 1
#endif
#endif
#if PIN_EXISTS(Z_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z))
#define HAS_Z_ENABLE 1
#endif
#if PIN_EXISTS(Z_DIR)
#define HAS_Z_DIR 1
#endif
#if PIN_EXISTS(Z_STEP)
#define HAS_Z_STEP 1
#endif
#if PIN_EXISTS(Z_MS1)
#define HAS_Z_MS_PINS 1
#if NUM_Z_STEPPER_DRIVERS >= 2
#if PIN_EXISTS(Z2_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z2))
#define HAS_Z2_ENABLE 1
#endif
#if PIN_EXISTS(Z2_DIR)
#define HAS_Z2_DIR 1
#endif
#if PIN_EXISTS(Z2_STEP)
#define HAS_Z2_STEP 1
#endif
#if PIN_EXISTS(Z2_MS1)
#define HAS_Z2_MS_PINS 1
#endif
#endif
#if PIN_EXISTS(Z2_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z2))
#define HAS_Z2_ENABLE 1
#endif
#if PIN_EXISTS(Z2_DIR)
#define HAS_Z2_DIR 1
#endif
#if PIN_EXISTS(Z2_STEP)
#define HAS_Z2_STEP 1
#endif
#if PIN_EXISTS(Z2_MS1)
#define HAS_Z2_MS_PINS 1
#if NUM_Z_STEPPER_DRIVERS >= 3
#if PIN_EXISTS(Z3_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z3))
#define HAS_Z3_ENABLE 1
#endif
#if PIN_EXISTS(Z3_DIR)
#define HAS_Z3_DIR 1
#endif
#if PIN_EXISTS(Z3_STEP)
#define HAS_Z3_STEP 1
#endif
#if PIN_EXISTS(Z3_MS1)
#define HAS_Z3_MS_PINS 1
#endif
#endif
#if PIN_EXISTS(Z3_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z3))
#define HAS_Z3_ENABLE 1
#endif
#if PIN_EXISTS(Z3_DIR)
#define HAS_Z3_DIR 1
#endif
#if PIN_EXISTS(Z3_STEP)
#define HAS_Z3_STEP 1
#endif
#if PIN_EXISTS(Z3_MS1)
#define HAS_Z3_MS_PINS 1
#if NUM_Z_STEPPER_DRIVERS >= 4
#if PIN_EXISTS(Z4_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z4))
#define HAS_Z4_ENABLE 1
#endif
#if PIN_EXISTS(Z4_DIR)
#define HAS_Z4_DIR 1
#endif
#if PIN_EXISTS(Z4_STEP)
#define HAS_Z4_STEP 1
#endif
#if PIN_EXISTS(Z4_MS1)
#define HAS_Z4_MS_PINS 1
#endif
#endif
#if PIN_EXISTS(Z4_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(Z4))
#define HAS_Z4_ENABLE 1
#if LINEAR_AXES >= 4
#if PIN_EXISTS(I_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(I))
#define HAS_I_ENABLE 1
#endif
#if PIN_EXISTS(I_DIR)
#define HAS_I_DIR 1
#endif
#if PIN_EXISTS(I_STEP)
#define HAS_I_STEP 1
#endif
#if PIN_EXISTS(I_MS1)
#define HAS_I_MS_PINS 1
#endif
#endif
#if PIN_EXISTS(Z4_DIR)
#define HAS_Z4_DIR 1
#if LINEAR_AXES >= 5
#if PIN_EXISTS(J_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(J))
#define HAS_J_ENABLE 1
#endif
#if PIN_EXISTS(J_DIR)
#define HAS_J_DIR 1
#endif
#if PIN_EXISTS(J_STEP)
#define HAS_J_STEP 1
#endif
#if PIN_EXISTS(J_MS1)
#define HAS_J_MS_PINS 1
#endif
#endif
#if PIN_EXISTS(Z4_STEP)
#define HAS_Z4_STEP 1
#endif
#if PIN_EXISTS(Z4_MS1)
#define HAS_Z4_MS_PINS 1
#if LINEAR_AXES >= 6
#if PIN_EXISTS(K_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(K))
#define HAS_K_ENABLE 1
#endif
#if PIN_EXISTS(K_DIR)
#define HAS_K_DIR 1
#endif
#if PIN_EXISTS(K_STEP)
#define HAS_K_STEP 1
#endif
#if PIN_EXISTS(K_MS1)
#define HAS_K_MS_PINS 1
#endif
#endif
// Extruder steppers and solenoids
@ -1700,7 +1875,7 @@
//
#if HAS_TRINAMIC_CONFIG
#if ANY(STEALTHCHOP_XY, STEALTHCHOP_Z, STEALTHCHOP_E)
#if ANY(STEALTHCHOP_E, STEALTHCHOP_XY, STEALTHCHOP_Z, STEALTHCHOP_I, STEALTHCHOP_J, STEALTHCHOP_K)
#define STEALTHCHOP_ENABLED 1
#endif
#if EITHER(SENSORLESS_HOMING, SENSORLESS_PROBING)
@ -1737,6 +1912,65 @@
#if defined(Z4_STALL_SENSITIVITY) && AXIS_HAS_STALLGUARD(Z4)
#define Z4_SENSORLESS 1
#endif
#if AXIS_HAS_STEALTHCHOP(X)
#define X_HAS_STEALTHCHOP 1
#endif
#if AXIS_HAS_STEALTHCHOP(X2)
#define X2_HAS_STEALTHCHOP 1
#endif
#if AXIS_HAS_STEALTHCHOP(Y)
#define Y_HAS_STEALTHCHOP 1
#endif
#if AXIS_HAS_STEALTHCHOP(Y2)
#define Y2_HAS_STEALTHCHOP 1
#endif
#if AXIS_HAS_STEALTHCHOP(Z)
#define Z_HAS_STEALTHCHOP 1
#endif
#if AXIS_HAS_STEALTHCHOP(Z2)
#define Z2_HAS_STEALTHCHOP 1
#endif
#if AXIS_HAS_STEALTHCHOP(Z3)
#define Z3_HAS_STEALTHCHOP 1
#endif
#if AXIS_HAS_STEALTHCHOP(Z4)
#define Z4_HAS_STEALTHCHOP 1
#endif
#if AXIS_HAS_STEALTHCHOP(I)
#define I_HAS_STEALTHCHOP 1
#endif
#if AXIS_HAS_STEALTHCHOP(J)
#define J_HAS_STEALTHCHOP 1
#endif
#if AXIS_HAS_STEALTHCHOP(K)
#define K_HAS_STEALTHCHOP 1
#endif
#if E_STEPPERS > 0 && AXIS_HAS_STEALTHCHOP(E0)
#define E0_HAS_STEALTHCHOP 1
#endif
#if E_STEPPERS > 1 && AXIS_HAS_STEALTHCHOP(E1)
#define E1_HAS_STEALTHCHOP 1
#endif
#if E_STEPPERS > 2 && AXIS_HAS_STEALTHCHOP(E2)
#define E2_HAS_STEALTHCHOP 1
#endif
#if E_STEPPERS > 3 && AXIS_HAS_STEALTHCHOP(E3)
#define E3_HAS_STEALTHCHOP 1
#endif
#if E_STEPPERS > 4 && AXIS_HAS_STEALTHCHOP(E4)
#define E4_HAS_STEALTHCHOP 1
#endif
#if E_STEPPERS > 5 && AXIS_HAS_STEALTHCHOP(E5)
#define E5_HAS_STEALTHCHOP 1
#endif
#if E_STEPPERS > 6 && AXIS_HAS_STEALTHCHOP(E6)
#define E6_HAS_STEALTHCHOP 1
#endif
#if E_STEPPERS > 7 && AXIS_HAS_STEALTHCHOP(E7)
#define E7_HAS_STEALTHCHOP 1
#endif
#if ENABLED(SPI_ENDSTOPS)
#define X_SPI_SENSORLESS X_SENSORLESS
#define Y_SPI_SENSORLESS Y_SENSORLESS
@ -1766,6 +2000,21 @@
#ifndef Z4_INTERPOLATE
#define Z4_INTERPOLATE INTERPOLATE
#endif
#if LINEAR_AXES >= 4
#ifndef I_INTERPOLATE
#define I_INTERPOLATE INTERPOLATE
#endif
#endif
#if LINEAR_AXES >= 5
#ifndef J_INTERPOLATE
#define J_INTERPOLATE INTERPOLATE
#endif
#endif
#if LINEAR_AXES >= 6
#ifndef K_INTERPOLATE
#define K_INTERPOLATE INTERPOLATE
#endif
#endif
#ifndef E0_INTERPOLATE
#define E0_INTERPOLATE INTERPOLATE
#endif
@ -1799,6 +2048,15 @@
#ifndef Z_SLAVE_ADDRESS
#define Z_SLAVE_ADDRESS 0
#endif
#ifndef I_SLAVE_ADDRESS
#define I_SLAVE_ADDRESS 0
#endif
#ifndef J_SLAVE_ADDRESS
#define J_SLAVE_ADDRESS 0
#endif
#ifndef K_SLAVE_ADDRESS
#define K_SLAVE_ADDRESS 0
#endif
#ifndef X2_SLAVE_ADDRESS
#define X2_SLAVE_ADDRESS 0
#endif
@ -1853,6 +2111,10 @@
#define HAS_TMC_SW_SERIAL 1
#endif
#if !USE_SENSORLESS
#undef SENSORLESS_BACKOFF_MM
#endif
//
// Set USING_HW_SERIALn flags for used Serial Ports
//
@ -1972,18 +2234,36 @@
#if _HAS_STOP(X,MAX)
#define HAS_X_MAX 1
#endif
#if _HAS_STOP(Y,MIN)
#if HAS_Y_AXIS && _HAS_STOP(Y,MIN)
#define HAS_Y_MIN 1
#endif
#if _HAS_STOP(Y,MAX)
#if HAS_Y_AXIS && _HAS_STOP(Y,MAX)
#define HAS_Y_MAX 1
#endif
#if _HAS_STOP(Z,MIN)
#if BOTH(HAS_Z_AXIS, USE_ZMIN_PLUG) && _HAS_STOP(Z,MIN)
#define HAS_Z_MIN 1
#endif
#if _HAS_STOP(Z,MAX)
#if BOTH(HAS_Z_AXIS, USE_ZMAX_PLUG) && _HAS_STOP(Z,MAX)
#define HAS_Z_MAX 1
#endif
#if _HAS_STOP(I,MIN)
#define HAS_I_MIN 1
#endif
#if _HAS_STOP(I,MAX)
#define HAS_I_MAX 1
#endif
#if _HAS_STOP(J,MIN)
#define HAS_J_MIN 1
#endif
#if _HAS_STOP(J,MAX)
#define HAS_J_MAX 1
#endif
#if _HAS_STOP(K,MIN)
#define HAS_K_MIN 1
#endif
#if _HAS_STOP(K,MAX)
#define HAS_K_MAX 1
#endif
#if PIN_EXISTS(X2_MIN)
#define HAS_X2_MIN 1
#endif
@ -2365,7 +2645,7 @@
#if ANY(HAS_E0_MS_PINS, HAS_E1_MS_PINS, HAS_E2_MS_PINS, HAS_E3_MS_PINS, HAS_E4_MS_PINS, HAS_E5_MS_PINS, HAS_E6_MS_PINS, HAS_E7_MS_PINS)
#define HAS_SOME_E_MS_PINS 1
#endif
#if ANY(HAS_X_MS_PINS, HAS_X2_MS_PINS, HAS_Y_MS_PINS, HAS_Y2_MS_PINS, HAS_SOME_Z_MS_PINS, HAS_SOME_E_MS_PINS)
#if ANY(HAS_X_MS_PINS, HAS_X2_MS_PINS, HAS_Y_MS_PINS, HAS_Y2_MS_PINS, HAS_SOME_Z_MS_PINS, HAS_I_MS_PINS, HAS_J_MS_PINS, HAS_K_MS_PINS, HAS_SOME_E_MS_PINS)
#define HAS_MICROSTEPS 1
#endif

View File

@ -34,6 +34,10 @@
#error "Marlin requires C++11 support (gcc >= 4.7, Arduino IDE >= 1.6.8). Please upgrade your toolchain."
#endif
// Strings for sanity check messages
#define _LINEAR_AXES_STR LINEAR_AXIS_GANG("X ", "Y ", "Z ", "I ", "J ", "K ")
#define _LOGICAL_AXES_STR LOGICAL_AXIS_GANG("E ", "X ", "Y ", "Z ", "I ", "J ", "K ")
// Make sure macros aren't borked
#define TEST1
#define TEST2 1
@ -566,6 +570,9 @@
#error "NEOPIXEL_BKGD_LED_INDEX is now NEOPIXEL_BKGD_INDEX_FIRST."
#endif
constexpr float sbm[] = AXIS_RELATIVE_MODES;
static_assert(COUNT(sbm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _LOGICAL_AXES_STR "elements.");
/**
* Probe temp compensation requirements
*/
@ -644,14 +651,18 @@
#if ENABLED(Y_DUAL_STEPPER_DRIVERS) && !GOOD_AXIS_PINS(Y)
#error "Y_DUAL_STEPPER_DRIVERS requires Y2 pins to be defined."
#elif !WITHIN(NUM_Z_STEPPER_DRIVERS, 1, 4)
#error "NUM_Z_STEPPER_DRIVERS must be an integer from 1 to 4."
#elif NUM_Z_STEPPER_DRIVERS == 2 && !GOOD_AXIS_PINS(Z2)
#error "If NUM_Z_STEPPER_DRIVERS is 2, you must define stepper pins for Z2."
#elif NUM_Z_STEPPER_DRIVERS == 3 && !(GOOD_AXIS_PINS(Z2) && GOOD_AXIS_PINS(Z3))
#error "If NUM_Z_STEPPER_DRIVERS is 3, you must define stepper pins for Z2 and Z3."
#elif NUM_Z_STEPPER_DRIVERS == 4 && !(GOOD_AXIS_PINS(Z2) && GOOD_AXIS_PINS(Z3) && GOOD_AXIS_PINS(Z4))
#error "If NUM_Z_STEPPER_DRIVERS is 4, you must define stepper pins for Z2, Z3, and Z4."
#endif
#if HAS_Z_AXIS
#if !WITHIN(NUM_Z_STEPPER_DRIVERS, 1, 4)
#error "NUM_Z_STEPPER_DRIVERS must be an integer from 1 to 4."
#elif NUM_Z_STEPPER_DRIVERS == 2 && !GOOD_AXIS_PINS(Z2)
#error "If NUM_Z_STEPPER_DRIVERS is 2, you must define stepper pins for Z2."
#elif NUM_Z_STEPPER_DRIVERS == 3 && !(GOOD_AXIS_PINS(Z2) && GOOD_AXIS_PINS(Z3))
#error "If NUM_Z_STEPPER_DRIVERS is 3, you must define stepper pins for Z2 and Z3."
#elif NUM_Z_STEPPER_DRIVERS == 4 && !(GOOD_AXIS_PINS(Z2) && GOOD_AXIS_PINS(Z3) && GOOD_AXIS_PINS(Z4))
#error "If NUM_Z_STEPPER_DRIVERS is 4, you must define stepper pins for Z2, Z3, and Z4."
#endif
#endif
/**
@ -704,6 +715,12 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#error "Enable only one of ENDSTOPPULLUP_Y_MIN or ENDSTOPPULLDOWN_Y_MIN."
#elif BOTH(ENDSTOPPULLUP_ZMIN, ENDSTOPPULLDOWN_ZMIN)
#error "Enable only one of ENDSTOPPULLUP_Z_MIN or ENDSTOPPULLDOWN_Z_MIN."
#elif BOTH(ENDSTOPPULLUP_IMIN, ENDSTOPPULLDOWN_IMIN)
#error "Enable only one of ENDSTOPPULLUP_I_MIN or ENDSTOPPULLDOWN_I_MIN."
#elif BOTH(ENDSTOPPULLUP_JMIN, ENDSTOPPULLDOWN_JMIN)
#error "Enable only one of ENDSTOPPULLUP_J_MIN or ENDSTOPPULLDOWN_J_MIN."
#elif BOTH(ENDSTOPPULLUP_KMIN, ENDSTOPPULLDOWN_KMIN)
#error "Enable only one of ENDSTOPPULLUP_K_MIN or ENDSTOPPULLDOWN_K_MIN."
#endif
/**
@ -926,6 +943,13 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
static_assert(WITHIN(npp_xyz.z, Z_MIN_POS, Z_MAX_POS), "NOZZLE_PARK_POINT.Z is out of bounds (Z_MIN_POS, Z_MAX_POS).");
#endif
/**
* Instant Freeze
*/
#if ENABLED(FREEZE_FEATURE) && !PIN_EXISTS(FREEZE)
#error "FREEZE_FEATURE requires a FREEZE_PIN to be defined."
#endif
/**
* Individual axis homing is useless for DELTAS
*/
@ -1266,6 +1290,42 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#error "To use CHAMBER_LIMIT_SWITCHING you must disable PIDTEMPCHAMBER."
#endif
/**
* Features that require a min/max/specific LINEAR_AXES
*/
#if HAS_LEVELING && !HAS_Z_AXIS
#error "Leveling in Marlin requires three or more axes, with Z as the vertical axis."
#elif ENABLED(CNC_WORKSPACE_PLANES) && !HAS_Z_AXIS
#error "CNC_WORKSPACE_PLANES currently requires LINEAR_AXES >= 3"
#elif ENABLED(DIRECT_STEPPING) && LINEAR_AXES > XYZ
#error "DIRECT_STEPPING currently requires LINEAR_AXES 3"
#elif ENABLED(FOAMCUTTER_XYUV) && LINEAR_AXES < 5
#error "FOAMCUTTER_XYUV requires LINEAR_AXES >= 5."
#endif
/**
* Allow only extra axis codes that do not conflict with G-code parameter names
*/
#if LINEAR_AXES >= 4
#if AXIS4_NAME != 'A' && AXIS4_NAME != 'B' && AXIS4_NAME != 'C' && AXIS4_NAME != 'U' && AXIS4_NAME != 'V' && AXIS4_NAME != 'W'
#error "AXIS4_NAME can only be one of 'A', 'B', 'C', 'U', 'V', or 'W'."
#endif
#endif
#if LINEAR_AXES >= 5
#if AXIS5_NAME == AXIS4_NAME || AXIS5_NAME == AXIS6_NAME
#error "AXIS5_NAME must be different from AXIS4_NAME and AXIS6_NAME"
#elif AXIS5_NAME != 'A' && AXIS5_NAME != 'B' && AXIS5_NAME != 'C' && AXIS5_NAME != 'U' && AXIS5_NAME != 'V' && AXIS5_NAME != 'W'
#error "AXIS5_NAME can only be one of 'A', 'B', 'C', 'U', 'V', or 'W'."
#endif
#endif
#if LINEAR_AXES >= 6
#if AXIS6_NAME == AXIS5_NAME || AXIS6_NAME == AXIS4_NAME
#error "AXIS6_NAME must be different from AXIS5_NAME and AXIS4_NAME."
#elif AXIS6_NAME != 'A' && AXIS6_NAME != 'B' && AXIS6_NAME != 'C' && AXIS6_NAME != 'U' && AXIS6_NAME != 'V' && AXIS6_NAME != 'W'
#error "AXIS6_NAME can only be one of 'A', 'B', 'C', 'U', 'V', or 'W'."
#endif
#endif
/**
* Kinematics
*/
@ -1273,8 +1333,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
/**
* Allow only one kinematic type to be defined
*/
#if MANY(DELTA, MORGAN_SCARA, MP_SCARA, AXEL_TPARA, COREXY, COREXZ, COREYZ, COREYX, COREZX, COREZY, MARKFORGED_XY)
#error "Please enable only one of DELTA, MORGAN_SCARA, AXEL_TPARA, COREXY, COREYX, COREXZ, COREZX, COREYZ, COREZY, or MARKFORGED_XY."
#if MANY(DELTA, MORGAN_SCARA, MP_SCARA, AXEL_TPARA, COREXY, COREXZ, COREYZ, COREYX, COREZX, COREZY, MARKFORGED_XY, FOAMCUTTER_XYUV)
#error "Please enable only one of DELTA, MORGAN_SCARA, MP_SCARA, AXEL_TPARA, COREXY, COREXZ, COREYZ, COREYX, COREZX, COREZY, MARKFORGED_XY, or FOAMCUTTER_XYUV."
#endif
/**
@ -1597,15 +1657,60 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#endif
/**
* Homing
* Homing checks
*/
constexpr float hbm[] = HOMING_BUMP_MM;
static_assert(COUNT(hbm) == LINEAR_AXES, "HOMING_BUMP_MM requires one element per linear axis.");
LINEAR_AXIS_CODE(
static_assert(hbm[X_AXIS] >= 0, "HOMING_BUMP_MM.X must be greater than or equal to 0."),
static_assert(hbm[Y_AXIS] >= 0, "HOMING_BUMP_MM.Y must be greater than or equal to 0."),
static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal to 0.")
);
#ifndef HOMING_BUMP_MM
#error "Required setting HOMING_BUMP_MM is missing!"
#elif !defined(HOMING_BUMP_DIVISOR)
#error "Required setting HOMING_BUMP_DIVISOR is missing!"
#else
constexpr float hbm[] = HOMING_BUMP_MM, hbd[] = HOMING_BUMP_DIVISOR;
static_assert(COUNT(hbm) == LINEAR_AXES, "HOMING_BUMP_MM must have " _LINEAR_AXES_STR "elements (and no others).");
LINEAR_AXIS_CODE(
static_assert(hbm[X_AXIS] >= 0, "HOMING_BUMP_MM.X must be greater than or equal to 0."),
static_assert(hbm[Y_AXIS] >= 0, "HOMING_BUMP_MM.Y must be greater than or equal to 0."),
static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal to 0."),
static_assert(hbm[I_AXIS] >= 0, "HOMING_BUMP_MM.I must be greater than or equal to 0."),
static_assert(hbm[J_AXIS] >= 0, "HOMING_BUMP_MM.J must be greater than or equal to 0."),
static_assert(hbm[K_AXIS] >= 0, "HOMING_BUMP_MM.K must be greater than or equal to 0.")
);
static_assert(COUNT(hbd) == LINEAR_AXES, "HOMING_BUMP_DIVISOR must have " _LINEAR_AXES_STR "elements (and no others).");
LINEAR_AXIS_CODE(
static_assert(hbd[X_AXIS] >= 1, "HOMING_BUMP_DIVISOR.X must be greater than or equal to 1."),
static_assert(hbd[Y_AXIS] >= 1, "HOMING_BUMP_DIVISOR.Y must be greater than or equal to 1."),
static_assert(hbd[Z_AXIS] >= 1, "HOMING_BUMP_DIVISOR.Z must be greater than or equal to 1."),
static_assert(hbd[I_AXIS] >= 1, "HOMING_BUMP_DIVISOR.I must be greater than or equal to 1."),
static_assert(hbd[J_AXIS] >= 1, "HOMING_BUMP_DIVISOR.J must be greater than or equal to 1."),
static_assert(hbd[K_AXIS] >= 1, "HOMING_BUMP_DIVISOR.K must be greater than or equal to 1.")
);
#endif
#ifdef HOMING_BACKOFF_POST_MM
constexpr float hbp[] = HOMING_BACKOFF_POST_MM;
static_assert(COUNT(hbp) == LINEAR_AXES, "HOMING_BACKOFF_POST_MM must have " _LINEAR_AXES_STR "elements (and no others).");
LINEAR_AXIS_CODE(
static_assert(hbp[X_AXIS] >= 0, "HOMING_BACKOFF_POST_MM.X must be greater than or equal to 0."),
static_assert(hbp[Y_AXIS] >= 0, "HOMING_BACKOFF_POST_MM.Y must be greater than or equal to 0."),
static_assert(hbp[Z_AXIS] >= 0, "HOMING_BACKOFF_POST_MM.Z must be greater than or equal to 0."),
static_assert(hbp[I_AXIS] >= 0, "HOMING_BACKOFF_POST_MM.I must be greater than or equal to 0."),
static_assert(hbp[J_AXIS] >= 0, "HOMING_BACKOFF_POST_MM.J must be greater than or equal to 0."),
static_assert(hbp[K_AXIS] >= 0, "HOMING_BACKOFF_POST_MM.K must be greater than or equal to 0.")
);
#endif
#ifdef SENSORLESS_BACKOFF_MM
constexpr float sbm[] = SENSORLESS_BACKOFF_MM;
static_assert(COUNT(sbm) == LINEAR_AXES, "SENSORLESS_BACKOFF_MM must have " _LINEAR_AXES_STR "elements (and no others).");
LINEAR_AXIS_CODE(
static_assert(sbm[X_AXIS] >= 0, "SENSORLESS_BACKOFF_MM.X must be greater than or equal to 0."),
static_assert(sbm[Y_AXIS] >= 0, "SENSORLESS_BACKOFF_MM.Y must be greater than or equal to 0."),
static_assert(sbm[Z_AXIS] >= 0, "SENSORLESS_BACKOFF_MM.Z must be greater than or equal to 0."),
static_assert(sbm[I_AXIS] >= 0, "SENSORLESS_BACKOFF_MM.I must be greater than or equal to 0."),
static_assert(sbm[J_AXIS] >= 0, "SENSORLESS_BACKOFF_MM.J must be greater than or equal to 0."),
static_assert(sbm[K_AXIS] >= 0, "SENSORLESS_BACKOFF_MM.K must be greater than or equal to 0.")
);
#endif
#if ENABLED(CODEPENDENT_XY_HOMING)
#if ENABLED(QUICK_HOME)
#error "QUICK_HOME is incompatible with CODEPENDENT_XY_HOMING."
@ -1625,9 +1730,9 @@ LINEAR_AXIS_CODE(
/**
* Make sure DISABLE_[XYZ] compatible with selected homing options
*/
#if ANY(DISABLE_X, DISABLE_Y, DISABLE_Z)
#if ANY(DISABLE_X, DISABLE_Y, DISABLE_Z, DISABLE_I, DISABLE_J, DISABLE_K)
#if EITHER(HOME_AFTER_DEACTIVATE, Z_SAFE_HOMING)
#error "DISABLE_[XYZ] is not compatible with HOME_AFTER_DEACTIVATE or Z_SAFE_HOMING."
#error "DISABLE_[XYZIJK] is not compatible with HOME_AFTER_DEACTIVATE or Z_SAFE_HOMING."
#endif
#endif
@ -2085,7 +2190,7 @@ LINEAR_AXIS_CODE(
#define _PLUG_UNUSED_TEST(A,P) (DISABLED(USE_##P##MIN_PLUG, USE_##P##MAX_PLUG) \
&& !(ENABLED(A##_DUAL_ENDSTOPS) && WITHIN(A##2_USE_ENDSTOP, _##P##MAX_, _##P##MIN_)) \
&& !(ENABLED(A##_MULTI_ENDSTOPS) && WITHIN(A##2_USE_ENDSTOP, _##P##MAX_, _##P##MIN_)) )
#define _AXIS_PLUG_UNUSED_TEST(A) (_PLUG_UNUSED_TEST(A,X) && _PLUG_UNUSED_TEST(A,Y) && _PLUG_UNUSED_TEST(A,Z))
#define _AXIS_PLUG_UNUSED_TEST(A) (1 LINEAR_AXIS_GANG(&& _PLUG_UNUSED_TEST(A,X), && _PLUG_UNUSED_TEST(A,Y), && _PLUG_UNUSED_TEST(A,Z), && _PLUG_UNUSED_TEST(A,I), && _PLUG_UNUSED_TEST(A,J), && _PLUG_UNUSED_TEST(A,K) ) )
// A machine with endstops must have a minimum of 3
#if HAS_ENDSTOPS
@ -2098,6 +2203,15 @@ LINEAR_AXIS_CODE(
#if _AXIS_PLUG_UNUSED_TEST(Z)
#error "You must enable USE_ZMIN_PLUG or USE_ZMAX_PLUG."
#endif
#if LINEAR_AXES >= 4 && _AXIS_PLUG_UNUSED_TEST(I)
#error "You must enable USE_IMIN_PLUG or USE_IMAX_PLUG."
#endif
#if LINEAR_AXES >= 5 && _AXIS_PLUG_UNUSED_TEST(J)
#error "You must enable USE_JMIN_PLUG or USE_JMAX_PLUG."
#endif
#if LINEAR_AXES >= 6 && _AXIS_PLUG_UNUSED_TEST(K)
#error "You must enable USE_KMIN_PLUG or USE_KMAX_PLUG."
#endif
// Delta and Cartesian use 3 homing endstops
#if NONE(IS_SCARA, SPI_ENDSTOPS)
@ -2109,6 +2223,18 @@ LINEAR_AXIS_CODE(
#error "Enable USE_YMIN_PLUG when homing Y to MIN."
#elif Y_HOME_TO_MAX && DISABLED(USE_YMAX_PLUG)
#error "Enable USE_YMAX_PLUG when homing Y to MAX."
#elif LINEAR_AXES >= 4 && I_HOME_TO_MIN && DISABLED(USE_IMIN_PLUG)
#error "Enable USE_IMIN_PLUG when homing I to MIN."
#elif LINEAR_AXES >= 4 && I_HOME_TO_MAX && DISABLED(USE_IMAX_PLUG)
#error "Enable USE_IMAX_PLUG when homing I to MAX."
#elif LINEAR_AXES >= 5 && J_HOME_TO_MIN && DISABLED(USE_JMIN_PLUG)
#error "Enable USE_JMIN_PLUG when homing J to MIN."
#elif LINEAR_AXES >= 5 && J_HOME_TO_MAX && DISABLED(USE_JMAX_PLUG)
#error "Enable USE_JMAX_PLUG when homing J to MAX."
#elif LINEAR_AXES >= 6 && K_HOME_TO_MIN && DISABLED(USE_KMIN_PLUG)
#error "Enable USE_KMIN_PLUG when homing K to MIN."
#elif LINEAR_AXES >= 6 && K_HOME_TO_MAX && DISABLED(USE_KMAX_PLUG)
#error "Enable USE_KMAX_PLUG when homing K to MAX."
#endif
#endif
@ -2503,6 +2629,12 @@ LINEAR_AXIS_CODE(
#error "An SPI driven TMC driver on E6 requires E6_CS_PIN."
#elif INVALID_TMC_SPI(E7)
#error "An SPI driven TMC driver on E7 requires E7_CS_PIN."
#elif INVALID_TMC_SPI(I)
#error "An SPI driven TMC on I requires I_CS_PIN."
#elif INVALID_TMC_SPI(J)
#error "An SPI driven TMC on J requires J_CS_PIN."
#elif INVALID_TMC_SPI(K)
#error "An SPI driven TMC on K requires K_CS_PIN."
#endif
#undef INVALID_TMC_SPI
@ -2542,6 +2674,12 @@ LINEAR_AXIS_CODE(
#error "TMC2208 or TMC2209 on E6 requires E6_HARDWARE_SERIAL or E6_SERIAL_(RX|TX)_PIN."
#elif INVALID_TMC_UART(E7)
#error "TMC2208 or TMC2209 on E7 requires E7_HARDWARE_SERIAL or E7_SERIAL_(RX|TX)_PIN."
#elif LINEAR_AXES >= 4 && INVALID_TMC_UART(I)
#error "TMC2208 or TMC2209 on I requires I_HARDWARE_SERIAL or I_SERIAL_(RX|TX)_PIN."
#elif LINEAR_AXES >= 5 && INVALID_TMC_UART(J)
#error "TMC2208 or TMC2209 on J requires J_HARDWARE_SERIAL or J_SERIAL_(RX|TX)_PIN."
#elif LINEAR_AXES >= 6 && INVALID_TMC_UART(K)
#error "TMC2208 or TMC2209 on K requires K_HARDWARE_SERIAL or K_SERIAL_(RX|TX)_PIN."
#endif
#undef INVALID_TMC_UART
@ -2565,6 +2703,12 @@ LINEAR_AXIS_CODE(
INVALID_TMC_ADDRESS(Z3);
#elif AXIS_DRIVER_TYPE_Z4(TMC2209)
INVALID_TMC_ADDRESS(Z4);
#elif AXIS_DRIVER_TYPE_I(TMC2209)
INVALID_TMC_ADDRESS(I);
#elif AXIS_DRIVER_TYPE_J(TMC2209)
INVALID_TMC_ADDRESS(J);
#elif AXIS_DRIVER_TYPE_K(TMC2209)
INVALID_TMC_ADDRESS(K);
#elif AXIS_DRIVER_TYPE_E0(TMC2209)
INVALID_TMC_ADDRESS(E0);
#elif AXIS_DRIVER_TYPE_E1(TMC2209)
@ -2620,6 +2764,12 @@ LINEAR_AXIS_CODE(
INVALID_TMC_MS(E6)
#elif !TMC_MICROSTEP_IS_VALID(E7)
INVALID_TMC_MS(E7)
#elif LINEAR_AXES >= 4 && !TMC_MICROSTEP_IS_VALID(I)
INVALID_TMC_MS(I)
#elif LINEAR_AXES >= 5 && !TMC_MICROSTEP_IS_VALID(J)
INVALID_TMC_MS(J)
#elif LINEAR_AXES >= 6 && !TMC_MICROSTEP_IS_VALID(K)
INVALID_TMC_MS(K)
#endif
#undef INVALID_TMC_MS
#undef TMC_MICROSTEP_IS_VALID
@ -2640,6 +2790,15 @@ LINEAR_AXIS_CODE(
#define X_ENDSTOP_INVERTING !AXIS_DRIVER_TYPE(X,TMC2209)
#define Y_ENDSTOP_INVERTING !AXIS_DRIVER_TYPE(Y,TMC2209)
#define Z_ENDSTOP_INVERTING !AXIS_DRIVER_TYPE(Z,TMC2209)
#if LINEAR_AXES >= 4
#define I_ENDSTOP_INVERTING !AXIS_DRIVER_TYPE(I,TMC2209)
#endif
#if LINEAR_AXES >= 5
#define J_ENDSTOP_INVERTING !AXIS_DRIVER_TYPE(J,TMC2209)
#endif
#if LINEAR_AXES >= 6
#define K_ENDSTOP_INVERTING !AXIS_DRIVER_TYPE(K,TMC2209)
#endif
#if NONE(SPI_ENDSTOPS, ONBOARD_ENDSTOPPULLUPS, ENDSTOPPULLUPS)
#if X_SENSORLESS && X_HOME_TO_MIN && DISABLED(ENDSTOPPULLUP_XMIN)
@ -2654,6 +2813,12 @@ LINEAR_AXIS_CODE(
#error "SENSORLESS_HOMING requires ENDSTOPPULLUP_ZMIN (or ENDSTOPPULLUPS) when homing to Z_MIN."
#elif Z_SENSORLESS && Z_HOME_TO_MAX && DISABLED(ENDSTOPPULLUP_ZMAX)
#error "SENSORLESS_HOMING requires ENDSTOPPULLUP_ZMAX (or ENDSTOPPULLUPS) when homing to Z_MAX."
#elif LINEAR_AXES >= 4 && I_SENSORLESS && I_HOME_TO_MAX && DISABLED(ENDSTOPPULLUP_IMAX)
#error "SENSORLESS_HOMING requires ENDSTOPPULLUP_IMAX (or ENDSTOPPULLUPS) when homing to I_MAX."
#elif LINEAR_AXES >= 5 && J_SENSORLESS && J_HOME_TO_MAX && DISABLED(ENDSTOPPULLUP_JMAX)
#error "SENSORLESS_HOMING requires ENDSTOPPULLUP_JMAX (or ENDSTOPPULLUPS) when homing to J_MAX."
#elif LINEAR_AXES >= 6 && K_SENSORLESS && K_HOME_TO_MAX && DISABLED(ENDSTOPPULLUP_KMAX)
#error "SENSORLESS_HOMING requires ENDSTOPPULLUP_KMAX (or ENDSTOPPULLUPS) when homing to K_MAX."
#endif
#endif
@ -2698,6 +2863,42 @@ LINEAR_AXIS_CODE(
#else
#error "SENSORLESS_HOMING requires Z_MAX_ENDSTOP_INVERTING = false when homing TMC2209 to Z_MAX."
#endif
#elif LINEAR_AXES >= 4 && I_SENSORLESS && I_HOME_TO_MIN && I_MIN_ENDSTOP_INVERTING != I_ENDSTOP_INVERTING
#if I_ENDSTOP_INVERTING
#error "SENSORLESS_HOMING requires I_MIN_ENDSTOP_INVERTING = true when homing to I_MIN."
#else
#error "SENSORLESS_HOMING requires I_MIN_ENDSTOP_INVERTING = false when homing TMC2209 to I_MIN."
#endif
#elif LINEAR_AXES >= 4 && I_SENSORLESS && I_HOME_TO_MAX && I_MAX_ENDSTOP_INVERTING != I_ENDSTOP_INVERTING
#if I_ENDSTOP_INVERTING
#error "SENSORLESS_HOMING requires I_MAX_ENDSTOP_INVERTING = true when homing to I_MAX."
#else
#error "SENSORLESS_HOMING requires I_MAX_ENDSTOP_INVERTING = false when homing TMC2209 to I_MAX."
#endif
#elif LINEAR_AXES >= 5 && J_SENSORLESS && J_HOME_TO_MIN && J_MIN_ENDSTOP_INVERTING != J_ENDSTOP_INVERTING
#if J_ENDSTOP_INVERTING
#error "SENSORLESS_HOMING requires J_MIN_ENDSTOP_INVERTING = true when homing to J_MIN."
#else
#error "SENSORLESS_HOMING requires J_MIN_ENDSTOP_INVERTING = false when homing TMC2209 to J_MIN."
#endif
#elif LINEAR_AXES >= 5 && J_SENSORLESS && J_HOME_TO_MAX && J_MAX_ENDSTOP_INVERTING != J_ENDSTOP_INVERTING
#if J_ENDSTOP_INVERTING
#error "SENSORLESS_HOMING requires J_MAX_ENDSTOP_INVERTING = true when homing to J_MAX."
#else
#error "SENSORLESS_HOMING requires J_MAX_ENDSTOP_INVERTING = false when homing TMC2209 to J_MAX."
#endif
#elif LINEAR_AXES >= 6 && K_SENSORLESS && K_HOME_TO_MIN && K_MIN_ENDSTOP_INVERTING != K_ENDSTOP_INVERTING
#if K_ENDSTOP_INVERTING
#error "SENSORLESS_HOMING requires K_MIN_ENDSTOP_INVERTING = true when homing to K_MIN."
#else
#error "SENSORLESS_HOMING requires K_MIN_ENDSTOP_INVERTING = false when homing TMC2209 to K_MIN."
#endif
#elif LINEAR_AXES >= 6 && K_SENSORLESS && K_HOME_TO_MAX && K_MAX_ENDSTOP_INVERTING != K_ENDSTOP_INVERTING
#if K_ENDSTOP_INVERTING
#error "SENSORLESS_HOMING requires K_MAX_ENDSTOP_INVERTING = true when homing to K_MAX."
#else
#error "SENSORLESS_HOMING requires K_MAX_ENDSTOP_INVERTING = false when homing TMC2209 to K_MAX."
#endif
#endif
#endif
@ -2712,6 +2913,9 @@ LINEAR_AXIS_CODE(
#undef X_ENDSTOP_INVERTING
#undef Y_ENDSTOP_INVERTING
#undef Z_ENDSTOP_INVERTING
#undef I_ENDSTOP_INVERTING
#undef J_ENDSTOP_INVERTING
#undef K_ENDSTOP_INVERTING
#endif
// Sensorless probing requirements
@ -2774,6 +2978,12 @@ LINEAR_AXIS_CODE(
#define CS_COMPARE Z2_CS_PIN
#elif IN_CHAIN(Z3)
#define CS_COMPARE Z3_CS_PIN
#elif IN_CHAIN(I)
#define CS_COMPARE I_CS_PIN
#elif IN_CHAIN(J)
#define CS_COMPARE J_CS_PIN
#elif IN_CHAIN(K)
#define CS_COMPARE K_CS_PIN
#elif IN_CHAIN(E0)
#define CS_COMPARE E0_CS_PIN
#elif IN_CHAIN(E1)
@ -2793,6 +3003,7 @@ LINEAR_AXIS_CODE(
#endif
#define BAD_CS_PIN(A) (IN_CHAIN(A) && A##_CS_PIN != CS_COMPARE)
#if BAD_CS_PIN(X ) || BAD_CS_PIN(Y ) || BAD_CS_PIN(Z ) || BAD_CS_PIN(X2) || BAD_CS_PIN(Y2) || BAD_CS_PIN(Z2) || BAD_CS_PIN(Z3) || BAD_CS_PIN(Z4) \
|| BAD_CS_PIN(I) || BAD_CS_PIN(J) || BAD_CS_PIN(K) \
|| BAD_CS_PIN(E0) || BAD_CS_PIN(E1) || BAD_CS_PIN(E2) || BAD_CS_PIN(E3) || BAD_CS_PIN(E4) || BAD_CS_PIN(E5) || BAD_CS_PIN(E6) || BAD_CS_PIN(E7)
#error "All chained TMC drivers must use the same CS pin."
#endif
@ -2803,6 +3014,13 @@ LINEAR_AXIS_CODE(
#endif
#undef IN_CHAIN
/**
* L64XX requirement
*/
#if HAS_L64XX && LINEAR_AXES >= 4
#error "L64XX requires LINEAR_AXES 3. Homing with L64XX is not yet implemented for LINEAR_AXES > 3."
#endif
/**
* Digipot requirement
*/
@ -2820,43 +3038,48 @@ LINEAR_AXIS_CODE(
*/
constexpr float sanity_arr_1[] = DEFAULT_AXIS_STEPS_PER_UNIT,
sanity_arr_2[] = DEFAULT_MAX_FEEDRATE,
sanity_arr_3[] = DEFAULT_MAX_ACCELERATION;
sanity_arr_3[] = DEFAULT_MAX_ACCELERATION,
sanity_arr_7[] = HOMING_FEEDRATE_MM_M;
#define _ARR_TEST(N,I) (sanity_arr_##N[_MIN(I,int(COUNT(sanity_arr_##N))-1)] > 0)
#if HAS_MULTI_EXTRUDER
#define _EXTRA_NOTE " (Did you forget to enable DISTINCT_E_FACTORS?)"
#elif EXTRUDERS == 0
#define _EXTRA_NOTE " (Note: EXTRUDERS is set to 0.)"
#else
#define _EXTRA_NOTE ""
#define _EXTRA_NOTE " (Should be " STRINGIFY(LINEAR_AXES) "+" STRINGIFY(E_STEPPERS) ")"
#endif
static_assert(COUNT(sanity_arr_1) >= LOGICAL_AXES, "DEFAULT_AXIS_STEPS_PER_UNIT requires X, Y, Z and E elements.");
static_assert(COUNT(sanity_arr_1) >= LOGICAL_AXES, "DEFAULT_AXIS_STEPS_PER_UNIT requires " _LOGICAL_AXES_STR "elements.");
static_assert(COUNT(sanity_arr_1) <= DISTINCT_AXES, "DEFAULT_AXIS_STEPS_PER_UNIT has too many elements." _EXTRA_NOTE);
static_assert( _ARR_TEST(1,0) && _ARR_TEST(1,1) && _ARR_TEST(1,2)
&& _ARR_TEST(1,3) && _ARR_TEST(1,4) && _ARR_TEST(1,5)
&& _ARR_TEST(1,6) && _ARR_TEST(1,7) && _ARR_TEST(1,8),
"DEFAULT_AXIS_STEPS_PER_UNIT values must be positive.");
static_assert(COUNT(sanity_arr_2) >= LOGICAL_AXES, "DEFAULT_MAX_FEEDRATE requires X, Y, Z and E elements.");
static_assert(COUNT(sanity_arr_2) >= LOGICAL_AXES, "DEFAULT_MAX_FEEDRATE requires " _LOGICAL_AXES_STR "elements.");
static_assert(COUNT(sanity_arr_2) <= DISTINCT_AXES, "DEFAULT_MAX_FEEDRATE has too many elements." _EXTRA_NOTE);
static_assert( _ARR_TEST(2,0) && _ARR_TEST(2,1) && _ARR_TEST(2,2)
&& _ARR_TEST(2,3) && _ARR_TEST(2,4) && _ARR_TEST(2,5)
&& _ARR_TEST(2,6) && _ARR_TEST(2,7) && _ARR_TEST(2,8),
"DEFAULT_MAX_FEEDRATE values must be positive.");
static_assert(COUNT(sanity_arr_3) >= LOGICAL_AXES, "DEFAULT_MAX_ACCELERATION requires X, Y, Z and E elements.");
static_assert(COUNT(sanity_arr_3) >= LOGICAL_AXES, "DEFAULT_MAX_ACCELERATION requires " _LOGICAL_AXES_STR "elements.");
static_assert(COUNT(sanity_arr_3) <= DISTINCT_AXES, "DEFAULT_MAX_ACCELERATION has too many elements." _EXTRA_NOTE);
static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
&& _ARR_TEST(3,3) && _ARR_TEST(3,4) && _ARR_TEST(3,5)
&& _ARR_TEST(3,6) && _ARR_TEST(3,7) && _ARR_TEST(3,8),
"DEFAULT_MAX_ACCELERATION values must be positive.");
static_assert(COUNT(sanity_arr_7) == LINEAR_AXES, "HOMING_FEEDRATE_MM_M requires " _LINEAR_AXES_STR "elements (and no others).");
static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
&& _ARR_TEST(3,3) && _ARR_TEST(3,4) && _ARR_TEST(3,5)
&& _ARR_TEST(3,6) && _ARR_TEST(3,7) && _ARR_TEST(3,8),
"HOMING_FEEDRATE_MM_M values must be positive.");
#if ENABLED(LIMITED_MAX_ACCEL_EDITING)
#ifdef MAX_ACCEL_EDIT_VALUES
constexpr float sanity_arr_4[] = MAX_ACCEL_EDIT_VALUES;
static_assert(COUNT(sanity_arr_4) >= LOGICAL_AXES, "MAX_ACCEL_EDIT_VALUES requires X, Y, Z and E elements.");
static_assert(COUNT(sanity_arr_4) <= LOGICAL_AXES, "MAX_ACCEL_EDIT_VALUES has too many elements. X, Y, Z and E elements only.");
static_assert(COUNT(sanity_arr_4) >= LOGICAL_AXES, "MAX_ACCEL_EDIT_VALUES requires " _LOGICAL_AXES_STR "elements.");
static_assert(COUNT(sanity_arr_4) <= LOGICAL_AXES, "MAX_ACCEL_EDIT_VALUES has too many elements. " _LOGICAL_AXES_STR "elements only.");
static_assert( _ARR_TEST(4,0) && _ARR_TEST(4,1) && _ARR_TEST(4,2)
&& _ARR_TEST(4,3) && _ARR_TEST(4,4) && _ARR_TEST(4,5)
&& _ARR_TEST(4,6) && _ARR_TEST(4,7) && _ARR_TEST(4,8),
@ -2867,8 +3090,8 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
#if ENABLED(LIMITED_MAX_FR_EDITING)
#ifdef MAX_FEEDRATE_EDIT_VALUES
constexpr float sanity_arr_5[] = MAX_FEEDRATE_EDIT_VALUES;
static_assert(COUNT(sanity_arr_5) >= LOGICAL_AXES, "MAX_FEEDRATE_EDIT_VALUES requires X, Y, Z and E elements.");
static_assert(COUNT(sanity_arr_5) <= LOGICAL_AXES, "MAX_FEEDRATE_EDIT_VALUES has too many elements. X, Y, Z and E elements only.");
static_assert(COUNT(sanity_arr_5) >= LOGICAL_AXES, "MAX_FEEDRATE_EDIT_VALUES requires " _LOGICAL_AXES_STR "elements.");
static_assert(COUNT(sanity_arr_5) <= LOGICAL_AXES, "MAX_FEEDRATE_EDIT_VALUES has too many elements. " _LOGICAL_AXES_STR "elements only.");
static_assert( _ARR_TEST(5,0) && _ARR_TEST(5,1) && _ARR_TEST(5,2)
&& _ARR_TEST(5,3) && _ARR_TEST(5,4) && _ARR_TEST(5,5)
&& _ARR_TEST(5,6) && _ARR_TEST(5,7) && _ARR_TEST(5,8),
@ -2879,8 +3102,8 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
#if ENABLED(LIMITED_JERK_EDITING)
#ifdef MAX_JERK_EDIT_VALUES
constexpr float sanity_arr_6[] = MAX_JERK_EDIT_VALUES;
static_assert(COUNT(sanity_arr_6) >= LOGICAL_AXES, "MAX_JERK_EDIT_VALUES requires X, Y, Z and E elements.");
static_assert(COUNT(sanity_arr_6) <= LOGICAL_AXES, "MAX_JERK_EDIT_VALUES has too many elements. X, Y, Z and E elements only.");
static_assert(COUNT(sanity_arr_6) >= LOGICAL_AXES, "MAX_JERK_EDIT_VALUES requires " _LOGICAL_AXES_STR "elements.");
static_assert(COUNT(sanity_arr_6) <= LOGICAL_AXES, "MAX_JERK_EDIT_VALUES has too many elements. " _LOGICAL_AXES_STR "elements only.");
static_assert( _ARR_TEST(6,0) && _ARR_TEST(6,1) && _ARR_TEST(6,2)
&& _ARR_TEST(6,3) && _ARR_TEST(6,4) && _ARR_TEST(6,5)
&& _ARR_TEST(6,6) && _ARR_TEST(6,7) && _ARR_TEST(6,8),
@ -3280,6 +3503,22 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
#if _BAD_DRIVER(Z)
#error "Z_DRIVER_TYPE is not recognized."
#endif
#if LINEAR_AXES >= 4
#if _BAD_DRIVER(I)
#error "I_DRIVER_TYPE is not recognized."
#endif
#endif
#if LINEAR_AXES >= 5
#if _BAD_DRIVER(J)
#error "J_DRIVER_TYPE is not recognized."
#endif
#endif
#if LINEAR_AXES >= 6
#if _BAD_DRIVER(K)
#error "K_DRIVER_TYPE is not recognized."
#endif
#endif
#if _BAD_DRIVER(X2)
#error "X2_DRIVER_TYPE is not recognized."
#endif
@ -3323,7 +3562,5 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
// Misc. Cleanup
#undef _TEST_PWM
#if ENABLED(FREEZE_FEATURE) && !PIN_EXISTS(FREEZE)
#error "FREEZE_FEATURE requires a FREEZE_PIN to be defined."
#endif
#undef _LINEAR_AXES_STR
#undef _LOGICAL_AXES_STR

View File

@ -52,7 +52,7 @@
* to alert users to major changes.
*/
#define MARLIN_HEX_VERSION 02000801
#define MARLIN_HEX_VERSION 02000900
#ifndef REQUIRED_CONFIGURATION_H_VERSION
#define REQUIRED_CONFIGURATION_H_VERSION MARLIN_HEX_VERSION
#endif