Quad Z stepper support (#16277)

This commit is contained in:
InsanityAutomation
2020-01-20 00:35:07 -05:00
committed by Scott Lahteine
parent f36f084465
commit 0fcf2b1110
52 changed files with 1198 additions and 415 deletions

View File

@ -37,7 +37,7 @@
*/
// Change EEPROM version if the structure changes
#define EEPROM_VERSION "V74"
#define EEPROM_VERSION "V75"
#define EEPROM_OFFSET 100
// Check the integrity of data offsets.
@ -120,10 +120,10 @@
#pragma pack(push, 1) // No padding between variables
typedef struct { uint16_t X, Y, Z, X2, Y2, Z2, Z3, E0, E1, E2, E3, E4, E5; } tmc_stepper_current_t;
typedef struct { uint32_t X, Y, Z, X2, Y2, Z2, Z3, E0, E1, E2, E3, E4, E5; } tmc_hybrid_threshold_t;
typedef struct { uint16_t X, Y, Z, X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5; } tmc_stepper_current_t;
typedef struct { uint32_t X, Y, Z, X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5; } tmc_hybrid_threshold_t;
typedef struct { int16_t X, Y, Z, X2; } tmc_sgt_t;
typedef struct { bool X, Y, Z, X2, Y2, Z2, Z3, E0, E1, E2, E3, E4, E5; } tmc_stealth_enabled_t;
typedef struct { bool X, Y, Z, X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5; } tmc_stealth_enabled_t;
// Limit an index to an array size
#define ALIM(I,ARR) _MIN(I, COUNT(ARR) - 1)
@ -243,11 +243,12 @@ typedef struct SettingsDataStruct {
delta_diagonal_rod, // M665 L
delta_segments_per_second; // M665 S
abc_float_t delta_tower_angle_trim; // M665 XYZ
#elif EITHER(X_DUAL_ENDSTOPS, Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
#elif HAS_EXTRA_ENDSTOPS
float x2_endstop_adj, // M666 X
y2_endstop_adj, // M666 Y
z2_endstop_adj, // M666 Z (S2)
z3_endstop_adj; // M666 Z (S3)
z2_endstop_adj, // M666 (S2) Z
z3_endstop_adj, // M666 (S3) Z
z4_endstop_adj; // M666 (S4) Z
#endif
//
@ -300,10 +301,10 @@ typedef struct SettingsDataStruct {
//
// HAS_TRINAMIC
//
tmc_stepper_current_t tmc_stepper_current; // M906 X Y Z X2 Y2 Z2 Z3 E0 E1 E2 E3 E4 E5
tmc_hybrid_threshold_t tmc_hybrid_threshold; // M913 X Y Z X2 Y2 Z2 Z3 E0 E1 E2 E3 E4 E5
tmc_stepper_current_t tmc_stepper_current; // M906 X Y Z X2 Y2 Z2 Z3 Z4 E0 E1 E2 E3 E4 E5
tmc_hybrid_threshold_t tmc_hybrid_threshold; // M913 X Y Z X2 Y2 Z2 Z3 Z4 E0 E1 E2 E3 E4 E5
tmc_sgt_t tmc_sgt; // M914 X Y Z X2
tmc_stealth_enabled_t tmc_stealth_enabled; // M569 X Y Z X2 Y2 Z2 Z3 E0 E1 E2 E3 E4 E5
tmc_stealth_enabled_t tmc_stealth_enabled; // M569 X Y Z X2 Y2 Z2 Z3 Z4 E0 E1 E2 E3 E4 E5
//
// LIN_ADVANCE
@ -756,7 +757,7 @@ void MarlinSettings::postprocess() {
EEPROM_WRITE(delta_segments_per_second); // 1 float
EEPROM_WRITE(delta_tower_angle_trim); // 3 floats
#elif EITHER(X_DUAL_ENDSTOPS, Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
#elif HAS_EXTRA_ENDSTOPS
_FIELD_TEST(x2_endstop_adj);
@ -774,18 +775,24 @@ void MarlinSettings::postprocess() {
EEPROM_WRITE(dummy);
#endif
#if Z_MULTI_ENDSTOPS
#if ENABLED(Z_MULTI_ENDSTOPS)
EEPROM_WRITE(endstops.z2_endstop_adj); // 1 float
#else
EEPROM_WRITE(dummy);
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS)
#if ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 3
EEPROM_WRITE(endstops.z3_endstop_adj); // 1 float
#else
EEPROM_WRITE(dummy);
#endif
#if ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 4
EEPROM_WRITE(endstops.z4_endstop_adj); // 1 float
#else
EEPROM_WRITE(dummy);
#endif
#endif
}
@ -974,6 +981,9 @@ void MarlinSettings::postprocess() {
#if AXIS_IS_TMC(Z3)
tmc_stepper_current.Z3 = stepperZ3.getMilliamps();
#endif
#if AXIS_IS_TMC(Z4)
tmc_stepper_current.Z4 = stepperZ4.getMilliamps();
#endif
#if MAX_EXTRUDERS
#if AXIS_IS_TMC(E0)
tmc_stepper_current.E0 = stepperE0.getMilliamps();
@ -1037,6 +1047,9 @@ void MarlinSettings::postprocess() {
#if AXIS_HAS_STEALTHCHOP(Z3)
tmc_hybrid_threshold.Z3 = stepperZ3.get_pwm_thrs();
#endif
#if AXIS_HAS_STEALTHCHOP(Z4)
tmc_hybrid_threshold.Z4 = stepperZ4.get_pwm_thrs();
#endif
#if MAX_EXTRUDERS
#if AXIS_HAS_STEALTHCHOP(E0)
tmc_hybrid_threshold.E0 = stepperE0.get_pwm_thrs();
@ -1070,7 +1083,7 @@ void MarlinSettings::postprocess() {
#else
const tmc_hybrid_threshold_t tmc_hybrid_threshold = {
.X = 100, .Y = 100, .Z = 3,
.X2 = 100, .Y2 = 100, .Z2 = 3, .Z3 = 3,
.X2 = 100, .Y2 = 100, .Z2 = 3, .Z3 = 3, .Z4 = 3,
.E0 = 30, .E1 = 30, .E2 = 30,
.E3 = 30, .E4 = 30, .E5 = 30
};
@ -1130,6 +1143,9 @@ void MarlinSettings::postprocess() {
#if AXIS_HAS_STEALTHCHOP(Z3)
tmc_stealth_enabled.Z3 = stepperZ3.get_stealthChop_status();
#endif
#if AXIS_HAS_STEALTHCHOP(Z4)
tmc_stealth_enabled.Z4 = stepperZ4.get_stealthChop_status();
#endif
#if MAX_EXTRUDERS
#if AXIS_HAS_STEALTHCHOP(E0)
tmc_stealth_enabled.E0 = stepperE0.get_stealthChop_status();
@ -1585,7 +1601,7 @@ void MarlinSettings::postprocess() {
EEPROM_READ(delta_segments_per_second); // 1 float
EEPROM_READ(delta_tower_angle_trim); // 3 floats
#elif EITHER(X_DUAL_ENDSTOPS, Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
#elif HAS_EXTRA_ENDSTOPS
_FIELD_TEST(x2_endstop_adj);
@ -1599,16 +1615,21 @@ void MarlinSettings::postprocess() {
#else
EEPROM_READ(dummy);
#endif
#if Z_MULTI_ENDSTOPS
#if ENABLED(Z_MULTI_ENDSTOPS)
EEPROM_READ(endstops.z2_endstop_adj); // 1 float
#else
EEPROM_READ(dummy);
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS)
#if ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 3
EEPROM_READ(endstops.z3_endstop_adj); // 1 float
#else
EEPROM_READ(dummy);
#endif
#if ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 4
EEPROM_READ(endstops.z4_endstop_adj); // 1 float
#else
EEPROM_READ(dummy);
#endif
#endif
}
@ -1800,6 +1821,9 @@ void MarlinSettings::postprocess() {
#if AXIS_IS_TMC(Z3)
SET_CURR(Z3);
#endif
#if AXIS_IS_TMC(Z4)
SET_CURR(Z4);
#endif
#if AXIS_IS_TMC(E0)
SET_CURR(E0);
#endif
@ -1851,6 +1875,9 @@ void MarlinSettings::postprocess() {
#if AXIS_HAS_STEALTHCHOP(Z3)
stepperZ3.set_pwm_thrs(tmc_hybrid_threshold.Z3);
#endif
#if AXIS_HAS_STEALTHCHOP(Z4)
stepperZ4.set_pwm_thrs(tmc_hybrid_threshold.Z4);
#endif
#if AXIS_HAS_STEALTHCHOP(E0)
stepperE0.set_pwm_thrs(tmc_hybrid_threshold.E0);
#endif
@ -1877,7 +1904,7 @@ void MarlinSettings::postprocess() {
// TMC StallGuard threshold.
// X and X2 use the same value
// Y and Y2 use the same value
// Z, Z2 and Z3 use the same value
// Z, Z2, Z3 and Z4 use the same value
//
{
tmc_sgt_t tmc_sgt;
@ -1914,6 +1941,9 @@ void MarlinSettings::postprocess() {
#if AXIS_HAS_STALLGUARD(Z3)
stepperZ3.homing_threshold(tmc_sgt.Z);
#endif
#if AXIS_HAS_STALLGUARD(Z4)
stepperZ4.homing_threshold(tmc_sgt.Z);
#endif
#endif
}
#endif
@ -1951,6 +1981,9 @@ void MarlinSettings::postprocess() {
#if AXIS_HAS_STEALTHCHOP(Z3)
SET_STEPPING_MODE(Z3);
#endif
#if AXIS_HAS_STEALTHCHOP(Z4)
SET_STEPPING_MODE(Z4);
#endif
#if AXIS_HAS_STEALTHCHOP(E0)
SET_STEPPING_MODE(E0);
#endif
@ -2433,51 +2466,39 @@ void MarlinSettings::reset() {
delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND;
delta_tower_angle_trim = dta;
#elif EITHER(X_DUAL_ENDSTOPS, Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
#endif
#if ENABLED(X_DUAL_ENDSTOPS)
endstops.x2_endstop_adj = (
#ifdef X_DUAL_ENDSTOPS_ADJUSTMENT
X_DUAL_ENDSTOPS_ADJUSTMENT
#else
0
#endif
);
#endif
#if ENABLED(Y_DUAL_ENDSTOPS)
endstops.y2_endstop_adj = (
#ifdef Y_DUAL_ENDSTOPS_ADJUSTMENT
Y_DUAL_ENDSTOPS_ADJUSTMENT
#else
0
#endif
);
#endif
#if ENABLED(Z_DUAL_ENDSTOPS)
endstops.z2_endstop_adj = (
#ifdef Z_DUAL_ENDSTOPS_ADJUSTMENT
Z_DUAL_ENDSTOPS_ADJUSTMENT
#else
0
#endif
);
#elif ENABLED(Z_TRIPLE_ENDSTOPS)
endstops.z2_endstop_adj = (
#ifdef Z_TRIPLE_ENDSTOPS_ADJUSTMENT2
Z_TRIPLE_ENDSTOPS_ADJUSTMENT2
#else
0
#endif
);
endstops.z3_endstop_adj = (
#ifdef Z_TRIPLE_ENDSTOPS_ADJUSTMENT3
Z_TRIPLE_ENDSTOPS_ADJUSTMENT3
#else
0
#endif
);
#if ENABLED(X_DUAL_ENDSTOPS)
#ifndef X2_ENDSTOP_ADJUSTMENT
#define X2_ENDSTOP_ADJUSTMENT 0
#endif
endstops.x2_endstop_adj = X2_ENDSTOP_ADJUSTMENT;
#endif
#if ENABLED(Y_DUAL_ENDSTOPS)
#ifndef Y2_ENDSTOP_ADJUSTMENT
#define Y2_ENDSTOP_ADJUSTMENT 0
#endif
endstops.y2_endstop_adj = Y2_ENDSTOP_ADJUSTMENT;
#endif
#if ENABLED(Z_MULTI_ENDSTOPS)
#ifndef Z2_ENDSTOP_ADJUSTMENT
#define Z2_ENDSTOP_ADJUSTMENT 0
#endif
endstops.z2_endstop_adj = Z2_ENDSTOP_ADJUSTMENT;
#if NUM_Z_STEPPER_DRIVERS >= 3
#ifndef Z3_ENDSTOP_ADJUSTMENT
#define Z3_ENDSTOP_ADJUSTMENT 0
#endif
endstops.z3_endstop_adj = Z3_ENDSTOP_ADJUSTMENT;
#endif
#if NUM_Z_STEPPER_DRIVERS >= 4
#ifndef Z4_ENDSTOP_ADJUSTMENT
#define Z4_ENDSTOP_ADJUSTMENT 0
#endif
endstops.z4_endstop_adj = Z4_ENDSTOP_ADJUSTMENT;
#endif
#endif
//
@ -3016,25 +3037,30 @@ void MarlinSettings::reset() {
, SP_Z_STR, LINEAR_UNIT(delta_tower_angle_trim.c)
);
#elif EITHER(X_DUAL_ENDSTOPS, Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
#elif HAS_EXTRA_ENDSTOPS
CONFIG_ECHO_HEADING("Endstop adjustment:");
CONFIG_ECHO_START();
SERIAL_ECHOPGM(" M666");
#if ENABLED(X_DUAL_ENDSTOPS)
SERIAL_ECHOPAIR_P(SP_X_STR, LINEAR_UNIT(endstops.x2_endstop_adj));
SERIAL_ECHOLNPAIR_P(SP_X_STR, LINEAR_UNIT(endstops.x2_endstop_adj));
#endif
#if ENABLED(Y_DUAL_ENDSTOPS)
SERIAL_ECHOPAIR_P(SP_Y_STR, LINEAR_UNIT(endstops.y2_endstop_adj));
SERIAL_ECHOLNPAIR_P(SP_Y_STR, LINEAR_UNIT(endstops.y2_endstop_adj));
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS)
SERIAL_ECHOLNPAIR("S1 Z", LINEAR_UNIT(endstops.z2_endstop_adj));
CONFIG_ECHO_START();
SERIAL_ECHOPAIR(" M666 S2 Z", LINEAR_UNIT(endstops.z3_endstop_adj));
#elif ENABLED(Z_DUAL_ENDSTOPS)
SERIAL_ECHOPAIR_P(SP_Z_STR, LINEAR_UNIT(endstops.z2_endstop_adj));
#if ENABLED(Z_MULTI_ENDSTOPS)
#if NUM_Z_STEPPER_DRIVERS >= 3
SERIAL_ECHOPAIR(" S2 Z", LINEAR_UNIT(endstops.z3_endstop_adj));
CONFIG_ECHO_START();
SERIAL_ECHOPAIR(" M666 S3 Z", LINEAR_UNIT(endstops.z3_endstop_adj));
#if NUM_Z_STEPPER_DRIVERS >= 4
CONFIG_ECHO_START();
SERIAL_ECHOPAIR(" M666 S4 Z", LINEAR_UNIT(endstops.z4_endstop_adj));
#endif
#else
SERIAL_ECHOLNPAIR_P(SP_Z_STR, LINEAR_UNIT(endstops.z2_endstop_adj));
#endif
#endif
SERIAL_EOL();
#endif // [XYZ]_DUAL_ENDSTOPS
@ -3218,6 +3244,11 @@ void MarlinSettings::reset() {
SERIAL_ECHOLNPAIR(" I2 Z", stepperZ3.getMilliamps());
#endif
#if AXIS_IS_TMC(Z4)
say_M906(forReplay);
SERIAL_ECHOLNPAIR(" I3 Z", stepperZ4.getMilliamps());
#endif
#if AXIS_IS_TMC(E0)
say_M906(forReplay);
SERIAL_ECHOLNPAIR(" T0 E", stepperE0.getMilliamps());
@ -3287,6 +3318,11 @@ void MarlinSettings::reset() {
SERIAL_ECHOLNPAIR(" I2 Z", stepperZ3.get_pwm_thrs());
#endif
#if AXIS_HAS_STEALTHCHOP(Z4)
say_M913(forReplay);
SERIAL_ECHOLNPAIR(" I3 Z", stepperZ4.get_pwm_thrs());
#endif
#if AXIS_HAS_STEALTHCHOP(E0)
say_M913(forReplay);
SERIAL_ECHOLNPAIR(" T0 E", stepperE0.get_pwm_thrs());
@ -3356,6 +3392,12 @@ void MarlinSettings::reset() {
SERIAL_ECHOLNPAIR(" I2 Z", stepperZ3.homing_threshold());
#endif
#if Z4_SENSORLESS
CONFIG_ECHO_START();
say_M914();
SERIAL_ECHOLNPAIR(" I3 Z", stepperZ4.homing_threshold());
#endif
#endif // USE_SENSORLESS
/**
@ -3415,6 +3457,10 @@ void MarlinSettings::reset() {
if (stepperZ3.get_stealthChop_status()) { say_M569(forReplay, PSTR("I2 Z"), true); }
#endif
#if AXIS_HAS_STEALTHCHOP(Z4)
if (stepperZ4.get_stealthChop_status()) { say_M569(forReplay, PSTR("I3 Z"), true); }
#endif
#if AXIS_HAS_STEALTHCHOP(E0)
if (stepperE0.get_stealthChop_status()) { say_M569(forReplay, PSTR("T0 E"), true); }
#endif

View File

@ -73,11 +73,14 @@ Endstops::esbits_t Endstops::live_state = 0;
#if ENABLED(Y_DUAL_ENDSTOPS)
float Endstops::y2_endstop_adj;
#endif
#if Z_MULTI_ENDSTOPS
#if ENABLED(Z_MULTI_ENDSTOPS)
float Endstops::z2_endstop_adj;
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS)
float Endstops::z3_endstop_adj;
#if NUM_Z_STEPPER_DRIVERS >= 3
float Endstops::z3_endstop_adj;
#if NUM_Z_STEPPER_DRIVERS >= 4
float Endstops::z4_endstop_adj;
#endif
#endif
#endif
#if ENABLED(SPI_ENDSTOPS)
@ -163,6 +166,16 @@ void Endstops::init() {
#endif
#endif
#if HAS_Z4_MIN
#if ENABLED(ENDSTOPPULLUP_ZMIN)
SET_INPUT_PULLUP(Z4_MIN_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_ZMIN)
SET_INPUT_PULLDOWN(Z4_MIN_PIN);
#else
SET_INPUT(Z4_MIN_PIN);
#endif
#endif
#if HAS_X_MAX
#if ENABLED(ENDSTOPPULLUP_XMAX)
SET_INPUT_PULLUP(X_MAX_PIN);
@ -233,6 +246,16 @@ void Endstops::init() {
#endif
#endif
#if HAS_Z4_MAX
#if ENABLED(ENDSTOPPULLUP_ZMAX)
SET_INPUT_PULLUP(Z4_MAX_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_ZMAX)
SET_INPUT_PULLDOWN(Z4_MAX_PIN);
#else
SET_INPUT(Z4_MAX_PIN);
#endif
#endif
#if HAS_CALIBRATION_PIN
#if ENABLED(CALIBRATION_PIN_PULLUP)
SET_INPUT_PULLUP(CALIBRATION_PIN);
@ -435,6 +458,9 @@ void _O2 Endstops::report_states() {
#if HAS_Z3_MIN
ES_REPORT(Z3_MIN);
#endif
#if HAS_Z4_MIN
ES_REPORT(Z4_MIN);
#endif
#if HAS_Z_MAX
ES_REPORT(Z_MAX);
#endif
@ -444,6 +470,9 @@ void _O2 Endstops::report_states() {
#if HAS_Z3_MAX
ES_REPORT(Z3_MAX);
#endif
#if HAS_Z4_MAX
ES_REPORT(Z4_MAX);
#endif
#if HAS_CUSTOM_PROBE_PIN
print_es_state(READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING, PSTR(MSG_Z_PROBE));
#endif
@ -584,19 +613,26 @@ void Endstops::update() {
#if HAS_Z_MIN && !Z_SPI_SENSORLESS
UPDATE_ENDSTOP_BIT(Z, MIN);
#if Z_MULTI_ENDSTOPS
#if ENABLED(Z_MULTI_ENDSTOPS)
#if HAS_Z2_MIN
UPDATE_ENDSTOP_BIT(Z2, MIN);
#else
COPY_LIVE_STATE(Z_MIN, Z2_MIN);
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS)
#if NUM_Z_STEPPER_DRIVERS >= 3
#if HAS_Z3_MIN
UPDATE_ENDSTOP_BIT(Z3, MIN);
#else
COPY_LIVE_STATE(Z_MIN, Z3_MIN);
#endif
#endif
#if NUM_Z_STEPPER_DRIVERS >= 4
#if HAS_Z4_MIN
UPDATE_ENDSTOP_BIT(Z4, MIN);
#else
COPY_LIVE_STATE(Z_MIN, Z4_MIN);
#endif
#endif
#endif
#endif
@ -607,20 +643,27 @@ void Endstops::update() {
#if HAS_Z_MAX && !Z_SPI_SENSORLESS
// Check both Z dual endstops
#if Z_MULTI_ENDSTOPS
#if ENABLED(Z_MULTI_ENDSTOPS)
UPDATE_ENDSTOP_BIT(Z, MAX);
#if HAS_Z2_MAX
UPDATE_ENDSTOP_BIT(Z2, MAX);
#else
COPY_LIVE_STATE(Z_MAX, Z2_MAX);
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS)
#if NUM_Z_STEPPER_DRIVERS >= 3
#if HAS_Z3_MAX
UPDATE_ENDSTOP_BIT(Z3, MAX);
#else
COPY_LIVE_STATE(Z_MAX, Z3_MAX);
#endif
#endif
#if NUM_Z_STEPPER_DRIVERS >= 4
#if HAS_Z4_MAX
UPDATE_ENDSTOP_BIT(Z4, MAX);
#else
COPY_LIVE_STATE(Z_MAX, Z4_MAX);
#endif
#endif
#elif !HAS_CUSTOM_PROBE_PIN || Z_MAX_PIN != Z_MIN_PROBE_PIN
// If this pin isn't the bed probe it's the Z endstop
UPDATE_ENDSTOP_BIT(Z, MAX);
@ -686,6 +729,16 @@ void Endstops::update() {
} \
}while(0)
#define PROCESS_QUAD_ENDSTOP(AXIS1, AXIS2, AXIS3, AXIS4, MINMAX) do { \
const byte quad_hit = TEST_ENDSTOP(_ENDSTOP(AXIS1, MINMAX)) | (TEST_ENDSTOP(_ENDSTOP(AXIS2, MINMAX)) << 1) | (TEST_ENDSTOP(_ENDSTOP(AXIS3, MINMAX)) << 2) | (TEST_ENDSTOP(_ENDSTOP(AXIS4, MINMAX)) << 3); \
if (quad_hit) { \
_ENDSTOP_HIT(AXIS1, MINMAX); \
/* if not performing home or if both endstops were trigged during homing... */ \
if (!stepper.separate_multi_axis || quad_hit == 0b1111) \
planner.endstop_triggered(_AXIS(AXIS1)); \
} \
}while(0)
#if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && !(CORE_IS_XY || CORE_IS_XZ)
#if ENABLED(G38_PROBE_AWAY)
#define _G38_OPEN_STATE (G38_move >= 4)
@ -747,10 +800,14 @@ void Endstops::update() {
if (stepper.axis_is_moving(Z_AXIS)) {
if (stepper.motor_direction(Z_AXIS_HEAD)) { // Z -direction. Gantry down, bed up.
#if HAS_Z_MIN || (Z_SPI_SENSORLESS && Z_HOME_DIR < 0)
#if ENABLED(Z_TRIPLE_ENDSTOPS)
PROCESS_TRIPLE_ENDSTOP(Z, Z2, Z3, MIN);
#elif ENABLED(Z_DUAL_ENDSTOPS)
PROCESS_DUAL_ENDSTOP(Z, Z2, MIN);
#if ENABLED(Z_MULTI_ENDSTOPS)
#if NUM_Z_STEPPER_DRIVERS == 4
PROCESS_QUAD_ENDSTOP(Z, Z2, Z3, Z4, MIN);
#elif NUM_Z_STEPPER_DRIVERS == 3
PROCESS_TRIPLE_ENDSTOP(Z, Z2, Z3, MIN);
#else
PROCESS_DUAL_ENDSTOP(Z, Z2, MIN);
#endif
#else
#if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
if (z_probe_enabled) PROCESS_ENDSTOP(Z, MIN);
@ -769,10 +826,14 @@ void Endstops::update() {
}
else { // Z +direction. Gantry up, bed down.
#if HAS_Z_MAX || (Z_SPI_SENSORLESS && Z_HOME_DIR > 0)
#if ENABLED(Z_TRIPLE_ENDSTOPS)
PROCESS_TRIPLE_ENDSTOP(Z, Z2, Z3, MAX);
#elif ENABLED(Z_DUAL_ENDSTOPS)
PROCESS_DUAL_ENDSTOP(Z, Z2, MAX);
#if ENABLED(Z_MULTI_ENDSTOPS)
#if NUM_Z_STEPPER_DRIVERS == 4
PROCESS_QUAD_ENDSTOP(Z, Z2, Z3, Z4, MAX);
#elif NUM_Z_STEPPER_DRIVERS == 3
PROCESS_TRIPLE_ENDSTOP(Z, Z2, Z3, MAX);
#else
PROCESS_DUAL_ENDSTOP(Z, Z2, MAX);
#endif
#elif !HAS_CUSTOM_PROBE_PIN || Z_MAX_PIN != Z_MIN_PROBE_PIN
// If this pin is not hijacked for the bed probe
// then it belongs to the Z endstop
@ -892,6 +953,12 @@ void Endstops::update() {
#if HAS_Z3_MAX
ES_GET_STATE(Z3_MAX);
#endif
#if HAS_Z4_MIN
ES_GET_STATE(Z4_MIN);
#endif
#if HAS_Z4_MAX
ES_GET_STATE(Z4_MAX);
#endif
uint16_t endstop_change = live_state_local ^ old_live_state_local;
#define ES_REPORT_CHANGE(S) if (TEST(endstop_change, S)) SERIAL_ECHOPAIR(" " STRINGIFY(S) ":", TEST(live_state_local, S))
@ -942,6 +1009,12 @@ void Endstops::update() {
#if HAS_Z3_MAX
ES_REPORT_CHANGE(Z3_MAX);
#endif
#if HAS_Z4_MIN
ES_REPORT_CHANGE(Z4_MIN);
#endif
#if HAS_Z4_MAX
ES_REPORT_CHANGE(Z4_MAX);
#endif
SERIAL_ECHOLNPGM("\n");
analogWrite(pin_t(LED_PIN), local_LED_status);
local_LED_status ^= 255;

View File

@ -34,7 +34,8 @@ enum EndstopEnum : char {
X2_MIN, X2_MAX,
Y2_MIN, Y2_MAX,
Z2_MIN, Z2_MAX,
Z3_MIN, Z3_MAX
Z3_MIN, Z3_MAX,
Z4_MIN, Z4_MAX
};
class Endstops {
@ -47,12 +48,15 @@ class Endstops {
#if ENABLED(Y_DUAL_ENDSTOPS)
static float y2_endstop_adj;
#endif
#if Z_MULTI_ENDSTOPS
#if ENABLED(Z_MULTI_ENDSTOPS)
static float z2_endstop_adj;
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS)
#if ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 3
static float z3_endstop_adj;
#endif
#if ENABLED(Z_MULTI_ENDSTOPS) && NUM_Z_STEPPER_DRIVERS >= 4
static float z4_endstop_adj;
#endif
#else
typedef uint8_t esbits_t;
#endif

View File

@ -1156,6 +1156,9 @@ feedRate_t get_homing_bump_feedrate(const AxisEnum axis) {
#if AXIS_HAS_STALLGUARD(Z3)
stealth_states.z3 = tmc_enable_stallguard(stepperZ3);
#endif
#if AXIS_HAS_STALLGUARD(Z4)
stealth_states.z4 = tmc_enable_stallguard(stepperZ4);
#endif
#if CORE_IS_XZ && X_SENSORLESS
stealth_states.x = tmc_enable_stallguard(stepperX);
#elif CORE_IS_YZ && Y_SENSORLESS
@ -1225,6 +1228,9 @@ feedRate_t get_homing_bump_feedrate(const AxisEnum axis) {
#if AXIS_HAS_STALLGUARD(Z3)
tmc_disable_stallguard(stepperZ3, enable_stealth.z3);
#endif
#if AXIS_HAS_STALLGUARD(Z4)
tmc_disable_stallguard(stepperZ4, enable_stealth.z4);
#endif
#if CORE_IS_XZ && X_SENSORLESS
tmc_disable_stallguard(stepperX, enable_stealth.x);
#elif CORE_IS_YZ && Y_SENSORLESS
@ -1509,7 +1515,7 @@ void homeaxis(const AxisEnum axis) {
#if ENABLED(Y_DUAL_ENDSTOPS)
case Y_AXIS:
#endif
#if Z_MULTI_ENDSTOPS
#if ENABLED(Z_MULTI_ENDSTOPS)
case Z_AXIS:
#endif
stepper.set_separate_multi_axis(true);
@ -1593,77 +1599,119 @@ void homeaxis(const AxisEnum axis) {
}
}
#endif
#if ENABLED(Z_DUAL_ENDSTOPS)
#if ENABLED(Z_MULTI_ENDSTOPS)
if (axis == Z_AXIS) {
const float adj = ABS(endstops.z2_endstop_adj);
if (adj) {
if (pos_dir ? (endstops.z2_endstop_adj > 0) : (endstops.z2_endstop_adj < 0)) stepper.set_z_lock(true); else stepper.set_z2_lock(true);
do_homing_move(axis, pos_dir ? -adj : adj);
#if NUM_Z_STEPPER_DRIVERS == 2
const float adj = ABS(endstops.z2_endstop_adj);
if (adj) {
if (pos_dir ? (endstops.z2_endstop_adj > 0) : (endstops.z2_endstop_adj < 0)) stepper.set_z_lock(true); else stepper.set_z2_lock(true);
do_homing_move(axis, pos_dir ? -adj : adj);
stepper.set_z_lock(false);
stepper.set_z2_lock(false);
}
#else
// Handy arrays of stepper lock function pointers
typedef void (*adjustFunc_t)(const bool);
adjustFunc_t lock[] = {
stepper.set_z_lock, stepper.set_z2_lock, stepper.set_z3_lock
#if NUM_Z_STEPPER_DRIVERS >= 4
, stepper.set_z4_lock
#endif
};
float adj[] = {
0, endstops.z2_endstop_adj, endstops.z3_endstop_adj
#if NUM_Z_STEPPER_DRIVERS >= 4
, endstops.z4_endstop_adj
#endif
};
adjustFunc_t tempLock;
float tempAdj;
// Manual bubble sort by adjust value
if (adj[1] < adj[0]) {
tempLock = lock[0], tempAdj = adj[0];
lock[0] = lock[1], adj[0] = adj[1];
lock[1] = tempLock, adj[1] = tempAdj;
}
if (adj[2] < adj[1]) {
tempLock = lock[1], tempAdj = adj[1];
lock[1] = lock[2], adj[1] = adj[2];
lock[2] = tempLock, adj[2] = tempAdj;
}
#if NUM_Z_STEPPER_DRIVERS >= 4
if (adj[3] < adj[2]) {
tempLock = lock[2], tempAdj = adj[2];
lock[2] = lock[3], adj[2] = adj[3];
lock[3] = tempLock, adj[3] = tempAdj;
}
if (adj[2] < adj[1]) {
tempLock = lock[1], tempAdj = adj[1];
lock[1] = lock[2], adj[1] = adj[2];
lock[2] = tempLock, adj[2] = tempAdj;
}
#endif
if (adj[1] < adj[0]) {
tempLock = lock[0], tempAdj = adj[0];
lock[0] = lock[1], adj[0] = adj[1];
lock[1] = tempLock, adj[1] = tempAdj;
}
if (pos_dir) {
// normalize adj to smallest value and do the first move
(*lock[0])(true);
do_homing_move(axis, adj[1] - adj[0]);
// lock the second stepper for the final correction
(*lock[1])(true);
do_homing_move(axis, adj[2] - adj[1]);
#if NUM_Z_STEPPER_DRIVERS >= 4
// lock the third stepper for the final correction
(*lock[2])(true);
do_homing_move(axis, adj[3] - adj[2]);
#endif
}
else {
#if NUM_Z_STEPPER_DRIVERS >= 4
(*lock[3])(true);
do_homing_move(axis, adj[2] - adj[3]);
#endif
(*lock[2])(true);
do_homing_move(axis, adj[1] - adj[2]);
(*lock[1])(true);
do_homing_move(axis, adj[0] - adj[1]);
}
stepper.set_z_lock(false);
stepper.set_z2_lock(false);
}
}
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS)
if (axis == Z_AXIS) {
// we push the function pointers for the stepper lock function into an array
void (*lock[3]) (bool)= {&stepper.set_z_lock, &stepper.set_z2_lock, &stepper.set_z3_lock};
float adj[3] = {0, endstops.z2_endstop_adj, endstops.z3_endstop_adj};
stepper.set_z3_lock(false);
#if NUM_Z_STEPPER_DRIVERS >= 4
stepper.set_z4_lock(false);
#endif
void (*tempLock) (bool);
float tempAdj;
// manual bubble sort by adjust value
if (adj[1] < adj[0]) {
tempLock = lock[0], tempAdj = adj[0];
lock[0] = lock[1], adj[0] = adj[1];
lock[1] = tempLock, adj[1] = tempAdj;
}
if (adj[2] < adj[1]) {
tempLock = lock[1], tempAdj = adj[1];
lock[1] = lock[2], adj[1] = adj[2];
lock[2] = tempLock, adj[2] = tempAdj;
}
if (adj[1] < adj[0]) {
tempLock = lock[0], tempAdj = adj[0];
lock[0] = lock[1], adj[0] = adj[1];
lock[1] = tempLock, adj[1] = tempAdj;
}
if (pos_dir) {
// normalize adj to smallest value and do the first move
(*lock[0])(true);
do_homing_move(axis, adj[1] - adj[0]);
// lock the second stepper for the final correction
(*lock[1])(true);
do_homing_move(axis, adj[2] - adj[1]);
}
else {
(*lock[2])(true);
do_homing_move(axis, adj[1] - adj[2]);
(*lock[1])(true);
do_homing_move(axis, adj[0] - adj[1]);
}
stepper.set_z_lock(false);
stepper.set_z2_lock(false);
stepper.set_z3_lock(false);
#endif
}
#endif
// Reset flags for X, Y, Z motor locking
switch (axis) {
default: break;
#if ENABLED(X_DUAL_ENDSTOPS)
case X_AXIS:
#endif
#if ENABLED(Y_DUAL_ENDSTOPS)
case Y_AXIS:
#endif
#if Z_MULTI_ENDSTOPS
#if ENABLED(Z_MULTI_ENDSTOPS)
case Z_AXIS:
#endif
stepper.set_separate_multi_axis(false);
default: break;
stepper.set_separate_multi_axis(false);
}
#endif

View File

@ -156,11 +156,16 @@ bool Stepper::abort_current_block;
#if ENABLED(Y_DUAL_ENDSTOPS)
bool Stepper::locked_Y_motor = false, Stepper::locked_Y2_motor = false;
#endif
#if Z_MULTI_ENDSTOPS || ENABLED(Z_STEPPER_AUTO_ALIGN)
bool Stepper::locked_Z_motor = false, Stepper::locked_Z2_motor = false;
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS) || BOTH(Z_STEPPER_AUTO_ALIGN, Z_TRIPLE_STEPPER_DRIVERS)
bool Stepper::locked_Z3_motor = false;
#if EITHER(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
bool Stepper::locked_Z_motor = false, Stepper::locked_Z2_motor = false
#if NUM_Z_STEPPER_DRIVERS >= 3
, Stepper::locked_Z3_motor = false
#if NUM_Z_STEPPER_DRIVERS >= 4
, Stepper::locked_Z4_motor = false
#endif
#endif
;
#endif
uint32_t Stepper::acceleration_time, Stepper::deceleration_time;
@ -281,6 +286,42 @@ xyze_int8_t Stepper::count_direction{0};
A##3_STEP_WRITE(V); \
}
#define QUAD_ENDSTOP_APPLY_STEP(A,V) \
if (separate_multi_axis) { \
if (A##_HOME_DIR < 0) { \
if (!(TEST(endstops.state(), A##_MIN) && count_direction[_AXIS(A)] < 0) && !locked_##A##_motor) A##_STEP_WRITE(V); \
if (!(TEST(endstops.state(), A##2_MIN) && count_direction[_AXIS(A)] < 0) && !locked_##A##2_motor) A##2_STEP_WRITE(V); \
if (!(TEST(endstops.state(), A##3_MIN) && count_direction[_AXIS(A)] < 0) && !locked_##A##3_motor) A##3_STEP_WRITE(V); \
if (!(TEST(endstops.state(), A##4_MIN) && count_direction[_AXIS(A)] < 0) && !locked_##A##4_motor) A##4_STEP_WRITE(V); \
} \
else { \
if (!(TEST(endstops.state(), A##_MAX) && count_direction[_AXIS(A)] > 0) && !locked_##A##_motor) A##_STEP_WRITE(V); \
if (!(TEST(endstops.state(), A##2_MAX) && count_direction[_AXIS(A)] > 0) && !locked_##A##2_motor) A##2_STEP_WRITE(V); \
if (!(TEST(endstops.state(), A##3_MAX) && count_direction[_AXIS(A)] > 0) && !locked_##A##3_motor) A##3_STEP_WRITE(V); \
if (!(TEST(endstops.state(), A##4_MAX) && count_direction[_AXIS(A)] > 0) && !locked_##A##4_motor) A##4_STEP_WRITE(V); \
} \
} \
else { \
A##_STEP_WRITE(V); \
A##2_STEP_WRITE(V); \
A##3_STEP_WRITE(V); \
A##4_STEP_WRITE(V); \
}
#define QUAD_SEPARATE_APPLY_STEP(A,V) \
if (separate_multi_axis) { \
if (!locked_##A##_motor) A##_STEP_WRITE(V); \
if (!locked_##A##2_motor) A##2_STEP_WRITE(V); \
if (!locked_##A##3_motor) A##3_STEP_WRITE(V); \
if (!locked_##A##4_motor) A##4_STEP_WRITE(V); \
} \
else { \
A##_STEP_WRITE(V); \
A##2_STEP_WRITE(V); \
A##3_STEP_WRITE(V); \
A##4_STEP_WRITE(V); \
}
#if ENABLED(X_DUAL_STEPPER_DRIVERS)
#define X_APPLY_DIR(v,Q) do{ X_DIR_WRITE(v); X2_DIR_WRITE((v) != INVERT_X2_VS_X_DIR); }while(0)
#if ENABLED(X_DUAL_ENDSTOPS)
@ -314,18 +355,27 @@ xyze_int8_t Stepper::count_direction{0};
#define Y_APPLY_STEP(v,Q) Y_STEP_WRITE(v)
#endif
#if ENABLED(Z_TRIPLE_STEPPER_DRIVERS)
#if NUM_Z_STEPPER_DRIVERS == 4
#define Z_APPLY_DIR(v,Q) do{ Z_DIR_WRITE(v); Z2_DIR_WRITE(v); Z3_DIR_WRITE(v); Z4_DIR_WRITE(v); }while(0)
#if ENABLED(Z_MULTI_ENDSTOPS)
#define Z_APPLY_STEP(v,Q) QUAD_ENDSTOP_APPLY_STEP(Z,v)
#elif ENABLED(Z_STEPPER_AUTO_ALIGN)
#define Z_APPLY_STEP(v,Q) QUAD_SEPARATE_APPLY_STEP(Z,v)
#else
#define Z_APPLY_STEP(v,Q) do{ Z_STEP_WRITE(v); Z2_STEP_WRITE(v); Z3_STEP_WRITE(v); Z4_STEP_WRITE(v); }while(0)
#endif
#elif NUM_Z_STEPPER_DRIVERS == 3
#define Z_APPLY_DIR(v,Q) do{ Z_DIR_WRITE(v); Z2_DIR_WRITE(v); Z3_DIR_WRITE(v); }while(0)
#if ENABLED(Z_TRIPLE_ENDSTOPS)
#if ENABLED(Z_MULTI_ENDSTOPS)
#define Z_APPLY_STEP(v,Q) TRIPLE_ENDSTOP_APPLY_STEP(Z,v)
#elif ENABLED(Z_STEPPER_AUTO_ALIGN)
#define Z_APPLY_STEP(v,Q) TRIPLE_SEPARATE_APPLY_STEP(Z,v)
#else
#define Z_APPLY_STEP(v,Q) do{ Z_STEP_WRITE(v); Z2_STEP_WRITE(v); Z3_STEP_WRITE(v); }while(0)
#endif
#elif ENABLED(Z_DUAL_STEPPER_DRIVERS)
#elif NUM_Z_STEPPER_DRIVERS == 2
#define Z_APPLY_DIR(v,Q) do{ Z_DIR_WRITE(v); Z2_DIR_WRITE(v); }while(0)
#if ENABLED(Z_DUAL_ENDSTOPS)
#if ENABLED(Z_MULTI_ENDSTOPS)
#define Z_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(Z,v)
#elif ENABLED(Z_STEPPER_AUTO_ALIGN)
#define Z_APPLY_STEP(v,Q) DUAL_SEPARATE_APPLY_STEP(Z,v)
@ -2062,12 +2112,15 @@ void Stepper::init() {
#endif
#if HAS_Z_DIR
Z_DIR_INIT();
#if Z_MULTI_STEPPER_DRIVERS && HAS_Z2_DIR
#if NUM_Z_STEPPER_DRIVERS >= 2 && HAS_Z2_DIR
Z2_DIR_INIT();
#endif
#if ENABLED(Z_TRIPLE_STEPPER_DRIVERS) && HAS_Z3_DIR
#if NUM_Z_STEPPER_DRIVERS >= 3 && HAS_Z3_DIR
Z3_DIR_INIT();
#endif
#if NUM_Z_STEPPER_DRIVERS >= 4 && HAS_Z4_DIR
Z4_DIR_INIT();
#endif
#endif
#if HAS_E0_DIR
E0_DIR_INIT();
@ -2108,14 +2161,18 @@ void Stepper::init() {
#if HAS_Z_ENABLE
Z_ENABLE_INIT();
if (!Z_ENABLE_ON) Z_ENABLE_WRITE(HIGH);
#if Z_MULTI_STEPPER_DRIVERS && HAS_Z2_ENABLE
#if NUM_Z_STEPPER_DRIVERS >= 2 && HAS_Z2_ENABLE
Z2_ENABLE_INIT();
if (!Z_ENABLE_ON) Z2_ENABLE_WRITE(HIGH);
#endif
#if ENABLED(Z_TRIPLE_STEPPER_DRIVERS) && HAS_Z3_ENABLE
#if NUM_Z_STEPPER_DRIVERS >= 3 && HAS_Z3_ENABLE
Z3_ENABLE_INIT();
if (!Z_ENABLE_ON) Z3_ENABLE_WRITE(HIGH);
#endif
#if NUM_Z_STEPPER_DRIVERS >= 4 && HAS_Z4_ENABLE
Z4_ENABLE_INIT();
if (!Z_ENABLE_ON) Z4_ENABLE_WRITE(HIGH);
#endif
#endif
#if HAS_E0_ENABLE
E0_ENABLE_INIT();
@ -2171,14 +2228,18 @@ void Stepper::init() {
#endif
#if HAS_Z_STEP
#if Z_MULTI_STEPPER_DRIVERS
#if NUM_Z_STEPPER_DRIVERS >= 2
Z2_STEP_INIT();
Z2_STEP_WRITE(INVERT_Z_STEP_PIN);
#endif
#if ENABLED(Z_TRIPLE_STEPPER_DRIVERS)
#if NUM_Z_STEPPER_DRIVERS >= 3
Z3_STEP_INIT();
Z3_STEP_WRITE(INVERT_Z_STEP_PIN);
#endif
#if NUM_Z_STEPPER_DRIVERS >= 4
Z4_STEP_INIT();
Z4_STEP_WRITE(INVERT_Z_STEP_PIN);
#endif
AXIS_INIT(Z, Z);
#endif
@ -2692,6 +2753,13 @@ void Stepper::report_positions() {
SET_OUTPUT(Z3_MS3_PIN);
#endif
#endif
#if HAS_Z4_MICROSTEPS
SET_OUTPUT(Z4_MS1_PIN);
SET_OUTPUT(Z4_MS2_PIN);
#if PIN_EXISTS(Z4_MS3)
SET_OUTPUT(Z4_MS3_PIN);
#endif
#endif
#if HAS_E0_MICROSTEPS
SET_OUTPUT(E0_MS1_PIN);
SET_OUTPUT(E0_MS2_PIN);
@ -2762,7 +2830,7 @@ void Stepper::report_positions() {
#endif
break;
#endif
#if HAS_Z_MICROSTEPS || HAS_Z2_MICROSTEPS || HAS_Z3_MICROSTEPS
#if HAS_SOME_Z_MICROSTEPS
case 2:
#if HAS_Z_MICROSTEPS
WRITE(Z_MS1_PIN, ms1);
@ -2773,6 +2841,9 @@ void Stepper::report_positions() {
#if HAS_Z3_MICROSTEPS
WRITE(Z3_MS1_PIN, ms1);
#endif
#if HAS_Z4_MICROSTEPS
WRITE(Z4_MS1_PIN, ms1);
#endif
break;
#endif
#if HAS_E0_MICROSTEPS
@ -2815,7 +2886,7 @@ void Stepper::report_positions() {
#endif
break;
#endif
#if HAS_Z_MICROSTEPS || HAS_Z2_MICROSTEPS || HAS_Z3_MICROSTEPS
#if HAS_SOME_Z_MICROSTEPS
case 2:
#if HAS_Z_MICROSTEPS
WRITE(Z_MS2_PIN, ms2);
@ -2826,6 +2897,9 @@ void Stepper::report_positions() {
#if HAS_Z3_MICROSTEPS
WRITE(Z3_MS2_PIN, ms2);
#endif
#if HAS_Z4_MICROSTEPS
WRITE(Z4_MS2_PIN, ms2);
#endif
break;
#endif
#if HAS_E0_MICROSTEPS
@ -2868,7 +2942,7 @@ void Stepper::report_positions() {
#endif
break;
#endif
#if HAS_Z_MICROSTEPS || HAS_Z2_MICROSTEPS || HAS_Z3_MICROSTEPS
#if HAS_SOME_Z_MICROSTEPS
case 2:
#if HAS_Z_MICROSTEPS && PIN_EXISTS(Z_MS3)
WRITE(Z_MS3_PIN, ms3);
@ -2879,6 +2953,9 @@ void Stepper::report_positions() {
#if HAS_Z3_MICROSTEPS && PIN_EXISTS(Z3_MS3)
WRITE(Z3_MS3_PIN, ms3);
#endif
#if HAS_Z4_MICROSTEPS && PIN_EXISTS(Z4_MS3)
WRITE(Z4_MS3_PIN, ms3);
#endif
break;
#endif
#if HAS_E0_MICROSTEPS && PIN_EXISTS(E0_MS3)

View File

@ -274,11 +274,15 @@ class Stepper {
#if ENABLED(Y_DUAL_ENDSTOPS)
static bool locked_Y_motor, locked_Y2_motor;
#endif
#if Z_MULTI_ENDSTOPS || ENABLED(Z_STEPPER_AUTO_ALIGN)
static bool locked_Z_motor, locked_Z2_motor;
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS) || BOTH(Z_STEPPER_AUTO_ALIGN, Z_TRIPLE_STEPPER_DRIVERS)
static bool locked_Z3_motor;
#if EITHER(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
static bool locked_Z_motor, locked_Z2_motor
#if NUM_Z_STEPPER_DRIVERS >= 3
, locked_Z3_motor
#if NUM_Z_STEPPER_DRIVERS >= 4
, locked_Z4_motor
#endif
#endif
;
#endif
static uint32_t acceleration_time, deceleration_time; // time measured in Stepper Timer ticks
@ -430,12 +434,15 @@ class Stepper {
FORCE_INLINE static void set_y_lock(const bool state) { locked_Y_motor = state; }
FORCE_INLINE static void set_y2_lock(const bool state) { locked_Y2_motor = state; }
#endif
#if Z_MULTI_ENDSTOPS || (ENABLED(Z_STEPPER_AUTO_ALIGN) && Z_MULTI_STEPPER_DRIVERS)
#if EITHER(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
FORCE_INLINE static void set_z_lock(const bool state) { locked_Z_motor = state; }
FORCE_INLINE static void set_z2_lock(const bool state) { locked_Z2_motor = state; }
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS) || BOTH(Z_STEPPER_AUTO_ALIGN, Z_TRIPLE_STEPPER_DRIVERS)
FORCE_INLINE static void set_z3_lock(const bool state) { locked_Z3_motor = state; }
#if NUM_Z_STEPPER_DRIVERS >= 3
FORCE_INLINE static void set_z3_lock(const bool state) { locked_Z3_motor = state; }
#if NUM_Z_STEPPER_DRIVERS >= 4
FORCE_INLINE static void set_z4_lock(const bool state) { locked_Z4_motor = state; }
#endif
#endif
#endif
#if ENABLED(BABYSTEPPING)

View File

@ -52,6 +52,9 @@
#if AXIS_IS_L64XX(Z3)
L64XX_CLASS(Z3) stepperZ3(L6470_CHAIN_SS_PIN);
#endif
#if AXIS_IS_L64XX(Z4)
L64XX_CLASS(Z4) stepperZ4(L6470_CHAIN_SS_PIN);
#endif
#if AXIS_IS_L64XX(E0)
L64XX_CLASS(E0) stepperE0(L6470_CHAIN_SS_PIN);
#endif

View File

@ -160,6 +160,23 @@
#endif
#endif
// Z4 Stepper
#if HAS_Z4_ENABLE && AXIS_IS_L64XX(Z4)
extern L64XX_CLASS(Z4) stepperZ4;
#define Z4_ENABLE_INIT() NOOP
#define Z4_ENABLE_WRITE(STATE) (STATE ? NOOP : stepperZ4.free())
#define Z4_ENABLE_READ() (stepperZ4.getStatus() & STATUS_HIZ)
#if AXIS_DRIVER_TYPE_Z4(L6474)
#define Z4_DIR_INIT() SET_OUTPUT(Z4_DIR_PIN)
#define Z4_DIR_WRITE(STATE) L6474_DIR_WRITE(Z4, STATE)
#define Z4_DIR_READ() READ(Z4_DIR_PIN)
#else
#define Z4_DIR_INIT() NOOP
#define Z4_DIR_WRITE(STATE) L64XX_DIR_WRITE(Z4, STATE)
#define Z4_DIR_READ() (stepper##Z4.getStatus() & STATUS_DIR);
#endif
#endif
// E0 Stepper
#if AXIS_IS_L64XX(E0)
extern L64XX_CLASS(E0) stepperE0;

View File

@ -57,6 +57,9 @@
#if AXIS_DRIVER_TYPE_Z3(TMC26X)
_TMC26X_DEFINE(Z3);
#endif
#if AXIS_DRIVER_TYPE_Z4(TMC26X)
_TMC26X_DEFINE(Z4);
#endif
#if AXIS_DRIVER_TYPE_E0(TMC26X)
_TMC26X_DEFINE(E0);
#endif
@ -103,6 +106,9 @@ void tmc26x_init_to_defaults() {
#if AXIS_DRIVER_TYPE_Z3(TMC26X)
_TMC26X_INIT(Z3);
#endif
#if AXIS_DRIVER_TYPE_Z4(TMC26X)
_TMC26X_INIT(Z4);
#endif
#if AXIS_DRIVER_TYPE_E0(TMC26X)
_TMC26X_INIT(E0);
#endif

View File

@ -95,6 +95,14 @@ void tmc26x_init_to_defaults();
#define Z3_ENABLE_READ() stepperZ3.isEnabled()
#endif
// Z4 Stepper
#if HAS_Z4_ENABLE && AXIS_DRIVER_TYPE_Z4(TMC26X)
extern TMC26XStepper stepperZ4;
#define Z4_ENABLE_INIT() NOOP
#define Z4_ENABLE_WRITE(STATE) stepperZ4.setEnabled(STATE)
#define Z4_ENABLE_READ() stepperZ4.isEnabled()
#endif
// E0 Stepper
#if AXIS_DRIVER_TYPE_E0(TMC26X)
extern TMC26XStepper stepperE0;

View File

@ -180,6 +180,27 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define Z3_DIR_WRITE(STATE) NOOP
#endif
// Z4 Stepper
#if HAS_Z4_ENABLE
#ifndef Z4_ENABLE_INIT
#define Z4_ENABLE_INIT() SET_OUTPUT(Z4_ENABLE_PIN)
#define Z4_ENABLE_WRITE(STATE) WRITE(Z4_ENABLE_PIN,STATE)
#define Z4_ENABLE_READ() READ(Z4_ENABLE_PIN)
#endif
#ifndef Z4_DIR_INIT
#define Z4_DIR_INIT() SET_OUTPUT(Z4_DIR_PIN)
#define Z4_DIR_WRITE(STATE) WRITE(Z4_DIR_PIN,STATE)
#define Z4_DIR_READ() READ(Z4_DIR_PIN)
#endif
#define Z4_STEP_INIT SET_OUTPUT(Z4_STEP_PIN)
#ifndef Z4_STEP_WRITE
#define Z4_STEP_WRITE(STATE) WRITE(Z4_STEP_PIN,STATE)
#endif
#define Z4_STEP_READ READ(Z4_STEP_PIN)
#else
#define Z4_DIR_WRITE(STATE) NOOP
#endif
// E0 Stepper
#ifndef E0_ENABLE_INIT
#define E0_ENABLE_INIT() SET_OUTPUT(E0_ENABLE_PIN)
@ -491,8 +512,20 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define Z3_disable() NOOP
#endif
#define enable_Z() do{ Z_enable(); Z2_enable(); Z3_enable(); }while(0)
#define disable_Z() do{ Z_disable(); Z2_disable(); Z3_disable(); CBI(axis_known_position, Z_AXIS); }while(0)
#if AXIS_DRIVER_TYPE_Z4(L6470)
extern L6470 stepperZ4;
#define Z4_enable() NOOP
#define Z4_disable() stepperZ4.free()
#elif HAS_Z4_ENABLE
#define Z4_enable() Z4_ENABLE_WRITE( Z_ENABLE_ON)
#define Z4_disable() Z4_ENABLE_WRITE(!Z_ENABLE_ON)
#else
#define Z4_enable() NOOP
#define Z4_disable() NOOP
#endif
#define enable_Z() do{ Z_enable(); Z2_enable(); Z3_enable(); Z4_enable(); }while(0)
#define disable_Z() do{ Z_disable(); Z2_disable(); Z3_disable(); Z4_disable(); CBI(axis_known_position, Z_AXIS); }while(0)
//
// Extruder Stepper enable / disable

View File

@ -88,6 +88,9 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E };
#if AXIS_HAS_SPI(Z3)
TMC_SPI_DEFINE(Z3, Z);
#endif
#if AXIS_HAS_SPI(Z4)
TMC_SPI_DEFINE(Z4, Z);
#endif
#if AXIS_HAS_SPI(E0)
TMC_SPI_DEFINE_E(0);
#endif
@ -249,6 +252,13 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E };
TMC_UART_DEFINE(SW, Z3, Z);
#endif
#endif
#if AXIS_HAS_UART(Z4)
#ifdef Z4_HARDWARE_SERIAL
TMC_UART_DEFINE(HW, Z4, Z);
#else
TMC_UART_DEFINE(SW, Z4, Z);
#endif
#endif
#if AXIS_HAS_UART(E0)
#ifdef E0_HARDWARE_SERIAL
TMC_UART_DEFINE_E(HW, 0);
@ -342,6 +352,13 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E };
stepperZ3.beginSerial(TMC_BAUD_RATE);
#endif
#endif
#if AXIS_HAS_UART(Z4)
#ifdef Z4_HARDWARE_SERIAL
Z4_HARDWARE_SERIAL.begin(TMC_BAUD_RATE);
#else
stepperZ4.beginSerial(TMC_BAUD_RATE);
#endif
#endif
#if AXIS_HAS_UART(E0)
#ifdef E0_HARDWARE_SERIAL
E0_HARDWARE_SERIAL.begin(TMC_BAUD_RATE);
@ -616,6 +633,9 @@ void restore_trinamic_drivers() {
#if AXIS_IS_TMC(Z3)
stepperZ3.push();
#endif
#if AXIS_IS_TMC(Z4)
stepperZ4.push();
#endif
#if AXIS_IS_TMC(E0)
stepperE0.push();
#endif
@ -678,6 +698,9 @@ void reset_trinamic_drivers() {
#if AXIS_IS_TMC(Z3)
_TMC_INIT(Z3, STEALTH_AXIS_Z);
#endif
#if AXIS_IS_TMC(Z4)
_TMC_INIT(Z4, STEALTH_AXIS_Z);
#endif
#if AXIS_IS_TMC(E0)
_TMC_INIT(E0, STEALTH_AXIS_E);
#endif
@ -727,6 +750,9 @@ void reset_trinamic_drivers() {
#if AXIS_HAS_STALLGUARD(Z3)
stepperZ3.homing_threshold(Z_STALL_SENSITIVITY);
#endif
#if AXIS_HAS_STALLGUARD(Z4)
stepperZ4.homing_threshold(Z_STALL_SENSITIVITY);
#endif
#endif
#endif

View File

@ -50,6 +50,7 @@
#define TMC_Y2_LABEL 'Y', '2'
#define TMC_Z2_LABEL 'Z', '2'
#define TMC_Z3_LABEL 'Z', '3'
#define TMC_Z4_LABEL 'Z', '4'
#define TMC_E0_LABEL 'E', '0'
#define TMC_E1_LABEL 'E', '1'
@ -175,6 +176,19 @@ void reset_trinamic_drivers();
#endif
#endif
// Z4 Stepper
#if HAS_Z4_ENABLE && AXIS_IS_TMC(Z4)
extern TMC_CLASS(Z4, Z) stepperZ4;
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
#define Z4_ENABLE_INIT() NOOP
#define Z4_ENABLE_WRITE(STATE) stepperZ4.toff((STATE)==Z_ENABLE_ON ? chopper_timing.toff : 0)
#define Z4_ENABLE_READ() stepperZ4.isEnabled()
#endif
#if AXIS_HAS_SQUARE_WAVE(Z4)
#define Z4_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(Z4_STEP_PIN); }while(0)
#endif
#endif
// E0 Stepper
#if AXIS_IS_TMC(E0)
extern TMC_CLASS_E(0) stepperE0;