Add support for Triple-Z steppers/endstops

This commit is contained in:
Holger Müller
2018-06-19 18:55:49 +02:00
committed by Scott Lahteine
parent bc06406d7d
commit 1a6f2b29b8
37 changed files with 901 additions and 155 deletions

View File

@ -194,10 +194,13 @@ typedef struct SettingsDataStruct {
delta_segments_per_second, // M665 S
delta_calibration_radius, // M665 B
delta_tower_angle_trim[ABC]; // M665 XYZ
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
float x_endstop_adj, // M666 X
y_endstop_adj, // M666 Y
z_endstop_adj; // M666 Z
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
float x2_endstop_adj, // M666 X
y2_endstop_adj, // M666 Y
z2_endstop_adj; // M666 Z
#if ENABLED(Z_TRIPLE_ENDSTOPS)
float z3_endstop_adj; // M666 Z
#endif
#endif
//
@ -246,9 +249,9 @@ typedef struct SettingsDataStruct {
//
// HAS_TRINAMIC
//
#define TMC_AXES (MAX_EXTRUDERS + 6)
uint16_t tmc_stepper_current[TMC_AXES]; // M906 X Y Z X2 Y2 Z2 E0 E1 E2 E3 E4
uint32_t tmc_hybrid_threshold[TMC_AXES]; // M913 X Y Z X2 Y2 Z2 E0 E1 E2 E3 E4
#define TMC_AXES (MAX_EXTRUDERS + 7)
uint16_t tmc_stepper_current[TMC_AXES]; // M906 X Y Z X2 Y2 Z2 Z3 E0 E1 E2 E3 E4
uint32_t tmc_hybrid_threshold[TMC_AXES]; // M913 X Y Z X2 Y2 Z2 Z3 E0 E1 E2 E3 E4
int16_t tmc_sgt[XYZ]; // M914 X Y Z
//
@ -574,26 +577,32 @@ void MarlinSettings::postprocess() {
EEPROM_WRITE(delta_calibration_radius); // 1 float
EEPROM_WRITE(delta_tower_angle_trim); // 3 floats
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
_FIELD_TEST(x_endstop_adj);
_FIELD_TEST(x2_endstop_adj);
// Write dual endstops in X, Y, Z order. Unused = 0.0
dummy = 0;
#if ENABLED(X_DUAL_ENDSTOPS)
EEPROM_WRITE(endstops.x_endstop_adj); // 1 float
EEPROM_WRITE(endstops.x2_endstop_adj); // 1 float
#else
EEPROM_WRITE(dummy);
#endif
#if ENABLED(Y_DUAL_ENDSTOPS)
EEPROM_WRITE(endstops.y_endstop_adj); // 1 float
EEPROM_WRITE(endstops.y2_endstop_adj); // 1 float
#else
EEPROM_WRITE(dummy);
#endif
#if ENABLED(Z_DUAL_ENDSTOPS)
EEPROM_WRITE(endstops.z_endstop_adj); // 1 float
#if Z_MULTI_ENDSTOPS
EEPROM_WRITE(endstops.z2_endstop_adj); // 1 float
#else
EEPROM_WRITE(dummy);
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS)
EEPROM_WRITE(endstops.z3_endstop_adj); // 1 float
#else
EEPROM_WRITE(dummy);
#endif
@ -740,6 +749,11 @@ void MarlinSettings::postprocess() {
#else
0,
#endif
#if AXIS_IS_TMC(Z3)
stepperZ3.getCurrent(),
#else
0,
#endif
#if AXIS_IS_TMC(E0)
stepperE0.getCurrent(),
#else
@ -809,6 +823,11 @@ void MarlinSettings::postprocess() {
#else
Z2_HYBRID_THRESHOLD,
#endif
#if AXIS_HAS_STEALTHCHOP(Z3)
TMC_GET_PWMTHRS(Z, Z3),
#else
Z3_HYBRID_THRESHOLD,
#endif
#if AXIS_HAS_STEALTHCHOP(E0)
TMC_GET_PWMTHRS(E, E0),
#else
@ -836,7 +855,7 @@ void MarlinSettings::postprocess() {
#endif
#else
100, 100, 3, // X, Y, Z
100, 100, 3, // X2, Y2, Z2
100, 100, 3, 3, // X2, Y2, Z2, Z3
30, 30, 30, 30, 30 // E0, E1, E2, E3, E4
#endif
};
@ -1187,22 +1206,27 @@ void MarlinSettings::postprocess() {
EEPROM_READ(delta_calibration_radius); // 1 float
EEPROM_READ(delta_tower_angle_trim); // 3 floats
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
_FIELD_TEST(x_endstop_adj);
_FIELD_TEST(x2_endstop_adj);
#if ENABLED(X_DUAL_ENDSTOPS)
EEPROM_READ(endstops.x_endstop_adj); // 1 float
EEPROM_READ(endstops.x2_endstop_adj); // 1 float
#else
EEPROM_READ(dummy);
#endif
#if ENABLED(Y_DUAL_ENDSTOPS)
EEPROM_READ(endstops.y_endstop_adj); // 1 float
EEPROM_READ(endstops.y2_endstop_adj); // 1 float
#else
EEPROM_READ(dummy);
#endif
#if ENABLED(Z_DUAL_ENDSTOPS)
EEPROM_READ(endstops.z_endstop_adj); // 1 float
#if Z_MULTI_ENDSTOPS
EEPROM_READ(endstops.z2_endstop_adj); // 1 float
#else
EEPROM_READ(dummy);
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS)
EEPROM_READ(endstops.z3_endstop_adj); // 1 float
#else
EEPROM_READ(dummy);
#endif
@ -1365,6 +1389,9 @@ void MarlinSettings::postprocess() {
#if AXIS_IS_TMC(Z2)
SET_CURR(Z2);
#endif
#if AXIS_IS_TMC(Z3)
SET_CURR(Z3);
#endif
#if AXIS_IS_TMC(E0)
SET_CURR(E0);
#endif
@ -1409,6 +1436,9 @@ void MarlinSettings::postprocess() {
#if AXIS_HAS_STEALTHCHOP(Z2)
TMC_SET_PWMTHRS(Z, Z2);
#endif
#if AXIS_HAS_STEALTHCHOP(Z3)
TMC_SET_PWMTHRS(Z, Z3);
#endif
#if AXIS_HAS_STEALTHCHOP(E0)
TMC_SET_PWMTHRS(E, E0);
#endif
@ -1434,7 +1464,7 @@ void MarlinSettings::postprocess() {
* TMC2130 Sensorless homing threshold.
* X and X2 use the same value
* Y and Y2 use the same value
* Z and Z2 use the same value
* Z, Z2 and Z3 use the same value
*/
int16_t tmc_sgt[XYZ];
EEPROM_READ(tmc_sgt);
@ -1463,6 +1493,9 @@ void MarlinSettings::postprocess() {
#if AXIS_HAS_STALLGUARD(Z2)
stepperZ2.sgt(tmc_sgt[2]);
#endif
#if AXIS_HAS_STALLGUARD(Z3)
stepperZ3.sgt(tmc_sgt[2]);
#endif
#endif
}
#endif
@ -1860,10 +1893,10 @@ void MarlinSettings::reset(PORTARG_SOLO) {
delta_calibration_radius = DELTA_CALIBRATION_RADIUS;
COPY(delta_tower_angle_trim, dta);
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
#if ENABLED(X_DUAL_ENDSTOPS)
endstops.x_endstop_adj = (
endstops.x2_endstop_adj = (
#ifdef X_DUAL_ENDSTOPS_ADJUSTMENT
X_DUAL_ENDSTOPS_ADJUSTMENT
#else
@ -1872,7 +1905,7 @@ void MarlinSettings::reset(PORTARG_SOLO) {
);
#endif
#if ENABLED(Y_DUAL_ENDSTOPS)
endstops.y_endstop_adj = (
endstops.y2_endstop_adj = (
#ifdef Y_DUAL_ENDSTOPS_ADJUSTMENT
Y_DUAL_ENDSTOPS_ADJUSTMENT
#else
@ -1881,13 +1914,28 @@ void MarlinSettings::reset(PORTARG_SOLO) {
);
#endif
#if ENABLED(Z_DUAL_ENDSTOPS)
endstops.z_endstop_adj = (
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
);
#endif
#endif
@ -2391,13 +2439,17 @@ void MarlinSettings::reset(PORTARG_SOLO) {
CONFIG_ECHO_START;
SERIAL_ECHOPGM_P(port, " M666");
#if ENABLED(X_DUAL_ENDSTOPS)
SERIAL_ECHOPAIR_P(port, " X", LINEAR_UNIT(endstops.x_endstop_adj));
SERIAL_ECHOPAIR_P(port, " X", LINEAR_UNIT(endstops.x2_endstop_adj));
#endif
#if ENABLED(Y_DUAL_ENDSTOPS)
SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(endstops.y_endstop_adj));
SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(endstops.y2_endstop_adj));
#endif
#if ENABLED(Z_DUAL_ENDSTOPS)
SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(endstops.z_endstop_adj));
#if ENABLED(Z_TRIPLE_ENDSTOPS)
SERIAL_ECHOLNPAIR_P(port, "S1 Z", LINEAR_UNIT(endstops.z2_endstop_adj));
CONFIG_ECHO_START;
SERIAL_ECHOPAIR_P(port, " M666 S2 Z", LINEAR_UNIT(endstops.z3_endstop_adj));
#elif ENABLED(Z_DUAL_ENDSTOPS)
SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(endstops.z2_endstop_adj));
#endif
SERIAL_EOL_P(port);
@ -2582,6 +2634,10 @@ void MarlinSettings::reset(PORTARG_SOLO) {
#if AXIS_IS_TMC(X2) || AXIS_IS_TMC(Y2) || AXIS_IS_TMC(Z2)
SERIAL_EOL_P(port);
#endif
#if AXIS_IS_TMC(Z3)
say_M906(PORTVAR_SOLO);
SERIAL_ECHOLNPAIR_P(port, " I2 Z", stepperZ3.getCurrent());
#endif
#if AXIS_IS_TMC(E0)
say_M906(PORTVAR_SOLO);
SERIAL_ECHOLNPAIR_P(port, " T0 E", stepperE0.getCurrent());
@ -2644,6 +2700,11 @@ void MarlinSettings::reset(PORTARG_SOLO) {
#if AXIS_IS_TMC(X2) || AXIS_IS_TMC(Y2) || AXIS_IS_TMC(Z2)
SERIAL_EOL_P(port);
#endif
#if AXIS_IS_TMC(Z3)
say_M913(PORTVAR_SOLO);
SERIAL_ECHOPGM_P(port, " I2");
SERIAL_ECHOLNPAIR_P(port, " Z", TMC_GET_PWMTHRS(Z, Z3));
#endif
#if AXIS_IS_TMC(E0)
say_M913(PORTVAR_SOLO);
SERIAL_ECHOLNPAIR_P(port, " T0 E", TMC_GET_PWMTHRS(E, E0));
@ -2693,6 +2754,7 @@ void MarlinSettings::reset(PORTARG_SOLO) {
#define HAS_X2_SENSORLESS (defined(X_HOMING_SENSITIVITY) && AXIS_HAS_STALLGUARD(X2))
#define HAS_Y2_SENSORLESS (defined(Y_HOMING_SENSITIVITY) && AXIS_HAS_STALLGUARD(Y2))
#define HAS_Z2_SENSORLESS (defined(Z_HOMING_SENSITIVITY) && AXIS_HAS_STALLGUARD(Z2))
#define HAS_Z3_SENSORLESS (defined(Z_HOMING_SENSITIVITY) && AXIS_HAS_STALLGUARD(Z3))
#if HAS_X2_SENSORLESS || HAS_Y2_SENSORLESS || HAS_Z2_SENSORLESS
say_M914(PORTVAR_SOLO);
SERIAL_ECHOPGM_P(port, " I1");
@ -2708,6 +2770,12 @@ void MarlinSettings::reset(PORTARG_SOLO) {
SERIAL_EOL_P(port);
#endif
#if HAS_Z3_SENSORLESS
say_M914(PORTVAR_SOLO);
SERIAL_ECHOPGM_P(port, " I2");
SERIAL_ECHOLNPAIR_P(port, " Z", stepperZ3.sgt());
#endif
#endif // SENSORLESS_HOMING
#endif // HAS_TRINAMIC

View File

@ -56,13 +56,16 @@ Endstops::esbits_t Endstops::live_state = 0;
// Initialized by settings.load()
#if ENABLED(X_DUAL_ENDSTOPS)
float Endstops::x_endstop_adj;
float Endstops::x2_endstop_adj;
#endif
#if ENABLED(Y_DUAL_ENDSTOPS)
float Endstops::y_endstop_adj;
float Endstops::y2_endstop_adj;
#endif
#if ENABLED(Z_DUAL_ENDSTOPS)
float Endstops::z_endstop_adj;
#if Z_MULTI_ENDSTOPS
float Endstops::z2_endstop_adj;
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS)
float Endstops::z3_endstop_adj;
#endif
/**
@ -131,6 +134,16 @@ void Endstops::init() {
#endif
#endif
#if HAS_Z3_MIN
#if ENABLED(ENDSTOPPULLUP_ZMIN)
SET_INPUT_PULLUP(Z3_MIN_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_ZMIN)
SET_INPUT_PULLDOWN(Z3_MIN_PIN);
#else
SET_INPUT(Z3_MIN_PIN);
#endif
#endif
#if HAS_X_MAX
#if ENABLED(ENDSTOPPULLUP_XMAX)
SET_INPUT_PULLUP(X_MAX_PIN);
@ -191,6 +204,16 @@ void Endstops::init() {
#endif
#endif
#if HAS_Z3_MAX
#if ENABLED(ENDSTOPPULLUP_ZMAX)
SET_INPUT_PULLUP(Z3_MAX_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_ZMAX)
SET_INPUT_PULLDOWN(Z3_MAX_PIN);
#else
SET_INPUT(Z3_MAX_PIN);
#endif
#endif
#if ENABLED(Z_MIN_PROBE_ENDSTOP)
#if ENABLED(ENDSTOPPULLUP_ZMIN_PROBE)
SET_INPUT_PULLUP(Z_MIN_PROBE_PIN);
@ -371,12 +394,18 @@ void Endstops::M119() {
#if HAS_Z2_MIN
ES_REPORT(Z2_MIN);
#endif
#if HAS_Z3_MIN
ES_REPORT(Z3_MIN);
#endif
#if HAS_Z_MAX
ES_REPORT(Z_MAX);
#endif
#if HAS_Z2_MAX
ES_REPORT(Z2_MAX);
#endif
#if HAS_Z3_MAX
ES_REPORT(Z3_MAX);
#endif
#if ENABLED(Z_MIN_PROBE_ENDSTOP)
SERIAL_PROTOCOLPGM(MSG_Z_PROBE);
SERIAL_PROTOCOLLN(((READ(Z_MIN_PROBE_PIN)^Z_MIN_PROBE_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
@ -492,13 +521,20 @@ void Endstops::update() {
#endif
#if HAS_Z_MIN
#if ENABLED(Z_DUAL_ENDSTOPS)
#if Z_MULTI_ENDSTOPS
UPDATE_ENDSTOP_BIT(Z, MIN);
#if HAS_Z2_MIN
UPDATE_ENDSTOP_BIT(Z2, MIN);
#else
COPY_LIVE_STATE(Z_MIN, Z2_MIN);
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS)
#if HAS_Z3_MIN
UPDATE_ENDSTOP_BIT(Z3, MIN);
#else
COPY_LIVE_STATE(Z_MIN, Z3_MIN);
#endif
#endif
#elif ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
UPDATE_ENDSTOP_BIT(Z, MIN);
#elif Z_HOME_DIR < 0
@ -513,13 +549,20 @@ void Endstops::update() {
#if HAS_Z_MAX
// Check both Z dual endstops
#if ENABLED(Z_DUAL_ENDSTOPS)
#if 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 HAS_Z3_MAX
UPDATE_ENDSTOP_BIT(Z3, MAX);
#else
COPY_LIVE_STATE(Z_MAX, Z3_MAX);
#endif
#endif
#elif DISABLED(Z_MIN_PROBE_ENDSTOP) || 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);
@ -569,7 +612,17 @@ void Endstops::update() {
if (dual_hit) { \
_ENDSTOP_HIT(AXIS1, MINMAX); \
/* if not performing home or if both endstops were trigged during homing... */ \
if (!stepper.homing_dual_axis || dual_hit == 0b11) \
if (!stepper.separate_multi_axis || dual_hit == 0b11) \
planner.endstop_triggered(_AXIS(AXIS1)); \
} \
}while(0)
#define PROCESS_TRIPLE_ENDSTOP(AXIS1, AXIS2, AXIS3, MINMAX) do { \
const byte triple_hit = TEST_ENDSTOP(_ENDSTOP(AXIS1, MINMAX)) | (TEST_ENDSTOP(_ENDSTOP(AXIS2, MINMAX)) << 1) | (TEST_ENDSTOP(_ENDSTOP(AXIS3, MINMAX)) << 2); \
if (triple_hit) { \
_ENDSTOP_HIT(AXIS1, MINMAX); \
/* if not performing home or if both endstops were trigged during homing... */ \
if (!stepper.separate_multi_axis || triple_hit == 0x7) \
planner.endstop_triggered(_AXIS(AXIS1)); \
} \
}while(0)
@ -632,7 +685,9 @@ 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
#if ENABLED(Z_DUAL_ENDSTOPS)
#if ENABLED(Z_TRIPLE_ENDSTOPS)
PROCESS_TRIPLE_ENDSTOP(Z, Z2, Z3, MIN);
#elif ENABLED(Z_DUAL_ENDSTOPS)
PROCESS_DUAL_ENDSTOP(Z, Z2, MIN);
#else
#if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
@ -652,7 +707,9 @@ void Endstops::update() {
}
else { // Z +direction. Gantry up, bed down.
#if HAS_Z_MAX
#if ENABLED(Z_DUAL_ENDSTOPS)
#if ENABLED(Z_TRIPLE_ENDSTOPS)
PROCESS_TRIPLE_ENDSTOP(Z, Z2, Z3, MAX);
#elif ENABLED(Z_DUAL_ENDSTOPS)
PROCESS_DUAL_ENDSTOP(Z, Z2, MAX);
#elif DISABLED(Z_MIN_PROBE_ENDSTOP) || Z_MAX_PIN != Z_MIN_PROBE_PIN
// If this pin is not hijacked for the bed probe
@ -723,6 +780,12 @@ void Endstops::update() {
#if HAS_Z2_MAX
if (READ(Z2_MAX_PIN)) SBI(live_state_local, Z2_MAX);
#endif
#if HAS_Z3_MIN
if (READ(Z3_MIN_PIN)) SBI(live_state_local, Z3_MIN);
#endif
#if HAS_Z3_MAX
if (READ(Z3_MAX_PIN)) SBI(live_state_local, Z3_MAX);
#endif
uint16_t endstop_change = live_state_local ^ old_live_state_local;
@ -766,6 +829,12 @@ void Endstops::update() {
#if HAS_Z2_MAX
if (TEST(endstop_change, Z2_MAX)) SERIAL_PROTOCOLPAIR(" Z2_MAX:", TEST(live_state_local, Z2_MAX));
#endif
#if HAS_Z3_MIN
if (TEST(endstop_change, Z3_MIN)) SERIAL_PROTOCOLPAIR(" Z3_MIN:", TEST(live_state_local, Z3_MIN));
#endif
#if HAS_Z3_MAX
if (TEST(endstop_change, Z3_MAX)) SERIAL_PROTOCOLPAIR(" Z3_MAX:", TEST(live_state_local, Z3_MAX));
#endif
SERIAL_PROTOCOLPGM("\n\n");
analogWrite(LED_PIN, local_LED_status);
local_LED_status ^= 255;

View File

@ -45,7 +45,9 @@ enum EndstopEnum : char {
Y2_MIN,
Y2_MAX,
Z2_MIN,
Z2_MAX
Z2_MAX,
Z3_MIN,
Z3_MAX
};
class Endstops {
@ -54,16 +56,19 @@ class Endstops {
static bool enabled, enabled_globally;
#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
typedef uint16_t esbits_t;
#if ENABLED(X_DUAL_ENDSTOPS)
static float x_endstop_adj;
static float x2_endstop_adj;
#endif
#if ENABLED(Y_DUAL_ENDSTOPS)
static float y_endstop_adj;
static float y2_endstop_adj;
#endif
#if ENABLED(Z_DUAL_ENDSTOPS)
static float z_endstop_adj;
#if Z_MULTI_ENDSTOPS
static float z2_endstop_adj;
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS)
static float z3_endstop_adj;
#endif
#else
typedef uint8_t esbits_t;

View File

@ -1313,7 +1313,7 @@ void homeaxis(const AxisEnum axis) {
#endif
// Set flags for X, Y, Z motor locking
#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
switch (axis) {
#if ENABLED(X_DUAL_ENDSTOPS)
case X_AXIS:
@ -1324,7 +1324,17 @@ void homeaxis(const AxisEnum axis) {
#if ENABLED(Z_DUAL_ENDSTOPS)
case Z_AXIS:
#endif
stepper.set_homing_dual_axis(true);
stepper.set_separate_multi_axis(true);
default: break;
}
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS)
switch (axis) {
#if ENABLED(Z_TRIPLE_ENDSTOPS)
case Z_AXIS:
#endif
stepper.set_separate_multi_axis(true);
default: break;
}
#endif
@ -1384,13 +1394,13 @@ void homeaxis(const AxisEnum axis) {
#endif
}
#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
const bool pos_dir = axis_home_dir > 0;
#if ENABLED(X_DUAL_ENDSTOPS)
if (axis == X_AXIS) {
const float adj = ABS(endstops.x_endstop_adj);
const float adj = ABS(endstops.x2_endstop_adj);
if (adj) {
if (pos_dir ? (endstops.x_endstop_adj > 0) : (endstops.x_endstop_adj < 0)) stepper.set_x_lock(true); else stepper.set_x2_lock(true);
if (pos_dir ? (endstops.x2_endstop_adj > 0) : (endstops.x2_endstop_adj < 0)) stepper.set_x_lock(true); else stepper.set_x2_lock(true);
do_homing_move(axis, pos_dir ? -adj : adj);
stepper.set_x_lock(false);
stepper.set_x2_lock(false);
@ -1399,9 +1409,9 @@ void homeaxis(const AxisEnum axis) {
#endif
#if ENABLED(Y_DUAL_ENDSTOPS)
if (axis == Y_AXIS) {
const float adj = ABS(endstops.y_endstop_adj);
const float adj = ABS(endstops.y2_endstop_adj);
if (adj) {
if (pos_dir ? (endstops.y_endstop_adj > 0) : (endstops.y_endstop_adj < 0)) stepper.set_y_lock(true); else stepper.set_y2_lock(true);
if (pos_dir ? (endstops.y2_endstop_adj > 0) : (endstops.y2_endstop_adj < 0)) stepper.set_y_lock(true); else stepper.set_y2_lock(true);
do_homing_move(axis, pos_dir ? -adj : adj);
stepper.set_y_lock(false);
stepper.set_y2_lock(false);
@ -1410,16 +1420,62 @@ void homeaxis(const AxisEnum axis) {
#endif
#if ENABLED(Z_DUAL_ENDSTOPS)
if (axis == Z_AXIS) {
const float adj = ABS(endstops.z_endstop_adj);
const float adj = ABS(endstops.z2_endstop_adj);
if (adj) {
if (pos_dir ? (endstops.z_endstop_adj > 0) : (endstops.z_endstop_adj < 0)) stepper.set_z_lock(true); else stepper.set_z2_lock(true);
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);
}
}
#endif
stepper.set_homing_dual_axis(false);
#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};
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
#if IS_SCARA

View File

@ -107,8 +107,8 @@ Stepper stepper; // Singleton
// public:
#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
bool Stepper::homing_dual_axis = false;
#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
bool Stepper::separate_multi_axis = false;
#endif
#if HAS_MOTOR_CURRENT_PWM
@ -134,9 +134,12 @@ bool Stepper::abort_current_block;
#if ENABLED(Y_DUAL_ENDSTOPS)
bool Stepper::locked_Y_motor = false, Stepper::locked_Y2_motor = false;
#endif
#if ENABLED(Z_DUAL_ENDSTOPS)
#if Z_MULTI_ENDSTOPS
bool Stepper::locked_Z_motor = false, Stepper::locked_Z2_motor = false;
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS)
bool Stepper::locked_Z3_motor = false;
#endif
uint32_t Stepper::acceleration_time, Stepper::deceleration_time;
uint8_t Stepper::steps_per_isr;
@ -202,23 +205,40 @@ volatile int32_t Stepper::endstops_trigsteps[XYZ];
volatile int32_t Stepper::count_position[NUM_AXIS] = { 0 };
int8_t Stepper::count_direction[NUM_AXIS] = { 0, 0, 0, 0 };
#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
#define DUAL_ENDSTOP_APPLY_STEP(A,V) \
if (homing_dual_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); \
} \
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); \
} \
} \
else { \
A##_STEP_WRITE(V); \
A##2_STEP_WRITE(V); \
}
#endif
#define DUAL_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); \
} \
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); \
} \
} \
else { \
A##_STEP_WRITE(V); \
A##2_STEP_WRITE(V); \
}
#define TRIPLE_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); \
} \
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); \
} \
} \
else { \
A##_STEP_WRITE(V); \
A##2_STEP_WRITE(V); \
A##3_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)
@ -261,7 +281,14 @@ int8_t Stepper::count_direction[NUM_AXIS] = { 0, 0, 0, 0 };
#define Y_APPLY_STEP(v,Q) Y_STEP_WRITE(v)
#endif
#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
#if ENABLED(Z_TRIPLE_STEPPER_DRIVERS)
#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)
#define Z_APPLY_STEP(v,Q) TRIPLE_ENDSTOP_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)
#define Z_APPLY_DIR(v,Q) do{ Z_DIR_WRITE(v); Z2_DIR_WRITE(v); }while(0)
#if ENABLED(Z_DUAL_ENDSTOPS)
#define Z_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(Z,v)
@ -1933,9 +1960,12 @@ void Stepper::init() {
#endif
#if HAS_Z_DIR
Z_DIR_INIT;
#if ENABLED(Z_DUAL_STEPPER_DRIVERS) && HAS_Z2_DIR
#if Z_MULTI_STEPPER_DRIVERS && HAS_Z2_DIR
Z2_DIR_INIT;
#endif
#if ENABLED(Z_TRIPLE_STEPPER_DRIVERS) && HAS_Z3_DIR
Z3_DIR_INIT;
#endif
#endif
#if HAS_E0_DIR
E0_DIR_INIT;
@ -1973,10 +2003,14 @@ void Stepper::init() {
#if HAS_Z_ENABLE
Z_ENABLE_INIT;
if (!Z_ENABLE_ON) Z_ENABLE_WRITE(HIGH);
#if ENABLED(Z_DUAL_STEPPER_DRIVERS) && HAS_Z2_ENABLE
#if Z_MULTI_STEPPER_DRIVERS && HAS_Z2_ENABLE
Z2_ENABLE_INIT;
if (!Z_ENABLE_ON) Z2_ENABLE_WRITE(HIGH);
#endif
#if ENABLED(Z_TRIPLE_STEPPER_DRIVERS) && HAS_Z3_ENABLE
Z3_ENABLE_INIT;
if (!Z_ENABLE_ON) Z3_ENABLE_WRITE(HIGH);
#endif
#endif
#if HAS_E0_ENABLE
E0_ENABLE_INIT;
@ -2028,10 +2062,14 @@ void Stepper::init() {
#endif
#if HAS_Z_STEP
#if ENABLED(Z_DUAL_STEPPER_DRIVERS)
#if Z_MULTI_STEPPER_DRIVERS
Z2_STEP_INIT;
Z2_STEP_WRITE(INVERT_Z_STEP_PIN);
#endif
#if ENABLED(Z_TRIPLE_STEPPER_DRIVERS)
Z3_STEP_INIT;
Z3_STEP_WRITE(INVERT_Z_STEP_PIN);
#endif
AXIS_INIT(Z, Z);
#endif

View File

@ -234,8 +234,8 @@ class Stepper {
public:
#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
static bool homing_dual_axis;
#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
static bool separate_multi_axis;
#endif
#if HAS_MOTOR_CURRENT_PWM
@ -267,9 +267,12 @@ class Stepper {
#if ENABLED(Y_DUAL_ENDSTOPS)
static bool locked_Y_motor, locked_Y2_motor;
#endif
#if ENABLED(Z_DUAL_ENDSTOPS)
#if Z_MULTI_ENDSTOPS
static bool locked_Z_motor, locked_Z2_motor;
#endif
#if ENABLED(Z_TRIPLE_ENDSTOPS)
static bool locked_Z3_motor;
#endif
static uint32_t acceleration_time, deceleration_time; // time measured in Stepper Timer ticks
static uint8_t steps_per_isr; // Count of steps to perform per Stepper ISR call
@ -415,8 +418,8 @@ class Stepper {
static void microstep_readings();
#endif
#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
FORCE_INLINE static void set_homing_dual_axis(const bool state) { homing_dual_axis = state; }
#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || Z_MULTI_ENDSTOPS
FORCE_INLINE static void set_separate_multi_axis(const bool state) { separate_multi_axis = state; }
#endif
#if ENABLED(X_DUAL_ENDSTOPS)
FORCE_INLINE static void set_x_lock(const bool state) { locked_X_motor = state; }
@ -426,10 +429,13 @@ 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 ENABLED(Z_DUAL_ENDSTOPS)
#if Z_MULTI_ENDSTOPS
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)
FORCE_INLINE static void set_z3_lock(const bool state) { locked_Z3_motor = state; }
#endif
#if ENABLED(BABYSTEPPING)
static void babystep(const AxisEnum axis, const bool direction); // perform a short step with a single stepper motor, outside of any convention

View File

@ -69,6 +69,9 @@
#if AXIS_DRIVER_TYPE(Z2, TMC26X)
_TMC26X_DEFINE(Z2);
#endif
#if AXIS_DRIVER_TYPE(Z3, TMC26X)
_TMC26X_DEFINE(Z3);
#endif
#if AXIS_DRIVER_TYPE(E0, TMC26X)
_TMC26X_DEFINE(E0);
#endif
@ -109,6 +112,9 @@
#if AXIS_DRIVER_TYPE(Z2, TMC26X)
_TMC26X_INIT(Z2);
#endif
#if AXIS_DRIVER_TYPE(Z3, TMC26X)
_TMC26X_INIT(Z3);
#endif
#if AXIS_DRIVER_TYPE(E0, TMC26X)
_TMC26X_INIT(E0);
#endif
@ -166,6 +172,9 @@
#if AXIS_DRIVER_TYPE(Z2, TMC2130)
_TMC2130_DEFINE(Z2);
#endif
#if AXIS_DRIVER_TYPE(Z3, TMC2130)
_TMC2130_DEFINE(Z3);
#endif
#if AXIS_DRIVER_TYPE(E0, TMC2130)
_TMC2130_DEFINE(E0);
#endif
@ -233,6 +242,9 @@
#if AXIS_DRIVER_TYPE(Z2, TMC2130)
_TMC2130_INIT(Z2, planner.axis_steps_per_mm[Z_AXIS]);
#endif
#if AXIS_DRIVER_TYPE(Z3, TMC2130)
_TMC2130_INIT(Z3, planner.axis_steps_per_mm[Z_AXIS]);
#endif
#if AXIS_DRIVER_TYPE(E0, TMC2130)
_TMC2130_INIT(E0, planner.axis_steps_per_mm[E_AXIS]);
#endif
@ -274,6 +286,9 @@
#if AXIS_DRIVER_TYPE(Z2, TMC2130)
stepperZ2.sgt(Z_HOMING_SENSITIVITY);
#endif
#if ENABLED(Z3_IS_TMC2130)
stepperZ3.sgt(Z_HOMING_SENSITIVITY);
#endif
#endif
#endif
}
@ -337,6 +352,13 @@
_TMC2208_DEFINE_SOFTWARE(Z2);
#endif
#endif
#if AXIS_DRIVER_TYPE(Z3, TMC2208)
#ifdef Z3_HARDWARE_SERIAL
_TMC2208_DEFINE_HARDWARE(Z3);
#else
_TMC2208_DEFINE_SOFTWARE(Z3);
#endif
#endif
#if AXIS_DRIVER_TYPE(E0, TMC2208)
#ifdef E0_HARDWARE_SERIAL
_TMC2208_DEFINE_HARDWARE(E0);
@ -416,6 +438,13 @@
stepperZ2.beginSerial(115200);
#endif
#endif
#if AXIS_DRIVER_TYPE(Z3, TMC2208)
#ifdef Z3_HARDWARE_SERIAL
Z3_HARDWARE_SERIAL.begin(115200);
#else
stepperZ3.beginSerial(115200);
#endif
#endif
#if AXIS_DRIVER_TYPE(E0, TMC2208)
#ifdef E0_HARDWARE_SERIAL
E0_HARDWARE_SERIAL.begin(115200);
@ -510,6 +539,9 @@
#if AXIS_DRIVER_TYPE(Z2, TMC2208)
_TMC2208_INIT(Z2, planner.axis_steps_per_mm[Z_AXIS]);
#endif
#if AXIS_DRIVER_TYPE(Z3, TMC2208)
_TMC2208_INIT(Z3, planner.axis_steps_per_mm[Z_AXIS]);
#endif
#if AXIS_DRIVER_TYPE(E0, TMC2208)
_TMC2208_INIT(E0, planner.axis_steps_per_mm[E_AXIS]);
#endif
@ -547,6 +579,9 @@ void restore_stepper_drivers() {
#if AXIS_IS_TMC(Z2)
stepperZ2.push();
#endif
#if AXIS_IS_TMC(Z3)
stepperZ3.push();
#endif
#if AXIS_IS_TMC(E0)
stepperE0.push();
#endif
@ -614,6 +649,9 @@ void reset_stepper_drivers() {
#if AXIS_DRIVER_TYPE(Z2, L6470)
_L6470_DEFINE(Z2);
#endif
#if AXIS_DRIVER_TYPE(Z3, L6470)
_L6470_DEFINE(Z3);
#endif
#if AXIS_DRIVER_TYPE(E0, L6470)
_L6470_DEFINE(E0);
#endif
@ -657,6 +695,9 @@ void reset_stepper_drivers() {
#if AXIS_DRIVER_TYPE(Z2, L6470)
_L6470_INIT(Z2);
#endif
#if AXIS_DRIVER_TYPE(Z3, L6470)
_L6470_INIT(Z3);
#endif
#if AXIS_DRIVER_TYPE(E0, L6470)
_L6470_INIT(E0);
#endif

View File

@ -282,6 +282,41 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
#define Z2_STEP_READ READ(Z2_STEP_PIN)
#endif
// Z3 Stepper
#if HAS_Z3_ENABLE
#if ENABLED(Z3_IS_L6470)
extern L6470 stepperZ3;
#define Z3_ENABLE_INIT NOOP
#define Z3_ENABLE_WRITE(STATE) do{ if (STATE) stepperZ3.Step_Clock(stepperZ3.getStatus() & STATUS_HIZ); else stepperZ3.softFree(); }while(0)
#define Z3_ENABLE_READ (stepperZ3.getStatus() & STATUS_HIZ)
#define Z3_DIR_INIT NOOP
#define Z3_DIR_WRITE(STATE) stepperZ3.Step_Clock(STATE)
#define Z3_DIR_READ (stepperZ3.getStatus() & STATUS_DIR)
#else
#if ENABLED(Z3_IS_TMC26X)
extern TMC26XStepper stepperZ3;
#define Z3_ENABLE_INIT NOOP
#define Z3_ENABLE_WRITE(STATE) stepperZ3.setEnabled(STATE)
#define Z3_ENABLE_READ stepperZ3.isEnabled()
#else
#if ENABLED(Z3_IS_TMC2130)
extern TMC2130Stepper stepperZ3;
#elif ENABLED(Z3_IS_TMC2208)
extern TMC2208Stepper stepperZ3;
#endif
#define Z3_ENABLE_INIT SET_OUTPUT(Z3_ENABLE_PIN)
#define Z3_ENABLE_WRITE(STATE) WRITE(Z3_ENABLE_PIN,STATE)
#define Z3_ENABLE_READ READ(Z3_ENABLE_PIN)
#endif
#define Z3_DIR_INIT SET_OUTPUT(Z3_DIR_PIN)
#define Z3_DIR_WRITE(STATE) WRITE(Z3_DIR_PIN,STATE)
#define Z3_DIR_READ READ(Z3_DIR_PIN)
#endif
#define Z3_STEP_INIT SET_OUTPUT(Z3_STEP_PIN)
#define Z3_STEP_WRITE(STATE) WRITE(Z3_STEP_PIN,STATE)
#define Z3_STEP_READ READ(Z3_STEP_PIN)
#endif
// E0 Stepper
#if AXIS_DRIVER_TYPE(E0, L6470)
extern L6470 stepperE0;