@ -237,6 +237,9 @@ void home_delta() {
|
||||
TERN_(I_SENSORLESS, sensorless_t stealth_states_i = start_sensorless_homing_per_axis(I_AXIS));
|
||||
TERN_(J_SENSORLESS, sensorless_t stealth_states_j = start_sensorless_homing_per_axis(J_AXIS));
|
||||
TERN_(K_SENSORLESS, sensorless_t stealth_states_k = start_sensorless_homing_per_axis(K_AXIS));
|
||||
TERN_(U_SENSORLESS, sensorless_t stealth_states_u = start_sensorless_homing_per_axis(U_AXIS));
|
||||
TERN_(V_SENSORLESS, sensorless_t stealth_states_v = start_sensorless_homing_per_axis(V_AXIS));
|
||||
TERN_(W_SENSORLESS, sensorless_t stealth_states_w = start_sensorless_homing_per_axis(W_AXIS));
|
||||
#if SENSORLESS_STALLGUARD_DELAY
|
||||
safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
|
||||
#endif
|
||||
@ -256,6 +259,9 @@ void home_delta() {
|
||||
TERN_(I_SENSORLESS, end_sensorless_homing_per_axis(I_AXIS, stealth_states_i));
|
||||
TERN_(J_SENSORLESS, end_sensorless_homing_per_axis(J_AXIS, stealth_states_j));
|
||||
TERN_(K_SENSORLESS, end_sensorless_homing_per_axis(K_AXIS, stealth_states_k));
|
||||
TERN_(U_SENSORLESS, end_sensorless_homing_per_axis(U_AXIS, stealth_states_u));
|
||||
TERN_(V_SENSORLESS, end_sensorless_homing_per_axis(V_AXIS, stealth_states_v));
|
||||
TERN_(W_SENSORLESS, end_sensorless_homing_per_axis(W_AXIS, stealth_states_w));
|
||||
#if SENSORLESS_STALLGUARD_DELAY
|
||||
safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
|
||||
#endif
|
||||
|
@ -322,6 +322,66 @@ void Endstops::init() {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_U_MIN
|
||||
#if ENABLED(ENDSTOPPULLUP_UMIN)
|
||||
SET_INPUT_PULLUP(U_MIN_PIN);
|
||||
#elif ENABLED(ENDSTOPPULLDOWN_UMIN)
|
||||
SET_INPUT_PULLDOWN(U_MIN_PIN);
|
||||
#else
|
||||
SET_INPUT(U_MIN_PIN);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_U_MAX
|
||||
#if ENABLED(ENDSTOPPULLUP_UMAX)
|
||||
SET_INPUT_PULLUP(U_MAX_PIN);
|
||||
#elif ENABLED(ENDSTOPPULLDOWN_UMIN)
|
||||
SET_INPUT_PULLDOWN(U_MAX_PIN);
|
||||
#else
|
||||
SET_INPUT(U_MAX_PIN);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_V_MIN
|
||||
#if ENABLED(ENDSTOPPULLUP_VMIN)
|
||||
SET_INPUT_PULLUP(V_MIN_PIN);
|
||||
#elif ENABLED(ENDSTOPPULLDOWN_VMIN)
|
||||
SET_INPUT_PULLDOWN(V_MIN_PIN);
|
||||
#else
|
||||
SET_INPUT(V_MIN_PIN);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_V_MAX
|
||||
#if ENABLED(ENDSTOPPULLUP_VMAX)
|
||||
SET_INPUT_PULLUP(V_MAX_PIN);
|
||||
#elif ENABLED(ENDSTOPPULLDOWN_VMIN)
|
||||
SET_INPUT_PULLDOWN(V_MAX_PIN);
|
||||
#else
|
||||
SET_INPUT(V_MAX_PIN);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_W_MIN
|
||||
#if ENABLED(ENDSTOPPULLUP_WMIN)
|
||||
SET_INPUT_PULLUP(W_MIN_PIN);
|
||||
#elif ENABLED(ENDSTOPPULLDOWN_WMIN)
|
||||
SET_INPUT_PULLDOWN(W_MIN_PIN);
|
||||
#else
|
||||
SET_INPUT(W_MIN_PIN);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_W_MAX
|
||||
#if ENABLED(ENDSTOPPULLUP_WMAX)
|
||||
SET_INPUT_PULLUP(W_MAX_PIN);
|
||||
#elif ENABLED(ENDSTOPPULLDOWN_WMIN)
|
||||
SET_INPUT_PULLDOWN(W_MAX_PIN);
|
||||
#else
|
||||
SET_INPUT(W_MAX_PIN);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(CALIBRATION)
|
||||
#if ENABLED(CALIBRATION_PIN_PULLUP)
|
||||
SET_INPUT_PULLUP(CALIBRATION_PIN);
|
||||
@ -427,7 +487,7 @@ void Endstops::event_handler() {
|
||||
prev_hit_state = hit_state;
|
||||
if (hit_state) {
|
||||
#if HAS_STATUS_MESSAGE
|
||||
char LINEAR_AXIS_LIST(chrX = ' ', chrY = ' ', chrZ = ' ', chrI = ' ', chrJ = ' ', chrK = ' '),
|
||||
char NUM_AXIS_LIST(chrX = ' ', chrY = ' ', chrZ = ' ', chrI = ' ', chrJ = ' ', chrK = ' ', chrU = ' ', chrV = ' ', chrW = ' '),
|
||||
chrP = ' ';
|
||||
#define _SET_STOP_CHAR(A,C) (chr## A = C)
|
||||
#else
|
||||
@ -447,16 +507,22 @@ void Endstops::event_handler() {
|
||||
#define ENDSTOP_HIT_TEST_I() _ENDSTOP_HIT_TEST(I,'I')
|
||||
#define ENDSTOP_HIT_TEST_J() _ENDSTOP_HIT_TEST(J,'J')
|
||||
#define ENDSTOP_HIT_TEST_K() _ENDSTOP_HIT_TEST(K,'K')
|
||||
#define ENDSTOP_HIT_TEST_U() _ENDSTOP_HIT_TEST(U,'U')
|
||||
#define ENDSTOP_HIT_TEST_V() _ENDSTOP_HIT_TEST(V,'V')
|
||||
#define ENDSTOP_HIT_TEST_W() _ENDSTOP_HIT_TEST(W,'W')
|
||||
|
||||
SERIAL_ECHO_START();
|
||||
SERIAL_ECHOPGM(STR_ENDSTOPS_HIT);
|
||||
LINEAR_AXIS_CODE(
|
||||
NUM_AXIS_CODE(
|
||||
ENDSTOP_HIT_TEST_X(),
|
||||
ENDSTOP_HIT_TEST_Y(),
|
||||
ENDSTOP_HIT_TEST_Z(),
|
||||
_ENDSTOP_HIT_TEST(I,'I'),
|
||||
_ENDSTOP_HIT_TEST(J,'J'),
|
||||
_ENDSTOP_HIT_TEST(K,'K')
|
||||
_ENDSTOP_HIT_TEST(K,'K'),
|
||||
_ENDSTOP_HIT_TEST(U,'U'),
|
||||
_ENDSTOP_HIT_TEST(V,'V'),
|
||||
_ENDSTOP_HIT_TEST(W,'W')
|
||||
);
|
||||
|
||||
#if USES_Z_MIN_PROBE_PIN
|
||||
@ -467,9 +533,9 @@ void Endstops::event_handler() {
|
||||
|
||||
TERN_(HAS_STATUS_MESSAGE,
|
||||
ui.status_printf(0,
|
||||
F(S_FMT GANG_N_1(LINEAR_AXES, " %c") " %c"),
|
||||
F(S_FMT GANG_N_1(NUM_AXES, " %c") " %c"),
|
||||
GET_TEXT(MSG_LCD_ENDSTOPS),
|
||||
LINEAR_AXIS_LIST(chrX, chrY, chrZ, chrI, chrJ, chrK), chrP
|
||||
NUM_AXIS_LIST(chrX, chrY, chrZ, chrI, chrJ, chrK, chrU, chrV, chrW), chrP
|
||||
)
|
||||
);
|
||||
|
||||
@ -567,6 +633,24 @@ void __O2 Endstops::report_states() {
|
||||
#if HAS_K_MAX
|
||||
ES_REPORT(K_MAX);
|
||||
#endif
|
||||
#if HAS_U_MIN
|
||||
ES_REPORT(U_MIN);
|
||||
#endif
|
||||
#if HAS_U_MAX
|
||||
ES_REPORT(U_MAX);
|
||||
#endif
|
||||
#if HAS_V_MIN
|
||||
ES_REPORT(V_MIN);
|
||||
#endif
|
||||
#if HAS_V_MAX
|
||||
ES_REPORT(V_MAX);
|
||||
#endif
|
||||
#if HAS_W_MIN
|
||||
ES_REPORT(W_MIN);
|
||||
#endif
|
||||
#if HAS_W_MAX
|
||||
ES_REPORT(W_MAX);
|
||||
#endif
|
||||
#if ENABLED(PROBE_ACTIVATION_SWITCH)
|
||||
print_es_state(probe_switch_activated(), F(STR_PROBE_EN));
|
||||
#endif
|
||||
@ -652,6 +736,9 @@ void Endstops::update() {
|
||||
#define I_AXIS_HEAD I_AXIS
|
||||
#define J_AXIS_HEAD J_AXIS
|
||||
#define K_AXIS_HEAD K_AXIS
|
||||
#define U_AXIS_HEAD U_AXIS
|
||||
#define V_AXIS_HEAD V_AXIS
|
||||
#define W_AXIS_HEAD W_AXIS
|
||||
|
||||
/**
|
||||
* Check and update endstops
|
||||
@ -838,6 +925,82 @@ void Endstops::update() {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_U_MIN && !U_SPI_SENSORLESS
|
||||
#if ENABLED(U_DUAL_ENDSTOPS)
|
||||
UPDATE_ENDSTOP_BIT(U, MIN);
|
||||
#if HAS_U2_MIN
|
||||
UPDATE_ENDSTOP_BIT(U2, MIN);
|
||||
#else
|
||||
COPY_LIVE_STATE(U_MIN, U2_MIN);
|
||||
#endif
|
||||
#else
|
||||
UPDATE_ENDSTOP_BIT(U, MIN);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_U_MAX && !U_SPI_SENSORLESS
|
||||
#if ENABLED(U_DUAL_ENDSTOPS)
|
||||
UPDATE_ENDSTOP_BIT(U, MAX);
|
||||
#if HAS_U2_MAX
|
||||
UPDATE_ENDSTOP_BIT(U2, MAX);
|
||||
#else
|
||||
COPY_LIVE_STATE(U_MAX, U2_MAX);
|
||||
#endif
|
||||
#else
|
||||
UPDATE_ENDSTOP_BIT(U, MAX);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_V_MIN && !V_SPI_SENSORLESS
|
||||
#if ENABLED(V_DUAL_ENDSTOPS)
|
||||
UPDATE_ENDSTOP_BIT(V, MIN);
|
||||
#if HAS_V2_MIN
|
||||
UPDATE_ENDSTOP_BIT(V2, MIN);
|
||||
#else
|
||||
COPY_LIVE_STATE(V_MIN, V2_MIN);
|
||||
#endif
|
||||
#else
|
||||
UPDATE_ENDSTOP_BIT(V, MIN);
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_V_MAX && !V_SPI_SENSORLESS
|
||||
#if ENABLED(O_DUAL_ENDSTOPS)
|
||||
UPDATE_ENDSTOP_BIT(V, MAX);
|
||||
#if HAS_V2_MAX
|
||||
UPDATE_ENDSTOP_BIT(V2, MAX);
|
||||
#else
|
||||
COPY_LIVE_STATE(V_MAX, V2_MAX);
|
||||
#endif
|
||||
#else
|
||||
UPDATE_ENDSTOP_BIT(V, MAX);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_W_MIN && !W_SPI_SENSORLESS
|
||||
#if ENABLED(W_DUAL_ENDSTOPS)
|
||||
UPDATE_ENDSTOP_BIT(W, MIN);
|
||||
#if HAS_W2_MIN
|
||||
UPDATE_ENDSTOP_BIT(W2, MIN);
|
||||
#else
|
||||
COPY_LIVE_STATE(W_MIN, W2_MIN);
|
||||
#endif
|
||||
#else
|
||||
UPDATE_ENDSTOP_BIT(W, MIN);
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_W_MAX && !W_SPI_SENSORLESS
|
||||
#if ENABLED(W_DUAL_ENDSTOPS)
|
||||
UPDATE_ENDSTOP_BIT(W, MAX);
|
||||
#if HAS_W2_MAX
|
||||
UPDATE_ENDSTOP_BIT(W2, MAX);
|
||||
#else
|
||||
COPY_LIVE_STATE(W_MAX, W2_MAX);
|
||||
#endif
|
||||
#else
|
||||
UPDATE_ENDSTOP_BIT(W, MAX);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ENDSTOP_NOISE_THRESHOLD
|
||||
|
||||
/**
|
||||
@ -938,7 +1101,7 @@ void Endstops::update() {
|
||||
#define PROCESS_ENDSTOP_Z(MINMAX) PROCESS_DUAL_ENDSTOP(Z, MINMAX)
|
||||
#endif
|
||||
|
||||
#if HAS_G38_PROBE
|
||||
#if HAS_G38_PROBE // TODO (DerAndere): Add support for HAS_I_AXIS
|
||||
#define _G38_OPEN_STATE TERN(G38_PROBE_AWAY, (G38_move >= 4), LOW)
|
||||
// For G38 moves check the probe's pin for ALL movement
|
||||
if (G38_move && TEST_ENDSTOP(_ENDSTOP(Z, TERN(USES_Z_MIN_PROBE_PIN, MIN_PROBE, MIN))) != _G38_OPEN_STATE) {
|
||||
@ -1108,6 +1271,51 @@ void Endstops::update() {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_U_AXIS
|
||||
if (stepper.axis_is_moving(U_AXIS)) {
|
||||
if (stepper.motor_direction(U_AXIS_HEAD)) { // -direction
|
||||
#if HAS_U_MIN || (U_SPI_SENSORLESS && U_HOME_TO_MIN)
|
||||
PROCESS_ENDSTOP(U, MIN);
|
||||
#endif
|
||||
}
|
||||
else { // +direction
|
||||
#if HAS_U_MAX || (U_SPI_SENSORLESS && U_HOME_TO_MAX)
|
||||
PROCESS_ENDSTOP(U, MAX);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_V_AXIS
|
||||
if (stepper.axis_is_moving(V_AXIS)) {
|
||||
if (stepper.motor_direction(V_AXIS_HEAD)) { // -direction
|
||||
#if HAS_V_MIN || (V_SPI_SENSORLESS && V_HOME_TO_MIN)
|
||||
PROCESS_ENDSTOP(V, MIN);
|
||||
#endif
|
||||
}
|
||||
else { // +direction
|
||||
#if HAS_V_MAX || (V_SPI_SENSORLESS && V_HOME_TO_MAX)
|
||||
PROCESS_ENDSTOP(V, MAX);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_W_AXIS
|
||||
if (stepper.axis_is_moving(W_AXIS)) {
|
||||
if (stepper.motor_direction(W_AXIS_HEAD)) { // -direction
|
||||
#if HAS_W_MIN || (W_SPI_SENSORLESS && W_HOME_TO_MIN)
|
||||
PROCESS_ENDSTOP(W, MIN);
|
||||
#endif
|
||||
}
|
||||
else { // +direction
|
||||
#if HAS_W_MAX || (W_SPI_SENSORLESS && W_HOME_TO_MAX)
|
||||
PROCESS_ENDSTOP(W, MAX);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} // Endstops::update()
|
||||
|
||||
#if ENABLED(SPI_ENDSTOPS)
|
||||
@ -1169,6 +1377,24 @@ void Endstops::update() {
|
||||
hit = true;
|
||||
}
|
||||
#endif
|
||||
#if U_SPI_SENSORLESS
|
||||
if (tmc_spi_homing.u && stepperU.test_stall_status()) {
|
||||
SBI(live_state, U_ENDSTOP);
|
||||
hit = true;
|
||||
}
|
||||
#endif
|
||||
#if V_SPI_SENSORLESS
|
||||
if (tmc_spi_homing.v && stepperV.test_stall_status()) {
|
||||
SBI(live_state, V_ENDSTOP);
|
||||
hit = true;
|
||||
}
|
||||
#endif
|
||||
#if W_SPI_SENSORLESS
|
||||
if (tmc_spi_homing.w && stepperW.test_stall_status()) {
|
||||
SBI(live_state, W_ENDSTOP);
|
||||
hit = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (TERN0(ENDSTOP_INTERRUPTS_FEATURE, hit)) update();
|
||||
|
||||
@ -1182,6 +1408,9 @@ void Endstops::update() {
|
||||
TERN_(I_SPI_SENSORLESS, CBI(live_state, I_ENDSTOP));
|
||||
TERN_(J_SPI_SENSORLESS, CBI(live_state, J_ENDSTOP));
|
||||
TERN_(K_SPI_SENSORLESS, CBI(live_state, K_ENDSTOP));
|
||||
TERN_(U_SPI_SENSORLESS, CBI(live_state, U_ENDSTOP));
|
||||
TERN_(V_SPI_SENSORLESS, CBI(live_state, V_ENDSTOP));
|
||||
TERN_(W_SPI_SENSORLESS, CBI(live_state, W_ENDSTOP));
|
||||
}
|
||||
|
||||
#endif // SPI_ENDSTOPS
|
||||
@ -1276,6 +1505,24 @@ void Endstops::update() {
|
||||
#if HAS_K_MIN
|
||||
ES_GET_STATE(K_MIN);
|
||||
#endif
|
||||
#if HAS_U_MAX
|
||||
ES_GET_STATE(U_MAX);
|
||||
#endif
|
||||
#if HAS_U_MIN
|
||||
ES_GET_STATE(U_MIN);
|
||||
#endif
|
||||
#if HAS_V_MAX
|
||||
ES_GET_STATE(V_MAX);
|
||||
#endif
|
||||
#if HAS_V_MIN
|
||||
ES_GET_STATE(V_MIN);
|
||||
#endif
|
||||
#if HAS_W_MAX
|
||||
ES_GET_STATE(W_MAX);
|
||||
#endif
|
||||
#if HAS_W_MIN
|
||||
ES_GET_STATE(W_MIN);
|
||||
#endif
|
||||
|
||||
uint16_t endstop_change = live_state_local ^ old_live_state_local;
|
||||
#define ES_REPORT_CHANGE(S) if (TEST(endstop_change, S)) SERIAL_ECHOPGM(" " STRINGIFY(S) ":", TEST(live_state_local, S))
|
||||
@ -1350,6 +1597,25 @@ void Endstops::update() {
|
||||
#if HAS_K_MAX
|
||||
ES_REPORT_CHANGE(K_MAX);
|
||||
#endif
|
||||
#if HAS_U_MIN
|
||||
ES_REPORT_CHANGE(U_MIN);
|
||||
#endif
|
||||
#if HAS_U_MAX
|
||||
ES_REPORT_CHANGE(U_MAX);
|
||||
#endif
|
||||
#if HAS_V_MIN
|
||||
ES_REPORT_CHANGE(V_MIN);
|
||||
#endif
|
||||
#if HAS_V_MAX
|
||||
ES_REPORT_CHANGE(V_MAX);
|
||||
#endif
|
||||
#if HAS_W_MIN
|
||||
ES_REPORT_CHANGE(W_MIN);
|
||||
#endif
|
||||
#if HAS_W_MAX
|
||||
ES_REPORT_CHANGE(W_MAX);
|
||||
#endif
|
||||
|
||||
SERIAL_ECHOLNPGM("\n");
|
||||
hal.set_pwm_duty(pin_t(LED_PIN), local_LED_status);
|
||||
local_LED_status ^= 255;
|
||||
|
@ -45,6 +45,12 @@ enum EndstopEnum : char {
|
||||
_ES_ITEM(HAS_J_MAX, J_MAX)
|
||||
_ES_ITEM(HAS_K_MIN, K_MIN)
|
||||
_ES_ITEM(HAS_K_MAX, K_MAX)
|
||||
_ES_ITEM(HAS_U_MIN, U_MIN)
|
||||
_ES_ITEM(HAS_U_MAX, U_MAX)
|
||||
_ES_ITEM(HAS_V_MIN, V_MIN)
|
||||
_ES_ITEM(HAS_V_MAX, V_MAX)
|
||||
_ES_ITEM(HAS_W_MIN, W_MIN)
|
||||
_ES_ITEM(HAS_W_MAX, W_MAX)
|
||||
|
||||
// Extra Endstops for XYZ
|
||||
#if ENABLED(X_DUAL_ENDSTOPS)
|
||||
@ -234,7 +240,7 @@ class Endstops {
|
||||
typedef struct {
|
||||
union {
|
||||
bool any;
|
||||
struct { bool LINEAR_AXIS_LIST(x:1, y:1, z:1, i:1, j:1, k:1); };
|
||||
struct { bool NUM_AXIS_LIST(x:1, y:1, z:1, i:1, j:1, k:1); };
|
||||
};
|
||||
} tmc_spi_homing_t;
|
||||
static tmc_spi_homing_t tmc_spi_homing;
|
||||
|
@ -84,7 +84,7 @@ bool relative_mode; // = false;
|
||||
#define Z_INIT_POS Z_HOME_POS
|
||||
#endif
|
||||
|
||||
xyze_pos_t current_position = LOGICAL_AXIS_ARRAY(0, X_HOME_POS, Y_HOME_POS, Z_INIT_POS, I_HOME_POS, J_HOME_POS, K_HOME_POS);
|
||||
xyze_pos_t current_position = LOGICAL_AXIS_ARRAY(0, X_HOME_POS, Y_HOME_POS, Z_INIT_POS, I_HOME_POS, J_HOME_POS, K_HOME_POS, U_HOME_POS, V_HOME_POS, W_HOME_POS);
|
||||
|
||||
/**
|
||||
* Cartesian Destination
|
||||
@ -189,13 +189,16 @@ inline void report_more_positions() {
|
||||
inline void report_logical_position(const xyze_pos_t &rpos) {
|
||||
const xyze_pos_t lpos = rpos.asLogical();
|
||||
SERIAL_ECHOPGM_P(
|
||||
LIST_N(DOUBLE(LINEAR_AXES),
|
||||
LIST_N(DOUBLE(NUM_AXES),
|
||||
X_LBL, lpos.x,
|
||||
SP_Y_LBL, lpos.y,
|
||||
SP_Z_LBL, lpos.z,
|
||||
SP_I_LBL, lpos.i,
|
||||
SP_J_LBL, lpos.j,
|
||||
SP_K_LBL, lpos.k
|
||||
SP_K_LBL, lpos.k,
|
||||
SP_U_LBL, lpos.u,
|
||||
SP_V_LBL, lpos.v,
|
||||
SP_W_LBL, lpos.w
|
||||
)
|
||||
#if HAS_EXTRUDERS
|
||||
, SP_E_LBL, lpos.e
|
||||
@ -210,7 +213,8 @@ void report_real_position() {
|
||||
xyze_pos_t npos = LOGICAL_AXIS_ARRAY(
|
||||
planner.get_axis_position_mm(E_AXIS),
|
||||
cartes.x, cartes.y, cartes.z,
|
||||
cartes.i, cartes.j, cartes.k
|
||||
cartes.i, cartes.j, cartes.k,
|
||||
cartes.u, cartes.v, cartes.w
|
||||
);
|
||||
|
||||
TERN_(HAS_POSITION_MODIFIERS, planner.unapply_modifiers(npos, true));
|
||||
@ -257,13 +261,16 @@ void report_current_position_projected() {
|
||||
const xyz_pos_t lpos = cartes.asLogical();
|
||||
|
||||
SERIAL_ECHOPGM_P(
|
||||
LIST_N(DOUBLE(LINEAR_AXES),
|
||||
LIST_N(DOUBLE(NUM_AXES),
|
||||
X_LBL, lpos.x,
|
||||
SP_Y_LBL, lpos.y,
|
||||
SP_Z_LBL, lpos.z,
|
||||
SP_I_LBL, lpos.i,
|
||||
SP_J_LBL, lpos.j,
|
||||
SP_K_LBL, lpos.k
|
||||
SP_K_LBL, lpos.k,
|
||||
SP_U_LBL, lpos.u,
|
||||
SP_V_LBL, lpos.v,
|
||||
SP_W_LBL, lpos.w
|
||||
)
|
||||
#if HAS_EXTRUDERS
|
||||
, SP_E_LBL, current_position.e
|
||||
@ -354,13 +361,16 @@ void get_cartesian_from_steppers() {
|
||||
);
|
||||
cartes.z = planner.get_axis_position_mm(Z_AXIS);
|
||||
#else
|
||||
LINEAR_AXIS_CODE(
|
||||
NUM_AXIS_CODE(
|
||||
cartes.x = planner.get_axis_position_mm(X_AXIS),
|
||||
cartes.y = planner.get_axis_position_mm(Y_AXIS),
|
||||
cartes.z = planner.get_axis_position_mm(Z_AXIS),
|
||||
cartes.i = planner.get_axis_position_mm(I_AXIS),
|
||||
cartes.j = planner.get_axis_position_mm(J_AXIS),
|
||||
cartes.k = planner.get_axis_position_mm(K_AXIS)
|
||||
cartes.k = planner.get_axis_position_mm(K_AXIS),
|
||||
cartes.u = planner.get_axis_position_mm(U_AXIS),
|
||||
cartes.v = planner.get_axis_position_mm(V_AXIS),
|
||||
cartes.w = planner.get_axis_position_mm(W_AXIS)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
@ -467,24 +477,23 @@ void _internal_move_to_destination(const_feedRate_t fr_mm_s/*=0.0f*/
|
||||
* - Delta may lower Z first to get into the free motion zone.
|
||||
* - Before returning, wait for the planner buffer to empty.
|
||||
*/
|
||||
void do_blocking_move_to(LINEAR_AXIS_ARGS(const float), const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
void do_blocking_move_to(NUM_AXIS_ARGS(const float), const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
DEBUG_SECTION(log_move, "do_blocking_move_to", DEBUGGING(LEVELING));
|
||||
if (DEBUGGING(LEVELING)) DEBUG_XYZ("> ", LINEAR_AXIS_ARGS());
|
||||
if (DEBUGGING(LEVELING)) DEBUG_XYZ("> ", NUM_AXIS_ARGS());
|
||||
|
||||
const feedRate_t xy_feedrate = fr_mm_s ?: feedRate_t(XY_PROBE_FEEDRATE_MM_S);
|
||||
|
||||
#if HAS_Z_AXIS
|
||||
const feedRate_t z_feedrate = fr_mm_s ?: homing_feedrate(Z_AXIS);
|
||||
#endif
|
||||
#if HAS_I_AXIS
|
||||
const feedRate_t i_feedrate = fr_mm_s ?: homing_feedrate(I_AXIS);
|
||||
#endif
|
||||
#if HAS_J_AXIS
|
||||
const feedRate_t j_feedrate = fr_mm_s ?: homing_feedrate(J_AXIS);
|
||||
#endif
|
||||
#if HAS_K_AXIS
|
||||
const feedRate_t k_feedrate = fr_mm_s ?: homing_feedrate(K_AXIS);
|
||||
#endif
|
||||
SECONDARY_AXIS_CODE(
|
||||
const feedRate_t i_feedrate = fr_mm_s ?: homing_feedrate(I_AXIS),
|
||||
const feedRate_t j_feedrate = fr_mm_s ?: homing_feedrate(J_AXIS),
|
||||
const feedRate_t k_feedrate = fr_mm_s ?: homing_feedrate(K_AXIS),
|
||||
const feedRate_t u_feedrate = fr_mm_s ?: homing_feedrate(U_AXIS),
|
||||
const feedRate_t v_feedrate = fr_mm_s ?: homing_feedrate(V_AXIS),
|
||||
const feedRate_t w_feedrate = fr_mm_s ?: homing_feedrate(W_AXIS)
|
||||
);
|
||||
|
||||
#if IS_KINEMATIC
|
||||
if (!position_is_reachable(x, y)) return;
|
||||
@ -553,7 +562,18 @@ void do_blocking_move_to(LINEAR_AXIS_ARGS(const float), const_feedRate_t fr_mm_s
|
||||
#if HAS_K_AXIS
|
||||
current_position.k = k; line_to_current_position(k_feedrate);
|
||||
#endif
|
||||
#if HAS_Z_AXIS // If Z needs to lower, do it after moving XY...
|
||||
#if HAS_U_AXIS
|
||||
current_position.u = u; line_to_current_position(u_feedrate);
|
||||
#endif
|
||||
#if HAS_V_AXIS
|
||||
current_position.v = v; line_to_current_position(v_feedrate);
|
||||
#endif
|
||||
#if HAS_W_AXIS
|
||||
current_position.w = w; line_to_current_position(w_feedrate);
|
||||
#endif
|
||||
|
||||
#if HAS_Z_AXIS
|
||||
// If Z needs to lower, do it after moving XY
|
||||
if (current_position.z > z) { current_position.z = z; line_to_current_position(z_feedrate); }
|
||||
#endif
|
||||
|
||||
@ -563,17 +583,19 @@ void do_blocking_move_to(LINEAR_AXIS_ARGS(const float), const_feedRate_t fr_mm_s
|
||||
}
|
||||
|
||||
void do_blocking_move_to(const xy_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(LINEAR_AXIS_LIST(raw.x, raw.y, current_position.z, current_position.i, current_position.j, current_position.k), fr_mm_s);
|
||||
do_blocking_move_to(NUM_AXIS_LIST(raw.x, raw.y, current_position.z, current_position.i, current_position.j, current_position.k,
|
||||
current_position.u, current_position.v, current_position.w), fr_mm_s);
|
||||
}
|
||||
void do_blocking_move_to(const xyz_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(LINEAR_AXIS_ELEM(raw), fr_mm_s);
|
||||
do_blocking_move_to(NUM_AXIS_ELEM(raw), fr_mm_s);
|
||||
}
|
||||
void do_blocking_move_to(const xyze_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(LINEAR_AXIS_ELEM(raw), fr_mm_s);
|
||||
do_blocking_move_to(NUM_AXIS_ELEM(raw), fr_mm_s);
|
||||
}
|
||||
void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(rx, current_position.y, current_position.z, current_position.i, current_position.j, current_position.k),
|
||||
NUM_AXIS_LIST(rx, current_position.y, current_position.z, current_position.i, current_position.j, current_position.k,
|
||||
current_position.u, current_position.v, current_position.w),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
@ -581,7 +603,8 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
#if HAS_Y_AXIS
|
||||
void do_blocking_move_to_y(const_float_t ry, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(current_position.x, ry, current_position.z, current_position.i, current_position.j, current_position.k),
|
||||
NUM_AXIS_LIST(current_position.x, ry, current_position.z, current_position.i, current_position.j, current_position.k,
|
||||
current_position.u, current_position.v, current_position.w),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
@ -599,7 +622,7 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
}
|
||||
void do_blocking_move_to_xyz_i(const xyze_pos_t &raw, const_float_t i, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(raw.x, raw.y, raw.z, i, raw.j, raw.k),
|
||||
NUM_AXIS_LIST(raw.x, raw.y, raw.z, i, raw.j, raw.k, raw.u, raw.v, raw.w),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
@ -611,7 +634,7 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
}
|
||||
void do_blocking_move_to_xyzi_j(const xyze_pos_t &raw, const_float_t j, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(raw.x, raw.y, raw.z, raw.i, j, raw.k),
|
||||
NUM_AXIS_LIST(raw.x, raw.y, raw.z, raw.i, j, raw.k, raw.u, raw.v, raw.w),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
@ -623,7 +646,43 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
}
|
||||
void do_blocking_move_to_xyzij_k(const xyze_pos_t &raw, const_float_t k, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(raw.x, raw.y, raw.z, raw.i, raw.j, k),
|
||||
NUM_AXIS_LIST(raw.x, raw.y, raw.z, raw.i, raw.j, k, raw.u, raw.v, raw.w),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_U_AXIS
|
||||
void do_blocking_move_to_u(const_float_t ru, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to_xyzijk_u(current_position, ru, fr_mm_s);
|
||||
}
|
||||
void do_blocking_move_to_xyzijk_u(const xyze_pos_t &raw, const_float_t u, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(
|
||||
NUM_AXIS_LIST(raw.x, raw.y, raw.z, raw.i, raw.j, raw.k, u, raw.v, raw.w),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_V_AXIS
|
||||
void do_blocking_move_to_v(const_float_t rv, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to_xyzijku_v(current_position, rv, fr_mm_s);
|
||||
}
|
||||
void do_blocking_move_to_xyzijku_v(const xyze_pos_t &raw, const_float_t v, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(
|
||||
NUM_AXIS_LIST(raw.x, raw.y, raw.z, raw.i, raw.j, raw.k, raw.u, v, raw.w),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_W_AXIS
|
||||
void do_blocking_move_to_w(const_float_t rw, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to_xyzijkuv_w(current_position, rw, fr_mm_s);
|
||||
}
|
||||
void do_blocking_move_to_xyzijkuv_w(const xyze_pos_t &raw, const_float_t w, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(
|
||||
NUM_AXIS_LIST(raw.x, raw.y, raw.z, raw.i, raw.j, raw.k, raw.u, raw.v, w),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
@ -632,7 +691,8 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
#if HAS_Y_AXIS
|
||||
void do_blocking_move_to_xy(const_float_t rx, const_float_t ry, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(rx, ry, current_position.z, current_position.i, current_position.j, current_position.k),
|
||||
NUM_AXIS_LIST(rx, ry, current_position.z, current_position.i, current_position.j, current_position.k,
|
||||
current_position.u, current_position.v, current_position.w),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
@ -644,7 +704,8 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
#if HAS_Z_AXIS
|
||||
void do_blocking_move_to_xy_z(const xy_pos_t &raw, const_float_t z, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(raw.x, raw.y, z, current_position.i, current_position.j, current_position.k),
|
||||
NUM_AXIS_LIST(raw.x, raw.y, z, current_position.i, current_position.j, current_position.k,
|
||||
current_position.u, current_position.v, current_position.w),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
@ -679,8 +740,8 @@ void restore_feedrate_and_scaling() {
|
||||
// Software Endstops are based on the configured limits.
|
||||
soft_endstops_t soft_endstop = {
|
||||
true, false,
|
||||
LINEAR_AXIS_ARRAY(X_MIN_POS, Y_MIN_POS, Z_MIN_POS, I_MIN_POS, J_MIN_POS, K_MIN_POS),
|
||||
LINEAR_AXIS_ARRAY(X_MAX_BED, Y_MAX_BED, Z_MAX_POS, I_MAX_POS, J_MAX_POS, K_MAX_POS)
|
||||
NUM_AXIS_ARRAY(X_MIN_POS, Y_MIN_POS, Z_MIN_POS, I_MIN_POS, J_MIN_POS, K_MIN_POS, U_MIN_POS, V_MIN_POS, W_MIN_POS),
|
||||
NUM_AXIS_ARRAY(X_MAX_BED, Y_MAX_BED, Z_MAX_POS, I_MAX_POS, J_MAX_POS, K_MAX_POS, U_MAX_POS, V_MAX_POS, W_MAX_POS)
|
||||
};
|
||||
|
||||
/**
|
||||
@ -859,6 +920,36 @@ void restore_feedrate_and_scaling() {
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if HAS_U_AXIS
|
||||
if (axis_was_homed(U_AXIS)) {
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_U)
|
||||
NOLESS(target.u, soft_endstop.min.u);
|
||||
#endif
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_U)
|
||||
NOMORE(target.u, soft_endstop.max.u);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if HAS_V_AXIS
|
||||
if (axis_was_homed(V_AXIS)) {
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_V)
|
||||
NOLESS(target.v, soft_endstop.min.v);
|
||||
#endif
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_V)
|
||||
NOMORE(target.v, soft_endstop.max.v);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if HAS_W_AXIS
|
||||
if (axis_was_homed(W_AXIS)) {
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_W)
|
||||
NOLESS(target.w, soft_endstop.min.w);
|
||||
#endif
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_W)
|
||||
NOMORE(target.w, soft_endstop.max.w);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#else // !HAS_SOFTWARE_ENDSTOPS
|
||||
@ -1297,9 +1388,10 @@ void prepare_line_to_destination() {
|
||||
CBI(b, a);
|
||||
};
|
||||
// Clear test bits that are trusted
|
||||
LINEAR_AXIS_CODE(
|
||||
NUM_AXIS_CODE(
|
||||
set_should(axis_bits, X_AXIS), set_should(axis_bits, Y_AXIS), set_should(axis_bits, Z_AXIS),
|
||||
set_should(axis_bits, I_AXIS), set_should(axis_bits, J_AXIS), set_should(axis_bits, K_AXIS)
|
||||
set_should(axis_bits, I_AXIS), set_should(axis_bits, J_AXIS), set_should(axis_bits, K_AXIS),
|
||||
set_should(axis_bits, U_AXIS), set_should(axis_bits, V_AXIS), set_should(axis_bits, W_AXIS)
|
||||
);
|
||||
return axis_bits;
|
||||
}
|
||||
@ -1309,13 +1401,16 @@ void prepare_line_to_destination() {
|
||||
PGM_P home_first = GET_TEXT(MSG_HOME_FIRST);
|
||||
char msg[strlen_P(home_first)+1];
|
||||
sprintf_P(msg, home_first,
|
||||
LINEAR_AXIS_LIST(
|
||||
TEST(axis_bits, X_AXIS) ? "X" : "",
|
||||
TEST(axis_bits, Y_AXIS) ? "Y" : "",
|
||||
TEST(axis_bits, Z_AXIS) ? "Z" : "",
|
||||
NUM_AXIS_LIST(
|
||||
TEST(axis_bits, X_AXIS) ? STR_A : "",
|
||||
TEST(axis_bits, Y_AXIS) ? STR_B : "",
|
||||
TEST(axis_bits, Z_AXIS) ? STR_C : "",
|
||||
TEST(axis_bits, I_AXIS) ? STR_I : "",
|
||||
TEST(axis_bits, J_AXIS) ? STR_J : "",
|
||||
TEST(axis_bits, K_AXIS) ? STR_K : ""
|
||||
TEST(axis_bits, K_AXIS) ? STR_K : "",
|
||||
TEST(axis_bits, U_AXIS) ? STR_U : "",
|
||||
TEST(axis_bits, V_AXIS) ? STR_V : "",
|
||||
TEST(axis_bits, W_AXIS) ? STR_W : ""
|
||||
)
|
||||
);
|
||||
SERIAL_ECHO_START();
|
||||
@ -1395,6 +1490,15 @@ void prepare_line_to_destination() {
|
||||
#if K_SENSORLESS
|
||||
case K_AXIS: stealth_states.k = tmc_enable_stallguard(stepperK); break;
|
||||
#endif
|
||||
#if U_SENSORLESS
|
||||
case U_AXIS: stealth_states.u = tmc_enable_stallguard(stepperU); break;
|
||||
#endif
|
||||
#if V_SENSORLESS
|
||||
case V_AXIS: stealth_states.v = tmc_enable_stallguard(stepperV); break;
|
||||
#endif
|
||||
#if W_SENSORLESS
|
||||
case W_AXIS: stealth_states.w = tmc_enable_stallguard(stepperW); break;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ENABLED(SPI_ENDSTOPS)
|
||||
@ -1415,6 +1519,15 @@ void prepare_line_to_destination() {
|
||||
#if HAS_K_AXIS
|
||||
case K_AXIS: if (ENABLED(K_SPI_SENSORLESS)) endstops.tmc_spi_homing.k = true; break;
|
||||
#endif
|
||||
#if HAS_U_AXIS
|
||||
case U_AXIS: if (ENABLED(U_SPI_SENSORLESS)) endstops.tmc_spi_homing.u = true; break;
|
||||
#endif
|
||||
#if HAS_V_AXIS
|
||||
case V_AXIS: if (ENABLED(V_SPI_SENSORLESS)) endstops.tmc_spi_homing.v = true; break;
|
||||
#endif
|
||||
#if HAS_W_AXIS
|
||||
case W_AXIS: if (ENABLED(W_SPI_SENSORLESS)) endstops.tmc_spi_homing.w = true; break;
|
||||
#endif
|
||||
default: break;
|
||||
}
|
||||
#endif
|
||||
@ -1471,6 +1584,15 @@ void prepare_line_to_destination() {
|
||||
#if K_SENSORLESS
|
||||
case K_AXIS: tmc_disable_stallguard(stepperK, enable_stealth.k); break;
|
||||
#endif
|
||||
#if U_SENSORLESS
|
||||
case U_AXIS: tmc_disable_stallguard(stepperU, enable_stealth.u); break;
|
||||
#endif
|
||||
#if V_SENSORLESS
|
||||
case V_AXIS: tmc_disable_stallguard(stepperV, enable_stealth.v); break;
|
||||
#endif
|
||||
#if W_SENSORLESS
|
||||
case W_AXIS: tmc_disable_stallguard(stepperW, enable_stealth.w); break;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ENABLED(SPI_ENDSTOPS)
|
||||
@ -1491,6 +1613,15 @@ void prepare_line_to_destination() {
|
||||
#if HAS_K_AXIS
|
||||
case K_AXIS: if (ENABLED(K_SPI_SENSORLESS)) endstops.tmc_spi_homing.k = false; break;
|
||||
#endif
|
||||
#if HAS_U_AXIS
|
||||
case U_AXIS: if (ENABLED(U_SPI_SENSORLESS)) endstops.tmc_spi_homing.u = false; break;
|
||||
#endif
|
||||
#if HAS_V_AXIS
|
||||
case V_AXIS: if (ENABLED(V_SPI_SENSORLESS)) endstops.tmc_spi_homing.v = false; break;
|
||||
#endif
|
||||
#if HAS_W_AXIS
|
||||
case W_AXIS: if (ENABLED(W_SPI_SENSORLESS)) endstops.tmc_spi_homing.w = false; break;
|
||||
#endif
|
||||
default: break;
|
||||
}
|
||||
#endif
|
||||
@ -1677,6 +1808,30 @@ void prepare_line_to_destination() {
|
||||
stepperBackoutDir = IF_DISABLED(INVERT_K_DIR, -)effectorBackoutDir;
|
||||
break;
|
||||
#endif
|
||||
#ifdef U_MICROSTEPS
|
||||
case U_AXIS:
|
||||
phasePerUStep = PHASE_PER_MICROSTEP(U);
|
||||
phaseCurrent = stepperU.get_microstep_counter();
|
||||
effectorBackoutDir = -U_HOME_DIR;
|
||||
stepperBackoutDir = IF_DISABLED(INVERT_U_DIR, -)effectorBackoutDir;
|
||||
break;
|
||||
#endif
|
||||
#ifdef V_MICROSTEPS
|
||||
case V_AXIS:
|
||||
phasePerUStep = PHASE_PER_MICROSTEP(V);
|
||||
phaseCurrent = stepperV.get_microstep_counter();
|
||||
effectorBackoutDir = -V_HOME_DIR;
|
||||
stepperBackoutDir = IF_DISABLED(INVERT_V_DIR, -)effectorBackoutDir;
|
||||
break;
|
||||
#endif
|
||||
#ifdef W_MICROSTEPS
|
||||
case W_AXIS:
|
||||
phasePerUStep = PHASE_PER_MICROSTEP(W);
|
||||
phaseCurrent = stepperW.get_microstep_counter();
|
||||
effectorBackoutDir = -W_HOME_DIR;
|
||||
stepperBackoutDir = IF_DISABLED(INVERT_W_DIR, -)effectorBackoutDir;
|
||||
break;
|
||||
#endif
|
||||
default: return;
|
||||
}
|
||||
|
||||
@ -1733,13 +1888,16 @@ void prepare_line_to_destination() {
|
||||
|| TERN0(A##_HOME_TO_MIN, A##_MIN_PIN > -1) \
|
||||
|| TERN0(A##_HOME_TO_MAX, A##_MAX_PIN > -1) \
|
||||
))
|
||||
if (LINEAR_AXIS_GANG(
|
||||
if (NUM_AXIS_GANG(
|
||||
!_CAN_HOME(X),
|
||||
&& !_CAN_HOME(Y),
|
||||
&& !_CAN_HOME(Z),
|
||||
&& !_CAN_HOME(I),
|
||||
&& !_CAN_HOME(J),
|
||||
&& !_CAN_HOME(K))
|
||||
&& !_CAN_HOME(K),
|
||||
&& !_CAN_HOME(U),
|
||||
&& !_CAN_HOME(V),
|
||||
&& !_CAN_HOME(W))
|
||||
) return;
|
||||
#endif
|
||||
|
||||
@ -1832,6 +1990,15 @@ void prepare_line_to_destination() {
|
||||
#if HAS_K_AXIS
|
||||
case K_AXIS: es = K_ENDSTOP; break;
|
||||
#endif
|
||||
#if HAS_U_AXIS
|
||||
case U_AXIS: es = U_ENDSTOP; break;
|
||||
#endif
|
||||
#if HAS_V_AXIS
|
||||
case V_AXIS: es = V_ENDSTOP; break;
|
||||
#endif
|
||||
#if HAS_W_AXIS
|
||||
case W_AXIS: es = W_ENDSTOP; break;
|
||||
#endif
|
||||
}
|
||||
if (TEST(endstops.state(), es)) {
|
||||
SERIAL_ECHO_MSG("Bad ", AS_CHAR(AXIS_CHAR(axis)), " Endstop?");
|
||||
|
@ -44,7 +44,7 @@ extern xyze_pos_t current_position, // High-level current tool position
|
||||
|
||||
// G60/G61 Position Save and Return
|
||||
#if SAVED_POSITIONS
|
||||
extern uint8_t saved_slots[(SAVED_POSITIONS + 7) >> 3]; // TODO: Add support for LINEAR_AXES >= 4
|
||||
extern uint8_t saved_slots[(SAVED_POSITIONS + 7) >> 3]; // TODO: Add support for HAS_I_AXIS
|
||||
extern xyze_pos_t stored_position[SAVED_POSITIONS];
|
||||
#endif
|
||||
|
||||
@ -77,13 +77,16 @@ constexpr xyz_feedrate_t homing_feedrate_mm_m = HOMING_FEEDRATE_MM_M;
|
||||
FORCE_INLINE feedRate_t homing_feedrate(const AxisEnum a) {
|
||||
float v = TERN0(HAS_Z_AXIS, homing_feedrate_mm_m.z);
|
||||
#if DISABLED(DELTA)
|
||||
LINEAR_AXIS_CODE(
|
||||
NUM_AXIS_CODE(
|
||||
if (a == X_AXIS) v = homing_feedrate_mm_m.x,
|
||||
else if (a == Y_AXIS) v = homing_feedrate_mm_m.y,
|
||||
else if (a == Z_AXIS) v = homing_feedrate_mm_m.z,
|
||||
else if (a == I_AXIS) v = homing_feedrate_mm_m.i,
|
||||
else if (a == J_AXIS) v = homing_feedrate_mm_m.j,
|
||||
else if (a == K_AXIS) v = homing_feedrate_mm_m.k
|
||||
else if (a == K_AXIS) v = homing_feedrate_mm_m.k,
|
||||
else if (a == U_AXIS) v = homing_feedrate_mm_m.u,
|
||||
else if (a == V_AXIS) v = homing_feedrate_mm_m.v,
|
||||
else if (a == W_AXIS) v = homing_feedrate_mm_m.w
|
||||
);
|
||||
#endif
|
||||
return MMM_TO_MMS(v);
|
||||
@ -124,7 +127,7 @@ inline int8_t pgm_read_any(const int8_t *p) { return TERN(__IMXRT1062__, *p, pgm
|
||||
|
||||
#define XYZ_DEFS(T, NAME, OPT) \
|
||||
inline T NAME(const AxisEnum axis) { \
|
||||
static const XYZval<T> NAME##_P DEFS_PROGMEM = LINEAR_AXIS_ARRAY(X_##OPT, Y_##OPT, Z_##OPT, I_##OPT, J_##OPT, K_##OPT); \
|
||||
static const XYZval<T> NAME##_P DEFS_PROGMEM = NUM_AXIS_ARRAY(X_##OPT, Y_##OPT, Z_##OPT, I_##OPT, J_##OPT, K_##OPT, U_##OPT, V_##OPT, W_##OPT); \
|
||||
return pgm_read_any(&NAME##_P[axis]); \
|
||||
}
|
||||
XYZ_DEFS(float, base_min_pos, MIN_POS);
|
||||
@ -198,6 +201,24 @@ inline float home_bump_mm(const AxisEnum axis) {
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_K, amax = max.k);
|
||||
break;
|
||||
#endif
|
||||
#if HAS_U_AXIS
|
||||
case U_AXIS:
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_U, amin = min.u);
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_U, amax = max.u);
|
||||
break;
|
||||
#endif
|
||||
#if HAS_V_AXIS
|
||||
case V_AXIS:
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_V, amin = min.v);
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_V, amax = max.v);
|
||||
break;
|
||||
#endif
|
||||
#if HAS_W_AXIS
|
||||
case W_AXIS:
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_W, amin = min.w);
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_W, amax = max.w);
|
||||
break;
|
||||
#endif
|
||||
default: break;
|
||||
}
|
||||
#endif
|
||||
@ -323,7 +344,7 @@ inline void prepare_internal_move_to_destination(const_feedRate_t fr_mm_s=0.0f)
|
||||
/**
|
||||
* Blocking movement and shorthand functions
|
||||
*/
|
||||
void do_blocking_move_to(LINEAR_AXIS_ARGS(const float), const_feedRate_t fr_mm_s=0.0f);
|
||||
void do_blocking_move_to(NUM_AXIS_ARGS(const float), const_feedRate_t fr_mm_s=0.0f);
|
||||
void do_blocking_move_to(const xy_pos_t &raw, const_feedRate_t fr_mm_s=0.0f);
|
||||
void do_blocking_move_to(const xyz_pos_t &raw, const_feedRate_t fr_mm_s=0.0f);
|
||||
void do_blocking_move_to(const xyze_pos_t &raw, const_feedRate_t fr_mm_s=0.0f);
|
||||
@ -347,6 +368,18 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s=0.0f);
|
||||
void do_blocking_move_to_k(const_float_t rk, const_feedRate_t fr_mm_s=0.0f);
|
||||
void do_blocking_move_to_xyzij_k(const xyze_pos_t &raw, const_float_t k, const_feedRate_t fr_mm_s=0.0f);
|
||||
#endif
|
||||
#if HAS_U_AXIS
|
||||
void do_blocking_move_to_u(const_float_t ru, const_feedRate_t fr_mm_s=0.0f);
|
||||
void do_blocking_move_to_xyzijk_u(const xyze_pos_t &raw, const_float_t u, const_feedRate_t fr_mm_s=0.0f);
|
||||
#endif
|
||||
#if HAS_V_AXIS
|
||||
void do_blocking_move_to_v(const_float_t rv, const_feedRate_t fr_mm_s=0.0f);
|
||||
void do_blocking_move_to_xyzijku_v(const xyze_pos_t &raw, const_float_t v, const_feedRate_t fr_mm_s=0.0f);
|
||||
#endif
|
||||
#if HAS_W_AXIS
|
||||
void do_blocking_move_to_w(const float rw, const feedRate_t &fr_mm_s=0.0f);
|
||||
void do_blocking_move_to_xyzijkuv_w(const xyze_pos_t &raw, const float w, const feedRate_t &fr_mm_s=0.0f);
|
||||
#endif
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
void do_blocking_move_to_xy(const_float_t rx, const_float_t ry, const_feedRate_t fr_mm_s=0.0f);
|
||||
@ -374,8 +407,8 @@ void restore_feedrate_and_scaling();
|
||||
/**
|
||||
* Homing and Trusted Axes
|
||||
*/
|
||||
typedef IF<(LINEAR_AXES > 8), uint16_t, uint8_t>::type linear_axis_bits_t;
|
||||
constexpr linear_axis_bits_t linear_bits = _BV(LINEAR_AXES) - 1;
|
||||
typedef IF<(NUM_AXES > 8), uint16_t, uint8_t>::type linear_axis_bits_t;
|
||||
constexpr linear_axis_bits_t linear_bits = _BV(NUM_AXES) - 1;
|
||||
|
||||
void set_axis_is_at_home(const AxisEnum axis);
|
||||
|
||||
@ -490,6 +523,18 @@ void home_if_needed(const bool keeplev=false);
|
||||
#define LOGICAL_K_POSITION(POS) NATIVE_TO_LOGICAL(POS, K_AXIS)
|
||||
#define RAW_K_POSITION(POS) LOGICAL_TO_NATIVE(POS, K_AXIS)
|
||||
#endif
|
||||
#if HAS_U_AXIS
|
||||
#define LOGICAL_U_POSITION(POS) NATIVE_TO_LOGICAL(POS, U_AXIS)
|
||||
#define RAW_U_POSITION(POS) LOGICAL_TO_NATIVE(POS, U_AXIS)
|
||||
#endif
|
||||
#if HAS_V_AXIS
|
||||
#define LOGICAL_V_POSITION(POS) NATIVE_TO_LOGICAL(POS, V_AXIS)
|
||||
#define RAW_V_POSITION(POS) LOGICAL_TO_NATIVE(POS, V_AXIS)
|
||||
#endif
|
||||
#if HAS_W_AXIS
|
||||
#define LOGICAL_W_POSITION(POS) NATIVE_TO_LOGICAL(POS, W_AXIS)
|
||||
#define RAW_W_POSITION(POS) LOGICAL_TO_NATIVE(POS, W_AXIS)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* position_is_reachable family of functions
|
||||
|
@ -1300,7 +1300,7 @@ void Planner::recalculate() {
|
||||
*/
|
||||
void Planner::check_axes_activity() {
|
||||
|
||||
#if ANY(DISABLE_X, DISABLE_Y, DISABLE_Z, DISABLE_I, DISABLE_J, DISABLE_K, DISABLE_E)
|
||||
#if ANY(DISABLE_X, DISABLE_Y, DISABLE_Z, DISABLE_I, DISABLE_J, DISABLE_K, DISABLE_U, DISABLE_V, DISABLE_W, DISABLE_E)
|
||||
xyze_bool_t axis_active = { false };
|
||||
#endif
|
||||
|
||||
@ -1350,7 +1350,10 @@ void Planner::check_axes_activity() {
|
||||
if (TERN0(DISABLE_Z, bnext->steps.z)) axis_active.z = true,
|
||||
if (TERN0(DISABLE_I, bnext->steps.i)) axis_active.i = true,
|
||||
if (TERN0(DISABLE_J, bnext->steps.j)) axis_active.j = true,
|
||||
if (TERN0(DISABLE_K, bnext->steps.k)) axis_active.k = true
|
||||
if (TERN0(DISABLE_K, bnext->steps.k)) axis_active.k = true,
|
||||
if (TERN0(DISABLE_U, bnext->steps.u)) axis_active.u = true,
|
||||
if (TERN0(DISABLE_V, bnext->steps.v)) axis_active.v = true,
|
||||
if (TERN0(DISABLE_W, bnext->steps.w)) axis_active.w = true
|
||||
);
|
||||
}
|
||||
#endif
|
||||
@ -1385,7 +1388,10 @@ void Planner::check_axes_activity() {
|
||||
if (TERN0(DISABLE_Z, !axis_active.z)) stepper.disable_axis(Z_AXIS),
|
||||
if (TERN0(DISABLE_I, !axis_active.i)) stepper.disable_axis(I_AXIS),
|
||||
if (TERN0(DISABLE_J, !axis_active.j)) stepper.disable_axis(J_AXIS),
|
||||
if (TERN0(DISABLE_K, !axis_active.k)) stepper.disable_axis(K_AXIS)
|
||||
if (TERN0(DISABLE_K, !axis_active.k)) stepper.disable_axis(K_AXIS),
|
||||
if (TERN0(DISABLE_U, !axis_active.u)) stepper.disable_axis(U_AXIS),
|
||||
if (TERN0(DISABLE_V, !axis_active.v)) stepper.disable_axis(V_AXIS),
|
||||
if (TERN0(DISABLE_W, !axis_active.w)) stepper.disable_axis(W_AXIS)
|
||||
);
|
||||
|
||||
//
|
||||
@ -1453,7 +1459,7 @@ void Planner::check_axes_activity() {
|
||||
float high = 0.0f;
|
||||
for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) {
|
||||
const block_t * const block = &block_buffer[b];
|
||||
if (LINEAR_AXIS_GANG(block->steps.x, || block->steps.y, || block->steps.z, || block->steps.i, || block->steps.j, || block->steps.k)) {
|
||||
if (NUM_AXIS_GANG(block->steps.x, || block->steps.y, || block->steps.z, || block->steps.i, || block->steps.j, || block->steps.k, || block->steps.u, || block->steps.v, || block->steps.w)) {
|
||||
const float se = (float)block->steps.e / block->step_event_count * SQRT(block->nominal_speed_sqr); // mm/sec;
|
||||
NOLESS(high, se);
|
||||
}
|
||||
@ -1843,15 +1849,22 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
dc = target.c - position.c,
|
||||
di = target.i - position.i,
|
||||
dj = target.j - position.j,
|
||||
dk = target.k - position.k
|
||||
dk = target.k - position.k,
|
||||
du = target.u - position.u,
|
||||
dv = target.v - position.v,
|
||||
dw = target.w - position.w
|
||||
);
|
||||
|
||||
/* <-- add a slash to enable
|
||||
SERIAL_ECHOLNPGM(
|
||||
" _populate_block FR:", fr_mm_s,
|
||||
" A:", target.a, " (", da, " steps)"
|
||||
" B:", target.b, " (", db, " steps)"
|
||||
" C:", target.c, " (", dc, " steps)"
|
||||
#if HAS_Y_AXIS
|
||||
" B:", target.b, " (", db, " steps)"
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
" C:", target.c, " (", dc, " steps)"
|
||||
#endif
|
||||
#if HAS_I_AXIS
|
||||
" " STR_I ":", target.i, " (", di, " steps)"
|
||||
#endif
|
||||
@ -1861,6 +1874,14 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
#if HAS_K_AXIS
|
||||
" " STR_K ":", target.k, " (", dk, " steps)"
|
||||
#endif
|
||||
#if HAS_U_AXIS
|
||||
" " STR_U ":", target.u, " (", du, " steps)"
|
||||
#endif
|
||||
#if HAS_V_AXIS
|
||||
" " STR_V ":", target.v, " (", dv, " steps)"
|
||||
#endif
|
||||
#if HAS_W_AXIS
|
||||
" " STR_W ":", target.w, " (", dw, " steps)"
|
||||
#if HAS_EXTRUDERS
|
||||
" E:", target.e, " (", de, " steps)"
|
||||
#endif
|
||||
@ -1925,15 +1946,6 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
if (db + dc < 0) SBI(dm, B_AXIS); // Motor B direction
|
||||
if (CORESIGN(db - dc) < 0) SBI(dm, C_AXIS); // Motor C direction
|
||||
#endif
|
||||
#if HAS_I_AXIS
|
||||
if (di < 0) SBI(dm, I_AXIS);
|
||||
#endif
|
||||
#if HAS_J_AXIS
|
||||
if (dj < 0) SBI(dm, J_AXIS);
|
||||
#endif
|
||||
#if HAS_K_AXIS
|
||||
if (dk < 0) SBI(dm, K_AXIS);
|
||||
#endif
|
||||
#elif ENABLED(MARKFORGED_XY)
|
||||
if (da + db < 0) SBI(dm, A_AXIS); // Motor A direction
|
||||
if (db < 0) SBI(dm, B_AXIS); // Motor B direction
|
||||
@ -1941,16 +1953,22 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
if (da < 0) SBI(dm, A_AXIS); // Motor A direction
|
||||
if (db + da < 0) SBI(dm, B_AXIS); // Motor B direction
|
||||
#else
|
||||
LINEAR_AXIS_CODE(
|
||||
XYZ_CODE(
|
||||
if (da < 0) SBI(dm, X_AXIS),
|
||||
if (db < 0) SBI(dm, Y_AXIS),
|
||||
if (dc < 0) SBI(dm, Z_AXIS),
|
||||
if (di < 0) SBI(dm, I_AXIS),
|
||||
if (dj < 0) SBI(dm, J_AXIS),
|
||||
if (dk < 0) SBI(dm, K_AXIS)
|
||||
if (dc < 0) SBI(dm, Z_AXIS)
|
||||
);
|
||||
#endif
|
||||
|
||||
SECONDARY_AXIS_CODE(
|
||||
if (di < 0) SBI(dm, I_AXIS),
|
||||
if (dj < 0) SBI(dm, J_AXIS),
|
||||
if (dk < 0) SBI(dm, K_AXIS),
|
||||
if (du < 0) SBI(dm, U_AXIS),
|
||||
if (dv < 0) SBI(dm, V_AXIS),
|
||||
if (dw < 0) SBI(dm, W_AXIS)
|
||||
);
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
if (de < 0) SBI(dm, E_AXIS);
|
||||
const float esteps_float = de * e_factor[extruder];
|
||||
@ -1974,22 +1992,24 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
|
||||
// Number of steps for each axis
|
||||
// See https://www.corexy.com/theory.html
|
||||
#if CORE_IS_XY
|
||||
block->steps.set(LINEAR_AXIS_LIST(ABS(da + db), ABS(da - db), ABS(dc), ABS(di), ABS(dj), ABS(dk)));
|
||||
#elif CORE_IS_XZ
|
||||
block->steps.set(LINEAR_AXIS_LIST(ABS(da + dc), ABS(db), ABS(da - dc), ABS(di), ABS(dj), ABS(dk)));
|
||||
#elif CORE_IS_YZ
|
||||
block->steps.set(LINEAR_AXIS_LIST(ABS(da), ABS(db + dc), ABS(db - dc), ABS(di), ABS(dj), ABS(dk)));
|
||||
#elif ENABLED(MARKFORGED_XY)
|
||||
block->steps.set(LINEAR_AXIS_LIST(ABS(da + db), ABS(db), ABS(dc), ABS(di), ABS(dj), ABS(dk)));
|
||||
#elif ENABLED(MARKFORGED_YX)
|
||||
block->steps.set(LINEAR_AXIS_LIST(ABS(da), ABS(db + da), ABS(dc), ABS(di), ABS(dj), ABS(dk)));
|
||||
#elif IS_SCARA
|
||||
block->steps.set(LINEAR_AXIS_LIST(ABS(da), ABS(db), ABS(dc), ABS(di), ABS(dj), ABS(dk)));
|
||||
#else
|
||||
// default non-h-bot planning
|
||||
block->steps.set(LINEAR_AXIS_LIST(ABS(da), ABS(db), ABS(dc), ABS(di), ABS(dj), ABS(dk)));
|
||||
#endif
|
||||
block->steps.set(NUM_AXIS_LIST(
|
||||
#if CORE_IS_XY
|
||||
ABS(da + db), ABS(da - db), ABS(dc)
|
||||
#elif CORE_IS_XZ
|
||||
ABS(da + dc), ABS(db), ABS(da - dc)
|
||||
#elif CORE_IS_YZ
|
||||
ABS(da), ABS(db + dc), ABS(db - dc)
|
||||
#elif ENABLED(MARKFORGED_XY)
|
||||
ABS(da + db), ABS(db), ABS(dc)
|
||||
#elif ENABLED(MARKFORGED_YX)
|
||||
ABS(da), ABS(db + da), ABS(dc)
|
||||
#elif IS_SCARA
|
||||
ABS(da), ABS(db), ABS(dc)
|
||||
#else // default non-h-bot planning
|
||||
ABS(da), ABS(db), ABS(dc)
|
||||
#endif
|
||||
, ABS(di), ABS(dj), ABS(dk), ABS(du), ABS(dv), ABS(dw)
|
||||
));
|
||||
|
||||
/**
|
||||
* This part of the code calculates the total length of the movement.
|
||||
@ -2027,9 +2047,6 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
steps_dist_mm.b = (db + dc) * mm_per_step[B_AXIS];
|
||||
steps_dist_mm.c = CORESIGN(db - dc) * mm_per_step[C_AXIS];
|
||||
#endif
|
||||
TERN_(HAS_I_AXIS, steps_dist_mm.i = di * mm_per_step[I_AXIS]);
|
||||
TERN_(HAS_J_AXIS, steps_dist_mm.j = dj * mm_per_step[J_AXIS]);
|
||||
TERN_(HAS_K_AXIS, steps_dist_mm.k = dk * mm_per_step[K_AXIS]);
|
||||
#elif ENABLED(MARKFORGED_XY)
|
||||
steps_dist_mm.a = (da - db) * mm_per_step[A_AXIS];
|
||||
steps_dist_mm.b = db * mm_per_step[B_AXIS];
|
||||
@ -2037,27 +2054,40 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
steps_dist_mm.a = da * mm_per_step[A_AXIS];
|
||||
steps_dist_mm.b = (db - da) * mm_per_step[B_AXIS];
|
||||
#else
|
||||
LINEAR_AXIS_CODE(
|
||||
XYZ_CODE(
|
||||
steps_dist_mm.a = da * mm_per_step[A_AXIS],
|
||||
steps_dist_mm.b = db * mm_per_step[B_AXIS],
|
||||
steps_dist_mm.c = dc * mm_per_step[C_AXIS],
|
||||
steps_dist_mm.i = di * mm_per_step[I_AXIS],
|
||||
steps_dist_mm.j = dj * mm_per_step[J_AXIS],
|
||||
steps_dist_mm.k = dk * mm_per_step[K_AXIS]
|
||||
steps_dist_mm.c = dc * mm_per_step[C_AXIS]
|
||||
);
|
||||
#endif
|
||||
|
||||
SECONDARY_AXIS_CODE(
|
||||
steps_dist_mm.i = di * mm_per_step[I_AXIS],
|
||||
steps_dist_mm.j = dj * mm_per_step[J_AXIS],
|
||||
steps_dist_mm.k = dk * mm_per_step[K_AXIS],
|
||||
steps_dist_mm.u = du * mm_per_step[U_AXIS],
|
||||
steps_dist_mm.v = dv * mm_per_step[V_AXIS],
|
||||
steps_dist_mm.w = dw * mm_per_step[W_AXIS]
|
||||
);
|
||||
|
||||
TERN_(HAS_EXTRUDERS, steps_dist_mm.e = esteps_float * mm_per_step[E_AXIS_N(extruder)]);
|
||||
|
||||
TERN_(LCD_SHOW_E_TOTAL, e_move_accumulator += steps_dist_mm.e);
|
||||
|
||||
if (true LINEAR_AXIS_GANG(
|
||||
#if BOTH(HAS_ROTATIONAL_AXES, INCH_MODE_SUPPORT)
|
||||
bool cartesian_move = true;
|
||||
#endif
|
||||
|
||||
if (true NUM_AXIS_GANG(
|
||||
&& block->steps.a < MIN_STEPS_PER_SEGMENT,
|
||||
&& block->steps.b < MIN_STEPS_PER_SEGMENT,
|
||||
&& block->steps.c < MIN_STEPS_PER_SEGMENT,
|
||||
&& block->steps.i < MIN_STEPS_PER_SEGMENT,
|
||||
&& block->steps.j < MIN_STEPS_PER_SEGMENT,
|
||||
&& block->steps.k < MIN_STEPS_PER_SEGMENT
|
||||
&& block->steps.k < MIN_STEPS_PER_SEGMENT,
|
||||
&& block->steps.u < MIN_STEPS_PER_SEGMENT,
|
||||
&& block->steps.v < MIN_STEPS_PER_SEGMENT,
|
||||
&& block->steps.w < MIN_STEPS_PER_SEGMENT
|
||||
)
|
||||
) {
|
||||
block->millimeters = TERN0(HAS_EXTRUDERS, ABS(steps_dist_mm.e));
|
||||
@ -2066,36 +2096,71 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
if (millimeters)
|
||||
block->millimeters = millimeters;
|
||||
else {
|
||||
block->millimeters = SQRT(
|
||||
#if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX)
|
||||
LINEAR_AXIS_GANG(
|
||||
sq(steps_dist_mm.head.x), + sq(steps_dist_mm.head.y), + sq(steps_dist_mm.z),
|
||||
+ sq(steps_dist_mm.i), + sq(steps_dist_mm.j), + sq(steps_dist_mm.k)
|
||||
)
|
||||
#elif CORE_IS_XZ
|
||||
LINEAR_AXIS_GANG(
|
||||
sq(steps_dist_mm.head.x), + sq(steps_dist_mm.y), + sq(steps_dist_mm.head.z),
|
||||
+ sq(steps_dist_mm.i), + sq(steps_dist_mm.j), + sq(steps_dist_mm.k)
|
||||
)
|
||||
#elif CORE_IS_YZ
|
||||
LINEAR_AXIS_GANG(
|
||||
sq(steps_dist_mm.x) + sq(steps_dist_mm.head.y) + sq(steps_dist_mm.head.z)
|
||||
+ sq(steps_dist_mm.i), + sq(steps_dist_mm.j), + sq(steps_dist_mm.k)
|
||||
)
|
||||
/**
|
||||
* Distance for interpretation of feedrate in accordance with LinuxCNC (the successor of NIST
|
||||
* RS274NGC interpreter - version 3) and its default CANON_XYZ feed reference mode.
|
||||
* Assume that X, Y, Z are the primary linear axes and U, V, W are secondary linear axes and A, B, C are
|
||||
* rotational axes. Then dX, dY, dZ are the displacements of the primary linear axes and dU, dV, dW are the displacements of linear axes and
|
||||
* dA, dB, dC are the displacements of rotational axes.
|
||||
* The time it takes to execute move command with feedrate F is t = D/F, where D is the total distance, calculated as follows:
|
||||
* D^2 = dX^2 + dY^2 + dZ^2
|
||||
* if D^2 == 0 (none of XYZ move but any secondary linear axes move, whether other axes are moved or not):
|
||||
* D^2 = dU^2 + dV^2 + dW^2
|
||||
* if D^2 == 0 (only rotational axes are moved):
|
||||
* D^2 = dA^2 + dB^2 + dC^2
|
||||
*/
|
||||
float distance_sqr = (
|
||||
#if ENABLED(ARTICULATED_ROBOT_ARM)
|
||||
// For articulated robots, interpreting feedrate like LinuxCNC would require inverse kinematics. As a workaround, pretend that motors sit on n mutually orthogonal
|
||||
// axes and assume that we could think of distance as magnitude of an n-vector in an n-dimensional Euclidian space.
|
||||
NUM_AXIS_GANG(
|
||||
sq(steps_dist_mm.x), + sq(steps_dist_mm.y), + sq(steps_dist_mm.z),
|
||||
+ sq(steps_dist_mm.i), + sq(steps_dist_mm.j), + sq(steps_dist_mm.k),
|
||||
+ sq(steps_dist_mm.u), + sq(steps_dist_mm.v), + sq(steps_dist_mm.w)
|
||||
);
|
||||
#elif ENABLED(FOAMCUTTER_XYUV)
|
||||
// Return the largest distance move from either X/Y or I/J plane
|
||||
#if HAS_J_AXIS
|
||||
_MAX(sq(steps_dist_mm.x) + sq(steps_dist_mm.y), sq(steps_dist_mm.i) + sq(steps_dist_mm.j))
|
||||
#else
|
||||
// Special 5 axis kinematics. Return the largest distance move from either X/Y or I/J plane
|
||||
_MAX(sq(steps_dist_mm.x) + sq(steps_dist_mm.y), sq(steps_dist_mm.i) + sq(steps_dist_mm.j))
|
||||
#else // Foamcutter with only two axes (XY)
|
||||
sq(steps_dist_mm.x) + sq(steps_dist_mm.y)
|
||||
#endif
|
||||
#elif ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX)
|
||||
XYZ_GANG(sq(steps_dist_mm.head.x), + sq(steps_dist_mm.head.y), + sq(steps_dist_mm.z))
|
||||
#elif CORE_IS_XZ
|
||||
XYZ_GANG(sq(steps_dist_mm.head.x), + sq(steps_dist_mm.y), + sq(steps_dist_mm.head.z))
|
||||
#elif CORE_IS_YZ
|
||||
XYZ_GANG(sq(steps_dist_mm.x), + sq(steps_dist_mm.head.y), + sq(steps_dist_mm.head.z))
|
||||
#else
|
||||
LINEAR_AXIS_GANG(
|
||||
sq(steps_dist_mm.x), + sq(steps_dist_mm.y), + sq(steps_dist_mm.z),
|
||||
+ sq(steps_dist_mm.i), + sq(steps_dist_mm.j), + sq(steps_dist_mm.k)
|
||||
)
|
||||
XYZ_GANG(sq(steps_dist_mm.x), + sq(steps_dist_mm.y), + sq(steps_dist_mm.z))
|
||||
#endif
|
||||
);
|
||||
|
||||
#if SECONDARY_LINEAR_AXES >= 1 && NONE(FOAMCUTTER_XYUV, ARTICULATED_ROBOT_ARM)
|
||||
if (NEAR_ZERO(distance_sqr)) {
|
||||
// Move does not involve any primary linear axes (xyz) but might involve secondary linear axes
|
||||
distance_sqr = (0.0
|
||||
SECONDARY_AXIS_GANG(
|
||||
IF_DISABLED(AXIS4_ROTATES, + sq(steps_dist_mm.i)),
|
||||
IF_DISABLED(AXIS5_ROTATES, + sq(steps_dist_mm.j)),
|
||||
IF_DISABLED(AXIS6_ROTATES, + sq(steps_dist_mm.k)),
|
||||
IF_DISABLED(AXIS7_ROTATES, + sq(steps_dist_mm.u)),
|
||||
IF_DISABLED(AXIS8_ROTATES, + sq(steps_dist_mm.v)),
|
||||
IF_DISABLED(AXIS9_ROTATES, + sq(steps_dist_mm.w))
|
||||
)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_ROTATIONAL_AXES && NONE(FOAMCUTTER_XYUV, ARTICULATED_ROBOT_ARM)
|
||||
if (NEAR_ZERO(distance_sqr)) {
|
||||
// Move involves only rotational axes. Calculate angular distance in accordance with LinuxCNC
|
||||
TERN_(INCH_MODE_SUPPORT, cartesian_move = false);
|
||||
distance_sqr = ROTATIONAL_AXIS_GANG(sq(steps_dist_mm.i), + sq(steps_dist_mm.j), + sq(steps_dist_mm.k), + sq(steps_dist_mm.u), + sq(steps_dist_mm.v), + sq(steps_dist_mm.w));
|
||||
}
|
||||
#endif
|
||||
|
||||
block->millimeters = SQRT(distance_sqr);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2112,8 +2177,10 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
|
||||
TERN_(HAS_EXTRUDERS, block->steps.e = esteps);
|
||||
|
||||
block->step_event_count = _MAX(LOGICAL_AXIS_LIST(
|
||||
esteps, block->steps.a, block->steps.b, block->steps.c, block->steps.i, block->steps.j, block->steps.k
|
||||
block->step_event_count = _MAX(LOGICAL_AXIS_LIST(esteps,
|
||||
block->steps.a, block->steps.b, block->steps.c,
|
||||
block->steps.i, block->steps.j, block->steps.k,
|
||||
block->steps.u, block->steps.v, block->steps.w
|
||||
));
|
||||
|
||||
// Bail if this is a zero-length block
|
||||
@ -2135,13 +2202,16 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
E_TERN_(block->extruder = extruder);
|
||||
|
||||
#if ENABLED(AUTO_POWER_CONTROL)
|
||||
if (LINEAR_AXIS_GANG(
|
||||
if (NUM_AXIS_GANG(
|
||||
block->steps.x,
|
||||
|| block->steps.y,
|
||||
|| block->steps.z,
|
||||
|| block->steps.i,
|
||||
|| block->steps.j,
|
||||
|| block->steps.k
|
||||
|| block->steps.k,
|
||||
|| block->steps.u,
|
||||
|| block->steps.v,
|
||||
|| block->steps.w
|
||||
)) powerManager.power_on();
|
||||
#endif
|
||||
|
||||
@ -2167,19 +2237,27 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
}
|
||||
if (block->steps.x) stepper.enable_axis(X_AXIS);
|
||||
#else
|
||||
LINEAR_AXIS_CODE(
|
||||
NUM_AXIS_CODE(
|
||||
if (block->steps.x) stepper.enable_axis(X_AXIS),
|
||||
if (block->steps.y) stepper.enable_axis(Y_AXIS),
|
||||
if (TERN(Z_LATE_ENABLE, 0, block->steps.z)) stepper.enable_axis(Z_AXIS),
|
||||
if (block->steps.i) stepper.enable_axis(I_AXIS),
|
||||
if (block->steps.j) stepper.enable_axis(J_AXIS),
|
||||
if (block->steps.k) stepper.enable_axis(K_AXIS)
|
||||
if (block->steps.k) stepper.enable_axis(K_AXIS),
|
||||
if (block->steps.u) stepper.enable_axis(U_AXIS),
|
||||
if (block->steps.v) stepper.enable_axis(V_AXIS),
|
||||
if (block->steps.w) stepper.enable_axis(W_AXIS)
|
||||
);
|
||||
#endif
|
||||
#if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX)
|
||||
TERN_(HAS_I_AXIS, if (block->steps.i) stepper.enable_axis(I_AXIS));
|
||||
TERN_(HAS_J_AXIS, if (block->steps.j) stepper.enable_axis(J_AXIS));
|
||||
TERN_(HAS_K_AXIS, if (block->steps.k) stepper.enable_axis(K_AXIS));
|
||||
SECONDARY_AXIS_CODE(
|
||||
if (block->steps.i) stepper.enable_axis(I_AXIS),
|
||||
if (block->steps.j) stepper.enable_axis(J_AXIS),
|
||||
if (block->steps.k) stepper.enable_axis(K_AXIS),
|
||||
if (block->steps.u) stepper.enable_axis(U_AXIS),
|
||||
if (block->steps.v) stepper.enable_axis(V_AXIS),
|
||||
if (block->steps.w) stepper.enable_axis(W_AXIS)
|
||||
);
|
||||
#endif
|
||||
|
||||
// Enable extruder(s)
|
||||
@ -2226,8 +2304,14 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
const float inverse_millimeters = 1.0f / block->millimeters; // Inverse millimeters to remove multiple divides
|
||||
|
||||
// Calculate inverse time for this move. No divide by zero due to previous checks.
|
||||
// Example: At 120mm/s a 60mm move takes 0.5s. So this will give 2.0.
|
||||
float inverse_secs = fr_mm_s * inverse_millimeters;
|
||||
// Example: At 120mm/s a 60mm move involving XYZ axes takes 0.5s. So this will give 2.0.
|
||||
// Example 2: At 120°/s a 60° move involving only rotational axes takes 0.5s. So this will give 2.0.
|
||||
float inverse_secs;
|
||||
#if BOTH(HAS_ROTATIONAL_AXES, INCH_MODE_SUPPORT)
|
||||
inverse_secs = inverse_millimeters * (cartesian_move ? fr_mm_s : LINEAR_UNIT(fr_mm_s));
|
||||
#else
|
||||
inverse_secs = fr_mm_s * inverse_millimeters;
|
||||
#endif
|
||||
|
||||
// Get the number of non busy movements in queue (non busy means that they can be altered)
|
||||
const uint8_t moves_queued = nonbusy_movesplanned();
|
||||
@ -2273,13 +2357,13 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
filwidth.advance_e(steps_dist_mm.e);
|
||||
#endif
|
||||
|
||||
// Calculate and limit speed in mm/sec
|
||||
// Calculate and limit speed in mm/sec (linear) or degrees/sec (rotational)
|
||||
|
||||
xyze_float_t current_speed;
|
||||
float speed_factor = 1.0f; // factor <1 decreases speed
|
||||
|
||||
// Linear axes first with less logic
|
||||
LOOP_LINEAR_AXES(i) {
|
||||
LOOP_NUM_AXES(i) {
|
||||
current_speed[i] = steps_dist_mm[i] * inverse_secs;
|
||||
const feedRate_t cs = ABS(current_speed[i]),
|
||||
max_fr = settings.max_feedrate_mm_s[i];
|
||||
@ -2367,9 +2451,10 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
// Compute and limit the acceleration rate for the trapezoid generator.
|
||||
const float steps_per_mm = block->step_event_count * inverse_millimeters;
|
||||
uint32_t accel;
|
||||
if (LINEAR_AXIS_GANG(
|
||||
if (NUM_AXIS_GANG(
|
||||
!block->steps.a, && !block->steps.b, && !block->steps.c,
|
||||
&& !block->steps.i, && !block->steps.j, && !block->steps.k)
|
||||
&& !block->steps.i, && !block->steps.j, && !block->steps.k,
|
||||
&& !block->steps.u, && !block->steps.v, && !block->steps.w)
|
||||
) { // Is this a retract / recover move?
|
||||
accel = CEIL(settings.retract_acceleration * steps_per_mm); // Convert to: acceleration steps/sec^2
|
||||
TERN_(LIN_ADVANCE, block->use_advance_lead = false); // No linear advance for simple retract/recover
|
||||
@ -2442,7 +2527,10 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
LIMIT_ACCEL_LONG(C_AXIS, 0),
|
||||
LIMIT_ACCEL_LONG(I_AXIS, 0),
|
||||
LIMIT_ACCEL_LONG(J_AXIS, 0),
|
||||
LIMIT_ACCEL_LONG(K_AXIS, 0)
|
||||
LIMIT_ACCEL_LONG(K_AXIS, 0),
|
||||
LIMIT_ACCEL_LONG(U_AXIS, 0),
|
||||
LIMIT_ACCEL_LONG(V_AXIS, 0),
|
||||
LIMIT_ACCEL_LONG(W_AXIS, 0)
|
||||
);
|
||||
}
|
||||
else {
|
||||
@ -2453,7 +2541,10 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
LIMIT_ACCEL_FLOAT(C_AXIS, 0),
|
||||
LIMIT_ACCEL_FLOAT(I_AXIS, 0),
|
||||
LIMIT_ACCEL_FLOAT(J_AXIS, 0),
|
||||
LIMIT_ACCEL_FLOAT(K_AXIS, 0)
|
||||
LIMIT_ACCEL_FLOAT(K_AXIS, 0),
|
||||
LIMIT_ACCEL_FLOAT(U_AXIS, 0),
|
||||
LIMIT_ACCEL_FLOAT(V_AXIS, 0),
|
||||
LIMIT_ACCEL_FLOAT(W_AXIS, 0)
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -2518,7 +2609,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
#if HAS_DIST_MM_ARG
|
||||
cart_dist_mm
|
||||
#else
|
||||
LOGICAL_AXIS_ARRAY(steps_dist_mm.e, steps_dist_mm.x, steps_dist_mm.y, steps_dist_mm.z, steps_dist_mm.i, steps_dist_mm.j, steps_dist_mm.k)
|
||||
LOGICAL_AXIS_ARRAY(steps_dist_mm.e, steps_dist_mm.x, steps_dist_mm.y, steps_dist_mm.z, steps_dist_mm.i, steps_dist_mm.j, steps_dist_mm.k, steps_dist_mm.u, steps_dist_mm.v, steps_dist_mm.w)
|
||||
#endif
|
||||
;
|
||||
|
||||
@ -2544,7 +2635,10 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
+ (-prev_unit_vec.z * unit_vec.z),
|
||||
+ (-prev_unit_vec.i * unit_vec.i),
|
||||
+ (-prev_unit_vec.j * unit_vec.j),
|
||||
+ (-prev_unit_vec.k * unit_vec.k)
|
||||
+ (-prev_unit_vec.k * unit_vec.k),
|
||||
+ (-prev_unit_vec.u * unit_vec.u),
|
||||
+ (-prev_unit_vec.v * unit_vec.v),
|
||||
+ (-prev_unit_vec.w * unit_vec.w)
|
||||
);
|
||||
|
||||
// NOTE: Computed without any expensive trig, sin() or acos(), by trig half angle identity of cos(theta).
|
||||
@ -2691,7 +2785,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
const float extra_xyjerk = TERN0(HAS_EXTRUDERS, de <= 0) ? TRAVEL_EXTRA_XYJERK : 0;
|
||||
|
||||
uint8_t limited = 0;
|
||||
TERN(HAS_LINEAR_E_JERK, LOOP_LINEAR_AXES, LOOP_LOGICAL_AXES)(i) {
|
||||
TERN(HAS_LINEAR_E_JERK, LOOP_NUM_AXES, LOOP_LOGICAL_AXES)(i) {
|
||||
const float jerk = ABS(current_speed[i]), // cs : Starting from zero, change in speed for this axis
|
||||
maxj = (max_jerk[i] + (i == X_AXIS || i == Y_AXIS ? extra_xyjerk : 0.0f)); // mj : The max jerk setting for this axis
|
||||
if (jerk > maxj) { // cs > mj : New current speed too fast?
|
||||
@ -2729,7 +2823,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
vmax_junction = previous_nominal_speed;
|
||||
|
||||
// Now limit the jerk in all axes.
|
||||
TERN(HAS_LINEAR_E_JERK, LOOP_LINEAR_AXES, LOOP_LOGICAL_AXES)(axis) {
|
||||
TERN(HAS_LINEAR_E_JERK, LOOP_NUM_AXES, LOOP_LOGICAL_AXES)(axis) {
|
||||
// Limit an axis. We have to differentiate: coasting, reversal of an axis, full stop.
|
||||
float v_exit = previous_speed[axis] * smaller_speed_factor,
|
||||
v_entry = current_speed[axis];
|
||||
@ -2831,7 +2925,7 @@ void Planner::buffer_sync_block(TERN_(LASER_SYNCHRONOUS_M106_M107, uint8_t sync_
|
||||
|
||||
block->position = position;
|
||||
#if ENABLED(BACKLASH_COMPENSATION)
|
||||
LOOP_LINEAR_AXES(axis) block->position[axis] += backlash.get_applied_steps((AxisEnum)axis);
|
||||
LOOP_NUM_AXES(axis) block->position[axis] += backlash.get_applied_steps((AxisEnum)axis);
|
||||
#endif
|
||||
|
||||
#if BOTH(HAS_FAN, LASER_SYNCHRONOUS_M106_M107)
|
||||
@ -2893,7 +2987,10 @@ bool Planner::buffer_segment(const abce_pos_t &abce
|
||||
int32_t(LROUND(abce.c * settings.axis_steps_per_mm[C_AXIS])),
|
||||
int32_t(LROUND(abce.i * settings.axis_steps_per_mm[I_AXIS])),
|
||||
int32_t(LROUND(abce.j * settings.axis_steps_per_mm[J_AXIS])),
|
||||
int32_t(LROUND(abce.k * settings.axis_steps_per_mm[K_AXIS]))
|
||||
int32_t(LROUND(abce.k * settings.axis_steps_per_mm[K_AXIS])),
|
||||
int32_t(LROUND(abce.u * settings.axis_steps_per_mm[U_AXIS])),
|
||||
int32_t(LROUND(abce.v * settings.axis_steps_per_mm[V_AXIS])),
|
||||
int32_t(LROUND(abce.w * settings.axis_steps_per_mm[W_AXIS]))
|
||||
)
|
||||
};
|
||||
|
||||
@ -2945,6 +3042,21 @@ bool Planner::buffer_segment(const abce_pos_t &abce
|
||||
SERIAL_ECHOPGM(" (", position.k, "->", target.k);
|
||||
SERIAL_CHAR(')');
|
||||
#endif
|
||||
#if HAS_U_AXIS
|
||||
SERIAL_ECHOPGM_P(SP_U_LBL, abce.u);
|
||||
SERIAL_ECHOPGM(" (", position.u, "->", target.u);
|
||||
SERIAL_CHAR(')');
|
||||
#endif
|
||||
#if HAS_V_AXIS
|
||||
SERIAL_ECHOPGM_P(SP_V_LBL, abce.v);
|
||||
SERIAL_ECHOPGM(" (", position.v, "->", target.v);
|
||||
SERIAL_CHAR(')');
|
||||
#endif
|
||||
#if HAS_W_AXIS
|
||||
SERIAL_ECHOPGM_P(SP_W_LBL, abce.w);
|
||||
SERIAL_ECHOPGM(" (", position.w, "->", target.w);
|
||||
SERIAL_CHAR(')');
|
||||
#endif
|
||||
#if HAS_EXTRUDERS
|
||||
SERIAL_ECHOPGM_P(SP_E_LBL, abce.e);
|
||||
SERIAL_ECHOLNPGM(" (", position.e, "->", target.e, ")");
|
||||
@ -2987,12 +3099,14 @@ bool Planner::buffer_line(const xyze_pos_t &cart, const_feedRate_t fr_mm_s, cons
|
||||
const xyze_pos_t cart_dist_mm = LOGICAL_AXIS_ARRAY(
|
||||
cart.e - position_cart.e,
|
||||
cart.x - position_cart.x, cart.y - position_cart.y, cart.z - position_cart.z,
|
||||
cart.i - position_cart.i, cart.j - position_cart.j, cart.j - position_cart.k
|
||||
cart.i - position_cart.i, cart.j - position_cart.j, cart.k - position_cart.k,
|
||||
cart.u - position_cart.u, cart.v - position_cart.v, cart.w - position_cart.w
|
||||
);
|
||||
#else
|
||||
const xyz_pos_t cart_dist_mm = LINEAR_AXIS_ARRAY(
|
||||
const xyz_pos_t cart_dist_mm = NUM_AXIS_ARRAY(
|
||||
cart.x - position_cart.x, cart.y - position_cart.y, cart.z - position_cart.z,
|
||||
cart.i - position_cart.i, cart.j - position_cart.j, cart.j - position_cart.k
|
||||
cart.i - position_cart.i, cart.j - position_cart.j, cart.k - position_cart.k,
|
||||
cart.u - position_cart.u, cart.v - position_cart.v, cart.w - position_cart.w
|
||||
);
|
||||
#endif
|
||||
|
||||
@ -3097,7 +3211,10 @@ void Planner::set_machine_position_mm(const abce_pos_t &abce) {
|
||||
LROUND(abce.c * settings.axis_steps_per_mm[C_AXIS]),
|
||||
LROUND(abce.i * settings.axis_steps_per_mm[I_AXIS]),
|
||||
LROUND(abce.j * settings.axis_steps_per_mm[J_AXIS]),
|
||||
LROUND(abce.k * settings.axis_steps_per_mm[K_AXIS])
|
||||
LROUND(abce.k * settings.axis_steps_per_mm[K_AXIS]),
|
||||
LROUND(abce.u * settings.axis_steps_per_mm[U_AXIS]),
|
||||
LROUND(abce.v * settings.axis_steps_per_mm[V_AXIS]),
|
||||
LROUND(abce.w * settings.axis_steps_per_mm[W_AXIS])
|
||||
)
|
||||
);
|
||||
|
||||
@ -3109,7 +3226,7 @@ void Planner::set_machine_position_mm(const abce_pos_t &abce) {
|
||||
else {
|
||||
#if ENABLED(BACKLASH_COMPENSATION)
|
||||
abce_long_t stepper_pos = position;
|
||||
LOOP_LINEAR_AXES(axis) stepper_pos[axis] += backlash.get_applied_steps((AxisEnum)axis);
|
||||
LOOP_NUM_AXES(axis) stepper_pos[axis] += backlash.get_applied_steps((AxisEnum)axis);
|
||||
stepper.set_position(stepper_pos);
|
||||
#else
|
||||
stepper.set_position(position);
|
||||
|
@ -84,7 +84,8 @@
|
||||
constexpr xyze_feedrate_t _mf = MANUAL_FEEDRATE,
|
||||
manual_feedrate_mm_s = LOGICAL_AXIS_ARRAY(_mf.e / 60.0f,
|
||||
_mf.x / 60.0f, _mf.y / 60.0f, _mf.z / 60.0f,
|
||||
_mf.i / 60.0f, _mf.j / 60.0f, _mf.k / 60.0f);
|
||||
_mf.i / 60.0f, _mf.j / 60.0f, _mf.k / 60.0f,
|
||||
_mf.u / 60.0f, _mf.v / 60.0f, _mf.w / 60.0f);
|
||||
#endif
|
||||
|
||||
#if IS_KINEMATIC && HAS_JUNCTION_DEVIATION
|
||||
@ -843,7 +844,8 @@ class Planner {
|
||||
const abce_pos_t out = LOGICAL_AXIS_ARRAY(
|
||||
get_axis_position_mm(E_AXIS),
|
||||
get_axis_position_mm(A_AXIS), get_axis_position_mm(B_AXIS), get_axis_position_mm(C_AXIS),
|
||||
get_axis_position_mm(I_AXIS), get_axis_position_mm(J_AXIS), get_axis_position_mm(K_AXIS)
|
||||
get_axis_position_mm(I_AXIS), get_axis_position_mm(J_AXIS), get_axis_position_mm(K_AXIS),
|
||||
get_axis_position_mm(U_AXIS), get_axis_position_mm(V_AXIS), get_axis_position_mm(W_AXIS)
|
||||
);
|
||||
return out;
|
||||
}
|
||||
|
@ -188,7 +188,10 @@ void cubic_b_spline(
|
||||
interp(position.z, target.z, t), // FIXME. Wrong, since t is not linear in the distance.
|
||||
interp(position.i, target.i, t), // FIXME. Wrong, since t is not linear in the distance.
|
||||
interp(position.j, target.j, t), // FIXME. Wrong, since t is not linear in the distance.
|
||||
interp(position.k, target.k, t) // FIXME. Wrong, since t is not linear in the distance.
|
||||
interp(position.k, target.k, t), // FIXME. Wrong, since t is not linear in the distance.
|
||||
interp(position.u, target.u, t), // FIXME. Wrong, since t is not linear in the distance.
|
||||
interp(position.v, target.v, t), // FIXME. Wrong, since t is not linear in the distance.
|
||||
interp(position.w, target.w, t) // FIXME. Wrong, since t is not linear in the distance.
|
||||
);
|
||||
apply_motion_limits(new_bez);
|
||||
bez_target = new_bez;
|
||||
|
@ -809,9 +809,10 @@ float Probe::probe_at_point(const_float_t rx, const_float_t ry, const ProbePtRai
|
||||
#endif
|
||||
|
||||
// On delta keep Z below clip height or do_blocking_move_to will abort
|
||||
xyz_pos_t npos = LINEAR_AXIS_ARRAY(
|
||||
xyz_pos_t npos = NUM_AXIS_ARRAY(
|
||||
rx, ry, TERN(DELTA, _MIN(delta_clip_start_height, current_position.z), current_position.z),
|
||||
current_position.i, current_position.j, current_position.k
|
||||
current_position.i, current_position.j, current_position.k,
|
||||
current_position.u, current_position.v, current_position.w
|
||||
);
|
||||
if (!can_reach(npos, probe_relative)) {
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Position Not Reachable");
|
||||
|
@ -146,7 +146,7 @@ public:
|
||||
|
||||
#else
|
||||
|
||||
static constexpr xyz_pos_t offset = xyz_pos_t(LINEAR_AXIS_ARRAY(0, 0, 0, 0, 0, 0)); // See #16767
|
||||
static constexpr xyz_pos_t offset = xyz_pos_t(NUM_AXIS_ARRAY(0, 0, 0, 0, 0, 0)); // See #16767
|
||||
|
||||
static bool set_deployed(const bool) { return false; }
|
||||
|
||||
|
@ -254,7 +254,7 @@ float segments_per_second = TERN(AXEL_TPARA, TPARA_SEGMENTS_PER_SECOND, SCARA_SE
|
||||
// Do this here all at once for Delta, because
|
||||
// XYZ isn't ABC. Applying this per-tower would
|
||||
// give the impression that they are the same.
|
||||
LOOP_LINEAR_AXES(i) set_axis_is_at_home((AxisEnum)i);
|
||||
LOOP_NUM_AXES(i) set_axis_is_at_home((AxisEnum)i);
|
||||
|
||||
sync_plan_position();
|
||||
}
|
||||
|
@ -180,10 +180,10 @@
|
||||
#define _EN_ITEM(N) , E##N
|
||||
#define _EN1_ITEM(N) , E##N:1
|
||||
|
||||
typedef struct { uint16_t LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } per_stepper_uint16_t;
|
||||
typedef struct { uint32_t LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } per_stepper_uint32_t;
|
||||
typedef struct { int16_t LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4; } mot_stepper_int16_t;
|
||||
typedef struct { bool LINEAR_AXIS_LIST(X:1, Y:1, Z:1, I:1, J:1, K:1), X2:1, Y2:1, Z2:1, Z3:1, Z4:1 REPEAT(E_STEPPERS, _EN1_ITEM); } per_stepper_bool_t;
|
||||
typedef struct { uint16_t NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } per_stepper_uint16_t;
|
||||
typedef struct { uint32_t NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W), X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } per_stepper_uint32_t;
|
||||
typedef struct { int16_t NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W), X2, Y2, Z2, Z3, Z4; } mot_stepper_int16_t;
|
||||
typedef struct { bool NUM_AXIS_LIST(X:1, Y:1, Z:1, I:1, J:1, K:1, U:1, V:1, W:1), X2:1, Y2:1, Z2:1, Z3:1, Z4:1 REPEAT(E_STEPPERS, _EN1_ITEM); } per_stepper_bool_t;
|
||||
|
||||
#undef _EN_ITEM
|
||||
|
||||
@ -211,7 +211,7 @@ typedef struct SettingsDataStruct {
|
||||
//
|
||||
// DISTINCT_E_FACTORS
|
||||
//
|
||||
uint8_t e_factors; // DISTINCT_AXES - LINEAR_AXES
|
||||
uint8_t e_factors; // DISTINCT_AXES - NUM_AXES
|
||||
|
||||
//
|
||||
// Planner settings
|
||||
@ -447,7 +447,7 @@ typedef struct SettingsDataStruct {
|
||||
// HAS_MOTOR_CURRENT_PWM
|
||||
//
|
||||
#ifndef MOTOR_CURRENT_COUNT
|
||||
#define MOTOR_CURRENT_COUNT LINEAR_AXES
|
||||
#define MOTOR_CURRENT_COUNT NUM_AXES
|
||||
#endif
|
||||
uint32_t motor_current_setting[MOTOR_CURRENT_COUNT]; // M907 X Z E ...
|
||||
|
||||
@ -600,7 +600,7 @@ void MarlinSettings::postprocess() {
|
||||
#endif
|
||||
|
||||
// Software endstops depend on home_offset
|
||||
LOOP_LINEAR_AXES(i) {
|
||||
LOOP_NUM_AXES(i) {
|
||||
update_workspace_offset((AxisEnum)i);
|
||||
update_software_endstops((AxisEnum)i);
|
||||
}
|
||||
@ -750,7 +750,7 @@ void MarlinSettings::postprocess() {
|
||||
|
||||
working_crc = 0; // clear before first "real data"
|
||||
|
||||
const uint8_t e_factors = DISTINCT_AXES - (LINEAR_AXES);
|
||||
const uint8_t e_factors = DISTINCT_AXES - (NUM_AXES);
|
||||
_FIELD_TEST(e_factors);
|
||||
EEPROM_WRITE(e_factors);
|
||||
|
||||
@ -767,7 +767,7 @@ void MarlinSettings::postprocess() {
|
||||
EEPROM_WRITE(dummyf);
|
||||
#endif
|
||||
#else
|
||||
const xyze_pos_t planner_max_jerk = LOGICAL_AXIS_ARRAY(float(DEFAULT_EJERK), 10, 10, 0.4, 0.4, 0.4, 0.4);
|
||||
const xyze_pos_t planner_max_jerk = LOGICAL_AXIS_ARRAY(float(DEFAULT_EJERK), 10, 10, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4);
|
||||
EEPROM_WRITE(planner_max_jerk);
|
||||
#endif
|
||||
|
||||
@ -1248,6 +1248,15 @@ void MarlinSettings::postprocess() {
|
||||
#if AXIS_IS_TMC(K)
|
||||
tmc_stepper_current.K = stepperK.getMilliamps();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(U)
|
||||
tmc_stepper_current.U = stepperU.getMilliamps();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(V)
|
||||
tmc_stepper_current.V = stepperV.getMilliamps();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(W)
|
||||
tmc_stepper_current.W = stepperW.getMilliamps();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(X2)
|
||||
tmc_stepper_current.X2 = stepperX2.getMilliamps();
|
||||
#endif
|
||||
@ -1305,6 +1314,9 @@ void MarlinSettings::postprocess() {
|
||||
TERN_(I_HAS_STEALTHCHOP, tmc_hybrid_threshold.I = stepperI.get_pwm_thrs());
|
||||
TERN_(J_HAS_STEALTHCHOP, tmc_hybrid_threshold.J = stepperJ.get_pwm_thrs());
|
||||
TERN_(K_HAS_STEALTHCHOP, tmc_hybrid_threshold.K = stepperK.get_pwm_thrs());
|
||||
TERN_(U_HAS_STEALTHCHOP, tmc_hybrid_threshold.U = stepperU.get_pwm_thrs());
|
||||
TERN_(V_HAS_STEALTHCHOP, tmc_hybrid_threshold.V = stepperV.get_pwm_thrs());
|
||||
TERN_(W_HAS_STEALTHCHOP, tmc_hybrid_threshold.W = stepperW.get_pwm_thrs());
|
||||
TERN_(X2_HAS_STEALTHCHOP, tmc_hybrid_threshold.X2 = stepperX2.get_pwm_thrs());
|
||||
TERN_(Y2_HAS_STEALTHCHOP, tmc_hybrid_threshold.Y2 = stepperY2.get_pwm_thrs());
|
||||
TERN_(Z2_HAS_STEALTHCHOP, tmc_hybrid_threshold.Z2 = stepperZ2.get_pwm_thrs());
|
||||
@ -1321,7 +1333,7 @@ void MarlinSettings::postprocess() {
|
||||
#else
|
||||
#define _EN_ITEM(N) , .E##N = 30
|
||||
const per_stepper_uint32_t tmc_hybrid_threshold = {
|
||||
LINEAR_AXIS_LIST(.X = 100, .Y = 100, .Z = 3, .I = 3, .J = 3, .K = 3),
|
||||
NUM_AXIS_LIST(.X = 100, .Y = 100, .Z = 3, .I = 3, .J = 3, .K = 3, .U = 3, .V = 3, .W = 3),
|
||||
.X2 = 100, .Y2 = 100, .Z2 = 3, .Z3 = 3, .Z4 = 3
|
||||
REPEAT(E_STEPPERS, _EN_ITEM)
|
||||
};
|
||||
@ -1336,13 +1348,16 @@ void MarlinSettings::postprocess() {
|
||||
{
|
||||
mot_stepper_int16_t tmc_sgt{0};
|
||||
#if USE_SENSORLESS
|
||||
LINEAR_AXIS_CODE(
|
||||
NUM_AXIS_CODE(
|
||||
TERN_(X_SENSORLESS, tmc_sgt.X = stepperX.homing_threshold()),
|
||||
TERN_(Y_SENSORLESS, tmc_sgt.Y = stepperY.homing_threshold()),
|
||||
TERN_(Z_SENSORLESS, tmc_sgt.Z = stepperZ.homing_threshold()),
|
||||
TERN_(I_SENSORLESS, tmc_sgt.I = stepperI.homing_threshold()),
|
||||
TERN_(J_SENSORLESS, tmc_sgt.J = stepperJ.homing_threshold()),
|
||||
TERN_(K_SENSORLESS, tmc_sgt.K = stepperK.homing_threshold())
|
||||
TERN_(K_SENSORLESS, tmc_sgt.K = stepperK.homing_threshold()),
|
||||
TERN_(U_SENSORLESS, tmc_sgt.U = stepperU.homing_threshold()),
|
||||
TERN_(V_SENSORLESS, tmc_sgt.V = stepperV.homing_threshold()),
|
||||
TERN_(W_SENSORLESS, tmc_sgt.W = stepperW.homing_threshold())
|
||||
);
|
||||
TERN_(X2_SENSORLESS, tmc_sgt.X2 = stepperX2.homing_threshold());
|
||||
TERN_(Y2_SENSORLESS, tmc_sgt.Y2 = stepperY2.homing_threshold());
|
||||
@ -1366,6 +1381,9 @@ void MarlinSettings::postprocess() {
|
||||
TERN_(I_HAS_STEALTHCHOP, tmc_stealth_enabled.I = stepperI.get_stored_stealthChop());
|
||||
TERN_(J_HAS_STEALTHCHOP, tmc_stealth_enabled.J = stepperJ.get_stored_stealthChop());
|
||||
TERN_(K_HAS_STEALTHCHOP, tmc_stealth_enabled.K = stepperK.get_stored_stealthChop());
|
||||
TERN_(U_HAS_STEALTHCHOP, tmc_stealth_enabled.U = stepperU.get_stored_stealthChop());
|
||||
TERN_(V_HAS_STEALTHCHOP, tmc_stealth_enabled.V = stepperV.get_stored_stealthChop());
|
||||
TERN_(W_HAS_STEALTHCHOP, tmc_stealth_enabled.W = stepperW.get_stored_stealthChop());
|
||||
TERN_(X2_HAS_STEALTHCHOP, tmc_stealth_enabled.X2 = stepperX2.get_stored_stealthChop());
|
||||
TERN_(Y2_HAS_STEALTHCHOP, tmc_stealth_enabled.Y2 = stepperY2.get_stored_stealthChop());
|
||||
TERN_(Z2_HAS_STEALTHCHOP, tmc_stealth_enabled.Z2 = stepperZ2.get_stored_stealthChop());
|
||||
@ -1455,7 +1473,7 @@ void MarlinSettings::postprocess() {
|
||||
{
|
||||
#if ENABLED(BACKLASH_GCODE)
|
||||
xyz_float_t backlash_distance_mm;
|
||||
LOOP_LINEAR_AXES(axis) backlash_distance_mm[axis] = backlash.get_distance_mm((AxisEnum)axis);
|
||||
LOOP_NUM_AXES(axis) backlash_distance_mm[axis] = backlash.get_distance_mm((AxisEnum)axis);
|
||||
const uint8_t backlash_correction = backlash.get_correction_uint8();
|
||||
#else
|
||||
const xyz_float_t backlash_distance_mm{0};
|
||||
@ -1675,16 +1693,16 @@ void MarlinSettings::postprocess() {
|
||||
{
|
||||
// Get only the number of E stepper parameters previously stored
|
||||
// Any steppers added later are set to their defaults
|
||||
uint32_t tmp1[LINEAR_AXES + e_factors];
|
||||
float tmp2[LINEAR_AXES + e_factors];
|
||||
feedRate_t tmp3[LINEAR_AXES + e_factors];
|
||||
uint32_t tmp1[NUM_AXES + e_factors];
|
||||
float tmp2[NUM_AXES + e_factors];
|
||||
feedRate_t tmp3[NUM_AXES + e_factors];
|
||||
EEPROM_READ((uint8_t *)tmp1, sizeof(tmp1)); // max_acceleration_mm_per_s2
|
||||
EEPROM_READ(planner.settings.min_segment_time_us);
|
||||
EEPROM_READ((uint8_t *)tmp2, sizeof(tmp2)); // axis_steps_per_mm
|
||||
EEPROM_READ((uint8_t *)tmp3, sizeof(tmp3)); // max_feedrate_mm_s
|
||||
|
||||
if (!validating) LOOP_DISTINCT_AXES(i) {
|
||||
const bool in = (i < e_factors + LINEAR_AXES);
|
||||
const bool in = (i < e_factors + NUM_AXES);
|
||||
planner.settings.max_acceleration_mm_per_s2[i] = in ? tmp1[i] : pgm_read_dword(&_DMA[ALIM(i, _DMA)]);
|
||||
planner.settings.axis_steps_per_mm[i] = in ? tmp2[i] : pgm_read_float(&_DASU[ALIM(i, _DASU)]);
|
||||
planner.settings.max_feedrate_mm_s[i] = in ? tmp3[i] : pgm_read_float(&_DMF[ALIM(i, _DMF)]);
|
||||
@ -2199,6 +2217,15 @@ void MarlinSettings::postprocess() {
|
||||
#if AXIS_IS_TMC(K)
|
||||
SET_CURR(K);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(U)
|
||||
SET_CURR(U);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(V)
|
||||
SET_CURR(V);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(W)
|
||||
SET_CURR(W);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E0)
|
||||
SET_CURR(E0);
|
||||
#endif
|
||||
@ -2246,6 +2273,9 @@ void MarlinSettings::postprocess() {
|
||||
TERN_(I_HAS_STEALTHCHOP, stepperI.set_pwm_thrs(tmc_hybrid_threshold.I));
|
||||
TERN_(J_HAS_STEALTHCHOP, stepperJ.set_pwm_thrs(tmc_hybrid_threshold.J));
|
||||
TERN_(K_HAS_STEALTHCHOP, stepperK.set_pwm_thrs(tmc_hybrid_threshold.K));
|
||||
TERN_(U_HAS_STEALTHCHOP, stepperU.set_pwm_thrs(tmc_hybrid_threshold.U));
|
||||
TERN_(V_HAS_STEALTHCHOP, stepperV.set_pwm_thrs(tmc_hybrid_threshold.V));
|
||||
TERN_(W_HAS_STEALTHCHOP, stepperW.set_pwm_thrs(tmc_hybrid_threshold.W));
|
||||
TERN_(E0_HAS_STEALTHCHOP, stepperE0.set_pwm_thrs(tmc_hybrid_threshold.E0));
|
||||
TERN_(E1_HAS_STEALTHCHOP, stepperE1.set_pwm_thrs(tmc_hybrid_threshold.E1));
|
||||
TERN_(E2_HAS_STEALTHCHOP, stepperE2.set_pwm_thrs(tmc_hybrid_threshold.E2));
|
||||
@ -2267,13 +2297,16 @@ void MarlinSettings::postprocess() {
|
||||
EEPROM_READ(tmc_sgt);
|
||||
#if USE_SENSORLESS
|
||||
if (!validating) {
|
||||
LINEAR_AXIS_CODE(
|
||||
NUM_AXIS_CODE(
|
||||
TERN_(X_SENSORLESS, stepperX.homing_threshold(tmc_sgt.X)),
|
||||
TERN_(Y_SENSORLESS, stepperY.homing_threshold(tmc_sgt.Y)),
|
||||
TERN_(Z_SENSORLESS, stepperZ.homing_threshold(tmc_sgt.Z)),
|
||||
TERN_(I_SENSORLESS, stepperI.homing_threshold(tmc_sgt.I)),
|
||||
TERN_(J_SENSORLESS, stepperJ.homing_threshold(tmc_sgt.J)),
|
||||
TERN_(K_SENSORLESS, stepperK.homing_threshold(tmc_sgt.K))
|
||||
TERN_(K_SENSORLESS, stepperK.homing_threshold(tmc_sgt.K)),
|
||||
TERN_(U_SENSORLESS, stepperU.homing_threshold(tmc_sgt.U)),
|
||||
TERN_(V_SENSORLESS, stepperV.homing_threshold(tmc_sgt.V)),
|
||||
TERN_(W_SENSORLESS, stepperW.homing_threshold(tmc_sgt.W))
|
||||
);
|
||||
TERN_(X2_SENSORLESS, stepperX2.homing_threshold(tmc_sgt.X2));
|
||||
TERN_(Y2_SENSORLESS, stepperY2.homing_threshold(tmc_sgt.Y2));
|
||||
@ -2301,6 +2334,9 @@ void MarlinSettings::postprocess() {
|
||||
TERN_(I_HAS_STEALTHCHOP, SET_STEPPING_MODE(I));
|
||||
TERN_(J_HAS_STEALTHCHOP, SET_STEPPING_MODE(J));
|
||||
TERN_(K_HAS_STEALTHCHOP, SET_STEPPING_MODE(K));
|
||||
TERN_(U_HAS_STEALTHCHOP, SET_STEPPING_MODE(U));
|
||||
TERN_(V_HAS_STEALTHCHOP, SET_STEPPING_MODE(V));
|
||||
TERN_(W_HAS_STEALTHCHOP, SET_STEPPING_MODE(W));
|
||||
TERN_(X2_HAS_STEALTHCHOP, SET_STEPPING_MODE(X2));
|
||||
TERN_(Y2_HAS_STEALTHCHOP, SET_STEPPING_MODE(Y2));
|
||||
TERN_(Z2_HAS_STEALTHCHOP, SET_STEPPING_MODE(Z2));
|
||||
@ -2421,7 +2457,7 @@ void MarlinSettings::postprocess() {
|
||||
EEPROM_READ(backlash_smoothing_mm);
|
||||
|
||||
#if ENABLED(BACKLASH_GCODE)
|
||||
LOOP_LINEAR_AXES(axis) backlash.set_distance_mm((AxisEnum)axis, backlash_distance_mm[axis]);
|
||||
LOOP_NUM_AXES(axis) backlash.set_distance_mm((AxisEnum)axis, backlash_distance_mm[axis]);
|
||||
backlash.set_correction_uint8(backlash_correction);
|
||||
#ifdef BACKLASH_SMOOTHING_MM
|
||||
backlash.set_smoothing_mm(backlash_smoothing_mm);
|
||||
@ -2807,8 +2843,17 @@ void MarlinSettings::reset() {
|
||||
#if HAS_K_AXIS && !defined(DEFAULT_KJERK)
|
||||
#define DEFAULT_KJERK 0
|
||||
#endif
|
||||
#if HAS_U_AXIS && !defined(DEFAULT_UJERK)
|
||||
#define DEFAULT_UJERK 0
|
||||
#endif
|
||||
#if HAS_V_AXIS && !defined(DEFAULT_VJERK)
|
||||
#define DEFAULT_VJERK 0
|
||||
#endif
|
||||
#if HAS_W_AXIS && !defined(DEFAULT_WJERK)
|
||||
#define DEFAULT_WJERK 0
|
||||
#endif
|
||||
planner.max_jerk.set(
|
||||
LINEAR_AXIS_LIST(DEFAULT_XJERK, DEFAULT_YJERK, DEFAULT_ZJERK, DEFAULT_IJERK, DEFAULT_JJERK, DEFAULT_KJERK)
|
||||
NUM_AXIS_LIST(DEFAULT_XJERK, DEFAULT_YJERK, DEFAULT_ZJERK, DEFAULT_IJERK, DEFAULT_JJERK, DEFAULT_KJERK, DEFAULT_UJERK, DEFAULT_VJERK, DEFAULT_WJERK)
|
||||
);
|
||||
TERN_(HAS_CLASSIC_E_JERK, planner.max_jerk.e = DEFAULT_EJERK);
|
||||
#endif
|
||||
@ -2870,7 +2915,7 @@ void MarlinSettings::reset() {
|
||||
#if ENABLED(BACKLASH_GCODE)
|
||||
backlash.set_correction(BACKLASH_CORRECTION);
|
||||
constexpr xyz_float_t tmp = BACKLASH_DISTANCE_MM;
|
||||
LOOP_LINEAR_AXES(axis) backlash.set_distance_mm((AxisEnum)axis, tmp[axis]);
|
||||
LOOP_NUM_AXES(axis) backlash.set_distance_mm((AxisEnum)axis, tmp[axis]);
|
||||
#ifdef BACKLASH_SMOOTHING_MM
|
||||
backlash.set_smoothing_mm(BACKLASH_SMOOTHING_MM);
|
||||
#endif
|
||||
@ -2916,11 +2961,11 @@ void MarlinSettings::reset() {
|
||||
//
|
||||
#if HAS_BED_PROBE
|
||||
constexpr float dpo[] = NOZZLE_TO_PROBE_OFFSET;
|
||||
static_assert(COUNT(dpo) == LINEAR_AXES, "NOZZLE_TO_PROBE_OFFSET must contain offsets for each linear axis X, Y, Z....");
|
||||
static_assert(COUNT(dpo) == NUM_AXES, "NOZZLE_TO_PROBE_OFFSET must contain offsets for each linear axis X, Y, Z....");
|
||||
#if HAS_PROBE_XY_OFFSET
|
||||
LOOP_LINEAR_AXES(a) probe.offset[a] = dpo[a];
|
||||
LOOP_NUM_AXES(a) probe.offset[a] = dpo[a];
|
||||
#else
|
||||
probe.offset.set(LINEAR_AXIS_LIST(0, 0, dpo[Z_AXIS], 0, 0, 0));
|
||||
probe.offset.set(NUM_AXIS_LIST(0, 0, dpo[Z_AXIS], 0, 0, 0, 0, 0, 0));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -447,6 +447,18 @@ xyze_int8_t Stepper::count_direction{0};
|
||||
#define K_APPLY_DIR(v,Q) K_DIR_WRITE(v)
|
||||
#define K_APPLY_STEP(v,Q) K_STEP_WRITE(v)
|
||||
#endif
|
||||
#if HAS_U_AXIS
|
||||
#define U_APPLY_DIR(v,Q) U_DIR_WRITE(v)
|
||||
#define U_APPLY_STEP(v,Q) U_STEP_WRITE(v)
|
||||
#endif
|
||||
#if HAS_V_AXIS
|
||||
#define V_APPLY_DIR(v,Q) V_DIR_WRITE(v)
|
||||
#define V_APPLY_STEP(v,Q) V_STEP_WRITE(v)
|
||||
#endif
|
||||
#if HAS_W_AXIS
|
||||
#define W_APPLY_DIR(v,Q) W_DIR_WRITE(v)
|
||||
#define W_APPLY_STEP(v,Q) W_STEP_WRITE(v)
|
||||
#endif
|
||||
|
||||
#if DISABLED(MIXING_EXTRUDER)
|
||||
#define E_APPLY_STEP(v,Q) E_STEP_WRITE(stepper_extruder, v)
|
||||
@ -486,9 +498,10 @@ xyze_int8_t Stepper::count_direction{0};
|
||||
void Stepper::enable_axis(const AxisEnum axis) {
|
||||
#define _CASE_ENABLE(N) case N##_AXIS: ENABLE_AXIS_##N(); break;
|
||||
switch (axis) {
|
||||
LINEAR_AXIS_CODE(
|
||||
NUM_AXIS_CODE(
|
||||
_CASE_ENABLE(X), _CASE_ENABLE(Y), _CASE_ENABLE(Z),
|
||||
_CASE_ENABLE(I), _CASE_ENABLE(J), _CASE_ENABLE(K)
|
||||
_CASE_ENABLE(I), _CASE_ENABLE(J), _CASE_ENABLE(K),
|
||||
_CASE_ENABLE(U), _CASE_ENABLE(V), _CASE_ENABLE(W)
|
||||
);
|
||||
default: break;
|
||||
}
|
||||
@ -505,9 +518,10 @@ bool Stepper::disable_axis(const AxisEnum axis) {
|
||||
if (can_disable) {
|
||||
#define _CASE_DISABLE(N) case N##_AXIS: DISABLE_AXIS_##N(); break;
|
||||
switch (axis) {
|
||||
LINEAR_AXIS_CODE(
|
||||
NUM_AXIS_CODE(
|
||||
_CASE_DISABLE(X), _CASE_DISABLE(Y), _CASE_DISABLE(Z),
|
||||
_CASE_DISABLE(I), _CASE_DISABLE(J), _CASE_DISABLE(K)
|
||||
_CASE_DISABLE(I), _CASE_DISABLE(J), _CASE_DISABLE(K),
|
||||
_CASE_DISABLE(U), _CASE_DISABLE(V), _CASE_DISABLE(W)
|
||||
);
|
||||
default: break;
|
||||
}
|
||||
@ -550,9 +564,10 @@ bool Stepper::disable_axis(const AxisEnum axis) {
|
||||
|
||||
void Stepper::enable_all_steppers() {
|
||||
TERN_(AUTO_POWER_CONTROL, powerManager.power_on());
|
||||
LINEAR_AXIS_CODE(
|
||||
NUM_AXIS_CODE(
|
||||
enable_axis(X_AXIS), enable_axis(Y_AXIS), enable_axis(Z_AXIS),
|
||||
enable_axis(I_AXIS), enable_axis(J_AXIS), enable_axis(K_AXIS)
|
||||
enable_axis(I_AXIS), enable_axis(J_AXIS), enable_axis(K_AXIS),
|
||||
enable_axis(U_AXIS), enable_axis(V_AXIS), enable_axis(W_AXIS)
|
||||
);
|
||||
enable_e_steppers();
|
||||
|
||||
@ -560,9 +575,10 @@ void Stepper::enable_all_steppers() {
|
||||
}
|
||||
|
||||
void Stepper::disable_all_steppers() {
|
||||
LINEAR_AXIS_CODE(
|
||||
NUM_AXIS_CODE(
|
||||
disable_axis(X_AXIS), disable_axis(Y_AXIS), disable_axis(Z_AXIS),
|
||||
disable_axis(I_AXIS), disable_axis(J_AXIS), disable_axis(K_AXIS)
|
||||
disable_axis(I_AXIS), disable_axis(J_AXIS), disable_axis(K_AXIS),
|
||||
disable_axis(U_AXIS), disable_axis(V_AXIS), disable_axis(W_AXIS)
|
||||
);
|
||||
disable_e_steppers();
|
||||
|
||||
@ -596,6 +612,9 @@ void Stepper::set_directions() {
|
||||
TERN_(HAS_I_DIR, SET_STEP_DIR(I));
|
||||
TERN_(HAS_J_DIR, SET_STEP_DIR(J));
|
||||
TERN_(HAS_K_DIR, SET_STEP_DIR(K));
|
||||
TERN_(HAS_U_DIR, SET_STEP_DIR(U));
|
||||
TERN_(HAS_V_DIR, SET_STEP_DIR(V));
|
||||
TERN_(HAS_W_DIR, SET_STEP_DIR(W));
|
||||
|
||||
#if DISABLED(LIN_ADVANCE)
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
@ -1816,6 +1835,15 @@ void Stepper::pulse_phase_isr() {
|
||||
#if HAS_K_STEP
|
||||
PULSE_PREP(K);
|
||||
#endif
|
||||
#if HAS_U_STEP
|
||||
PULSE_PREP(U);
|
||||
#endif
|
||||
#if HAS_V_STEP
|
||||
PULSE_PREP(V);
|
||||
#endif
|
||||
#if HAS_W_STEP
|
||||
PULSE_PREP(W);
|
||||
#endif
|
||||
|
||||
#if EITHER(LIN_ADVANCE, MIXING_EXTRUDER)
|
||||
delta_error.e += advance_dividend.e;
|
||||
@ -1860,6 +1888,15 @@ void Stepper::pulse_phase_isr() {
|
||||
#if HAS_K_STEP
|
||||
PULSE_START(K);
|
||||
#endif
|
||||
#if HAS_U_STEP
|
||||
PULSE_START(U);
|
||||
#endif
|
||||
#if HAS_V_STEP
|
||||
PULSE_START(V);
|
||||
#endif
|
||||
#if HAS_W_STEP
|
||||
PULSE_START(W);
|
||||
#endif
|
||||
|
||||
#if DISABLED(LIN_ADVANCE)
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
@ -1898,6 +1935,15 @@ void Stepper::pulse_phase_isr() {
|
||||
#if HAS_K_STEP
|
||||
PULSE_STOP(K);
|
||||
#endif
|
||||
#if HAS_U_STEP
|
||||
PULSE_STOP(U);
|
||||
#endif
|
||||
#if HAS_V_STEP
|
||||
PULSE_STOP(V);
|
||||
#endif
|
||||
#if HAS_W_STEP
|
||||
PULSE_STOP(W);
|
||||
#endif
|
||||
|
||||
#if DISABLED(LIN_ADVANCE)
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
@ -2243,13 +2289,16 @@ uint32_t Stepper::block_phase_isr() {
|
||||
#endif
|
||||
|
||||
axis_bits_t axis_bits = 0;
|
||||
LINEAR_AXIS_CODE(
|
||||
NUM_AXIS_CODE(
|
||||
if (X_MOVE_TEST) SBI(axis_bits, A_AXIS),
|
||||
if (Y_MOVE_TEST) SBI(axis_bits, B_AXIS),
|
||||
if (Z_MOVE_TEST) SBI(axis_bits, C_AXIS),
|
||||
if (current_block->steps.i) SBI(axis_bits, I_AXIS),
|
||||
if (current_block->steps.j) SBI(axis_bits, J_AXIS),
|
||||
if (current_block->steps.k) SBI(axis_bits, K_AXIS)
|
||||
if (current_block->steps.k) SBI(axis_bits, K_AXIS),
|
||||
if (current_block->steps.u) SBI(axis_bits, U_AXIS),
|
||||
if (current_block->steps.v) SBI(axis_bits, V_AXIS),
|
||||
if (current_block->steps.w) SBI(axis_bits, W_AXIS)
|
||||
);
|
||||
//if (current_block->steps.e) SBI(axis_bits, E_AXIS);
|
||||
//if (current_block->steps.a) SBI(axis_bits, X_HEAD);
|
||||
@ -2589,6 +2638,15 @@ void Stepper::init() {
|
||||
#if HAS_K_DIR
|
||||
K_DIR_INIT();
|
||||
#endif
|
||||
#if HAS_U_DIR
|
||||
U_DIR_INIT();
|
||||
#endif
|
||||
#if HAS_V_DIR
|
||||
V_DIR_INIT();
|
||||
#endif
|
||||
#if HAS_W_DIR
|
||||
W_DIR_INIT();
|
||||
#endif
|
||||
#if HAS_E0_DIR
|
||||
E0_DIR_INIT();
|
||||
#endif
|
||||
@ -2659,6 +2717,18 @@ void Stepper::init() {
|
||||
K_ENABLE_INIT();
|
||||
if (!K_ENABLE_ON) K_ENABLE_WRITE(HIGH);
|
||||
#endif
|
||||
#if HAS_U_ENABLE
|
||||
U_ENABLE_INIT();
|
||||
if (!U_ENABLE_ON) U_ENABLE_WRITE(HIGH);
|
||||
#endif
|
||||
#if HAS_V_ENABLE
|
||||
V_ENABLE_INIT();
|
||||
if (!V_ENABLE_ON) V_ENABLE_WRITE(HIGH);
|
||||
#endif
|
||||
#if HAS_W_ENABLE
|
||||
W_ENABLE_INIT();
|
||||
if (!W_ENABLE_ON) W_ENABLE_WRITE(HIGH);
|
||||
#endif
|
||||
#if HAS_E0_ENABLE
|
||||
E0_ENABLE_INIT();
|
||||
if (!E_ENABLE_ON) E0_ENABLE_WRITE(HIGH);
|
||||
@ -2744,6 +2814,15 @@ void Stepper::init() {
|
||||
#if HAS_K_STEP
|
||||
AXIS_INIT(K, K);
|
||||
#endif
|
||||
#if HAS_U_STEP
|
||||
AXIS_INIT(U, U);
|
||||
#endif
|
||||
#if HAS_V_STEP
|
||||
AXIS_INIT(V, V);
|
||||
#endif
|
||||
#if HAS_W_STEP
|
||||
AXIS_INIT(W, W);
|
||||
#endif
|
||||
|
||||
#if E_STEPPERS && HAS_E0_STEP
|
||||
E_AXIS_INIT(0);
|
||||
@ -2778,13 +2857,16 @@ void Stepper::init() {
|
||||
|
||||
// Init direction bits for first moves
|
||||
set_directions(0
|
||||
LINEAR_AXIS_GANG(
|
||||
NUM_AXIS_GANG(
|
||||
| TERN0(INVERT_X_DIR, _BV(X_AXIS)),
|
||||
| TERN0(INVERT_Y_DIR, _BV(Y_AXIS)),
|
||||
| TERN0(INVERT_Z_DIR, _BV(Z_AXIS)),
|
||||
| TERN0(INVERT_I_DIR, _BV(I_AXIS)),
|
||||
| TERN0(INVERT_J_DIR, _BV(J_AXIS)),
|
||||
| TERN0(INVERT_K_DIR, _BV(K_AXIS))
|
||||
| TERN0(INVERT_K_DIR, _BV(K_AXIS)),
|
||||
| TERN0(INVERT_U_DIR, _BV(U_AXIS)),
|
||||
| TERN0(INVERT_V_DIR, _BV(V_AXIS)),
|
||||
| TERN0(INVERT_W_DIR, _BV(W_AXIS))
|
||||
)
|
||||
);
|
||||
|
||||
@ -2820,6 +2902,14 @@ void Stepper::_set_position(const abce_long_t &spos) {
|
||||
#elif ENABLED(MARKFORGED_YX)
|
||||
count_position.set(spos.a, spos.b - spos.a, spos.c);
|
||||
#endif
|
||||
SECONDARY_AXIS_CODE(
|
||||
count_position.i = spos.i,
|
||||
count_position.j = spos.j,
|
||||
count_position.k = spos.k,
|
||||
count_position.u = spos.u,
|
||||
count_position.v = spos.v,
|
||||
count_position.w = spos.w
|
||||
);
|
||||
TERN_(HAS_EXTRUDERS, count_position.e = spos.e);
|
||||
#else
|
||||
// default non-h-bot planning
|
||||
@ -2934,13 +3024,16 @@ int32_t Stepper::triggered_position(const AxisEnum axis) {
|
||||
|
||||
void Stepper::report_a_position(const xyz_long_t &pos) {
|
||||
SERIAL_ECHOLNPGM_P(
|
||||
LIST_N(DOUBLE(LINEAR_AXES),
|
||||
LIST_N(DOUBLE(NUM_AXES),
|
||||
TERN(SAYS_A, PSTR(STR_COUNT_A), PSTR(STR_COUNT_X)), pos.x,
|
||||
TERN(SAYS_B, PSTR("B:"), SP_Y_LBL), pos.y,
|
||||
TERN(SAYS_C, PSTR("C:"), SP_Z_LBL), pos.z,
|
||||
SP_I_LBL, pos.i,
|
||||
SP_J_LBL, pos.j,
|
||||
SP_K_LBL, pos.k
|
||||
SP_K_LBL, pos.k,
|
||||
SP_U_LBL, pos.u,
|
||||
SP_V_LBL, pos.v,
|
||||
SP_W_LBL, pos.w
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -3096,16 +3189,18 @@ void Stepper::report_positions() {
|
||||
|
||||
const bool z_direction = direction ^ BABYSTEP_INVERT_Z;
|
||||
|
||||
LINEAR_AXIS_CODE(
|
||||
NUM_AXIS_CODE(
|
||||
enable_axis(X_AXIS), enable_axis(Y_AXIS), enable_axis(Z_AXIS),
|
||||
enable_axis(I_AXIS), enable_axis(J_AXIS), enable_axis(K_AXIS)
|
||||
enable_axis(I_AXIS), enable_axis(J_AXIS), enable_axis(K_AXIS),
|
||||
enable_axis(U_AXIS), enable_axis(V_AXIS), enable_axis(W_AXIS)
|
||||
);
|
||||
|
||||
DIR_WAIT_BEFORE();
|
||||
|
||||
const xyz_byte_t old_dir = LINEAR_AXIS_ARRAY(
|
||||
const xyz_byte_t old_dir = NUM_AXIS_ARRAY(
|
||||
X_DIR_READ(), Y_DIR_READ(), Z_DIR_READ(),
|
||||
I_DIR_READ(), J_DIR_READ(), K_DIR_READ()
|
||||
I_DIR_READ(), J_DIR_READ(), K_DIR_READ(),
|
||||
U_DIR_READ(), V_DIR_READ(), W_DIR_READ()
|
||||
);
|
||||
|
||||
X_DIR_WRITE(ENABLED(INVERT_X_DIR) ^ z_direction);
|
||||
@ -3124,6 +3219,15 @@ void Stepper::report_positions() {
|
||||
#ifdef K_DIR_WRITE
|
||||
K_DIR_WRITE(ENABLED(INVERT_K_DIR) ^ z_direction);
|
||||
#endif
|
||||
#ifdef U_DIR_WRITE
|
||||
U_DIR_WRITE(ENABLED(INVERT_U_DIR) ^ z_direction);
|
||||
#endif
|
||||
#ifdef V_DIR_WRITE
|
||||
V_DIR_WRITE(ENABLED(INVERT_V_DIR) ^ z_direction);
|
||||
#endif
|
||||
#ifdef W_DIR_WRITE
|
||||
W_DIR_WRITE(ENABLED(INVERT_W_DIR) ^ z_direction);
|
||||
#endif
|
||||
|
||||
DIR_WAIT_AFTER();
|
||||
|
||||
@ -3145,6 +3249,15 @@ void Stepper::report_positions() {
|
||||
#ifdef K_STEP_WRITE
|
||||
K_STEP_WRITE(!INVERT_K_STEP_PIN);
|
||||
#endif
|
||||
#ifdef U_STEP_WRITE
|
||||
U_STEP_WRITE(!INVERT_U_STEP_PIN);
|
||||
#endif
|
||||
#ifdef V_STEP_WRITE
|
||||
V_STEP_WRITE(!INVERT_V_STEP_PIN);
|
||||
#endif
|
||||
#ifdef W_STEP_WRITE
|
||||
W_STEP_WRITE(!INVERT_W_STEP_PIN);
|
||||
#endif
|
||||
|
||||
_PULSE_WAIT();
|
||||
|
||||
@ -3164,6 +3277,15 @@ void Stepper::report_positions() {
|
||||
#ifdef K_STEP_WRITE
|
||||
K_STEP_WRITE(INVERT_K_STEP_PIN);
|
||||
#endif
|
||||
#ifdef U_STEP_WRITE
|
||||
U_STEP_WRITE(INVERT_U_STEP_PIN);
|
||||
#endif
|
||||
#ifdef V_STEP_WRITE
|
||||
V_STEP_WRITE(INVERT_V_STEP_PIN);
|
||||
#endif
|
||||
#ifdef W_STEP_WRITE
|
||||
W_STEP_WRITE(INVERT_W_STEP_PIN);
|
||||
#endif
|
||||
|
||||
// Restore direction bits
|
||||
EXTRA_DIR_WAIT_BEFORE();
|
||||
@ -3184,6 +3306,15 @@ void Stepper::report_positions() {
|
||||
#ifdef K_DIR_WRITE
|
||||
K_DIR_WRITE(old_dir.k);
|
||||
#endif
|
||||
#ifdef U_DIR_WRITE
|
||||
U_DIR_WRITE(old_dir.u);
|
||||
#endif
|
||||
#ifdef V_DIR_WRITE
|
||||
V_DIR_WRITE(old_dir.v);
|
||||
#endif
|
||||
#ifdef W_DIR_WRITE
|
||||
W_DIR_WRITE(old_dir.w);
|
||||
#endif
|
||||
|
||||
EXTRA_DIR_WAIT_AFTER();
|
||||
|
||||
@ -3200,6 +3331,15 @@ void Stepper::report_positions() {
|
||||
#if HAS_K_AXIS
|
||||
case K_AXIS: BABYSTEP_AXIS(K, 0, direction); break;
|
||||
#endif
|
||||
#if HAS_U_AXIS
|
||||
case U_AXIS: BABYSTEP_AXIS(U, 0, direction); break;
|
||||
#endif
|
||||
#if HAS_V_AXIS
|
||||
case V_AXIS: BABYSTEP_AXIS(V, 0, direction); break;
|
||||
#endif
|
||||
#if HAS_W_AXIS
|
||||
case W_AXIS: BABYSTEP_AXIS(W, 0, direction); break;
|
||||
#endif
|
||||
|
||||
default: break;
|
||||
}
|
||||
@ -3428,6 +3568,24 @@ void Stepper::report_positions() {
|
||||
SET_OUTPUT(K_MS3_PIN);
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_U_MS_PINS
|
||||
SET_OUTPUT(U_MS1_PIN); SET_OUTPUT(U_MS2_PIN);
|
||||
#if PIN_EXISTS(U_MS3)
|
||||
SET_OUTPUT(U_MS3_PIN);
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_V_MS_PINS
|
||||
SET_OUTPUT(V_MS1_PIN); SET_OUTPUT(V_MS2_PIN);
|
||||
#if PIN_EXISTS(V_MS3)
|
||||
SET_OUTPUT(V_MS3_PIN);
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_W_MS_PINS
|
||||
SET_OUTPUT(W_MS1_PIN); SET_OUTPUT(W_MS2_PIN);
|
||||
#if PIN_EXISTS(W_MS3)
|
||||
SET_OUTPUT(W_MS3_PIN);
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_E0_MS_PINS
|
||||
SET_OUTPUT(E0_MS1_PIN); SET_OUTPUT(E0_MS2_PIN);
|
||||
#if PIN_EXISTS(E0_MS3)
|
||||
@ -3553,6 +3711,15 @@ void Stepper::report_positions() {
|
||||
#if HAS_K_MS_PINS
|
||||
case 13: WRITE(K_MS1_PIN, ms1); break
|
||||
#endif
|
||||
#if HAS_U_MS_PINS
|
||||
case 14: WRITE(U_MS1_PIN, ms1); break
|
||||
#endif
|
||||
#if HAS_V_MS_PINS
|
||||
case 15: WRITE(V_MS1_PIN, ms1); break
|
||||
#endif
|
||||
#if HAS_W_MS_PINS
|
||||
case 16: WRITE(W_MS1_PIN, ms1); break
|
||||
#endif
|
||||
}
|
||||
if (ms2 >= 0) switch (driver) {
|
||||
#if HAS_X_MS_PINS || HAS_X2_MS_PINS
|
||||
@ -3624,6 +3791,15 @@ void Stepper::report_positions() {
|
||||
#if HAS_K_MS_PINS
|
||||
case 13: WRITE(K_MS2_PIN, ms2); break
|
||||
#endif
|
||||
#if HAS_U_MS_PINS
|
||||
case 14: WRITE(U_MS2_PIN, ms2); break
|
||||
#endif
|
||||
#if HAS_V_MS_PINS
|
||||
case 15: WRITE(V_MS2_PIN, ms2); break
|
||||
#endif
|
||||
#if HAS_W_MS_PINS
|
||||
case 16: WRITE(W_MS2_PIN, ms2); break
|
||||
#endif
|
||||
}
|
||||
if (ms3 >= 0) switch (driver) {
|
||||
#if HAS_X_MS_PINS || HAS_X2_MS_PINS
|
||||
@ -3760,6 +3936,24 @@ void Stepper::report_positions() {
|
||||
PIN_CHAR(K_MS3);
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_U_MS_PINS
|
||||
MS_LINE(U);
|
||||
#if PIN_EXISTS(U_MS3)
|
||||
PIN_CHAR(U_MS3);
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_V_MS_PINS
|
||||
MS_LINE(V);
|
||||
#if PIN_EXISTS(V_MS3)
|
||||
PIN_CHAR(V_MS3);
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_W_MS_PINS
|
||||
MS_LINE(W);
|
||||
#if PIN_EXISTS(W_MS3)
|
||||
PIN_CHAR(W_MS3);
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_E0_MS_PINS
|
||||
MS_LINE(E0);
|
||||
#if PIN_EXISTS(E0_MS3)
|
||||
|
@ -159,12 +159,21 @@
|
||||
#if HAS_K_STEP
|
||||
#define ISR_K_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#endif
|
||||
#if HAS_U_STEP
|
||||
#define ISR_U_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#endif
|
||||
#if HAS_V_STEP
|
||||
#define ISR_V_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#endif
|
||||
#if HAS_W_STEP
|
||||
#define ISR_W_STEPPER_CYCLES ISR_STEPPER_CYCLES
|
||||
#endif
|
||||
#if HAS_EXTRUDERS
|
||||
#define ISR_E_STEPPER_CYCLES ISR_STEPPER_CYCLES // E is always interpolated, even for mixing extruders
|
||||
#endif
|
||||
|
||||
// And the total minimum loop time, not including the base
|
||||
#define MIN_ISR_LOOP_CYCLES (ISR_MIXING_STEPPER_CYCLES LOGICAL_AXIS_GANG(+ ISR_E_STEPPER_CYCLES, + ISR_X_STEPPER_CYCLES, + ISR_Y_STEPPER_CYCLES, + ISR_Z_STEPPER_CYCLES, + ISR_I_STEPPER_CYCLES, + ISR_J_STEPPER_CYCLES, + ISR_K_STEPPER_CYCLES))
|
||||
#define MIN_ISR_LOOP_CYCLES (ISR_MIXING_STEPPER_CYCLES LOGICAL_AXIS_GANG(+ ISR_E_STEPPER_CYCLES, + ISR_X_STEPPER_CYCLES, + ISR_Y_STEPPER_CYCLES, + ISR_Z_STEPPER_CYCLES, + ISR_I_STEPPER_CYCLES, + ISR_J_STEPPER_CYCLES, + ISR_K_STEPPER_CYCLES, + ISR_U_STEPPER_CYCLES, + ISR_V_STEPPER_CYCLES, + ISR_W_STEPPER_CYCLES))
|
||||
|
||||
// Calculate the minimum MPU cycles needed per pulse to enforce, limited to the max stepper rate
|
||||
#define _MIN_STEPPER_PULSE_CYCLES(N) _MAX(uint32_t((F_CPU) / (MAXIMUM_STEPPER_RATE)), ((F_CPU) / 500000UL) * (N))
|
||||
@ -236,7 +245,7 @@
|
||||
// Perhaps DISABLE_MULTI_STEPPING should be required with ADAPTIVE_STEP_SMOOTHING.
|
||||
#define MIN_STEP_ISR_FREQUENCY (MAX_STEP_ISR_FREQUENCY_1X / 2)
|
||||
|
||||
#define ENABLE_COUNT (LINEAR_AXES + E_STEPPERS)
|
||||
#define ENABLE_COUNT (NUM_AXES + E_STEPPERS)
|
||||
typedef IF<(ENABLE_COUNT > 8), uint16_t, uint8_t>::type ena_mask_t;
|
||||
|
||||
// Axis flags type, for enabled state or other simple state
|
||||
@ -244,25 +253,25 @@ typedef struct {
|
||||
union {
|
||||
ena_mask_t bits;
|
||||
struct {
|
||||
bool LINEAR_AXIS_LIST(X:1, Y:1, Z:1, I:1, J:1, K:1);
|
||||
bool NUM_AXIS_LIST(X:1, Y:1, Z:1, I:1, J:1, K:1, U:1, V:1, W:1);
|
||||
#if HAS_EXTRUDERS
|
||||
bool LIST_N(EXTRUDERS, E0:1, E1:1, E2:1, E3:1, E4:1, E5:1, E6:1, E7:1);
|
||||
#endif
|
||||
};
|
||||
};
|
||||
constexpr ena_mask_t linear_bits() { return _BV(LINEAR_AXES) - 1; }
|
||||
constexpr ena_mask_t e_bits() { return (_BV(EXTRUDERS) - 1) << LINEAR_AXES; }
|
||||
constexpr ena_mask_t linear_bits() { return _BV(NUM_AXES) - 1; }
|
||||
constexpr ena_mask_t e_bits() { return (_BV(EXTRUDERS) - 1) << NUM_AXES; }
|
||||
} stepper_flags_t;
|
||||
|
||||
// All the stepper enable pins
|
||||
constexpr pin_t ena_pins[] = {
|
||||
LINEAR_AXIS_LIST(X_ENABLE_PIN, Y_ENABLE_PIN, Z_ENABLE_PIN, I_ENABLE_PIN, J_ENABLE_PIN, K_ENABLE_PIN),
|
||||
NUM_AXIS_LIST(X_ENABLE_PIN, Y_ENABLE_PIN, Z_ENABLE_PIN, I_ENABLE_PIN, J_ENABLE_PIN, K_ENABLE_PIN, U_ENABLE_PIN, V_ENABLE_PIN, W_ENABLE_PIN),
|
||||
LIST_N(E_STEPPERS, E0_ENABLE_PIN, E1_ENABLE_PIN, E2_ENABLE_PIN, E3_ENABLE_PIN, E4_ENABLE_PIN, E5_ENABLE_PIN, E6_ENABLE_PIN, E7_ENABLE_PIN)
|
||||
};
|
||||
|
||||
// Index of the axis or extruder element in a combined array
|
||||
constexpr uint8_t index_of_axis(const AxisEnum axis E_OPTARG(const uint8_t eindex=0)) {
|
||||
return uint8_t(axis) + (E_TERN0(axis < LINEAR_AXES ? 0 : eindex));
|
||||
return uint8_t(axis) + (E_TERN0(axis < NUM_AXES ? 0 : eindex));
|
||||
}
|
||||
//#define __IAX_N(N,V...) _IAX_##N(V)
|
||||
//#define _IAX_N(N,V...) __IAX_N(N,V)
|
||||
@ -292,7 +301,7 @@ constexpr bool any_enable_overlap(const uint8_t a=0) {
|
||||
// (e.g., CoreXY, Dual XYZ, or E with multiple steppers, etc.).
|
||||
constexpr ena_mask_t enable_overlap[] = {
|
||||
#define _OVERLAP(N) ena_overlap(INDEX_OF_AXIS(AxisEnum(N))),
|
||||
REPEAT(LINEAR_AXES, _OVERLAP)
|
||||
REPEAT(NUM_AXES, _OVERLAP)
|
||||
#if HAS_EXTRUDERS
|
||||
#define _E_OVERLAP(N) ena_overlap(INDEX_OF_AXIS(E_AXIS, N)),
|
||||
REPEAT(E_STEPPERS, _E_OVERLAP)
|
||||
@ -320,7 +329,7 @@ class Stepper {
|
||||
#ifndef MOTOR_CURRENT_PWM_FREQUENCY
|
||||
#define MOTOR_CURRENT_PWM_FREQUENCY 31400
|
||||
#endif
|
||||
#define MOTOR_CURRENT_COUNT LINEAR_AXES
|
||||
#define MOTOR_CURRENT_COUNT NUM_AXES
|
||||
#elif HAS_MOTOR_CURRENT_SPI
|
||||
static constexpr uint32_t digipot_count[] = DIGIPOT_MOTOR_CURRENT;
|
||||
#define MOTOR_CURRENT_COUNT COUNT(Stepper::digipot_count)
|
||||
|
@ -64,6 +64,15 @@
|
||||
#if AXIS_IS_L64XX(K)
|
||||
L64XX_CLASS(K) stepperK(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(U)
|
||||
L64XX_CLASS(u) stepperU(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(V)
|
||||
L64XX_CLASS(v) stepperV(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(W)
|
||||
L64XX_CLASS(w) stepperW(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(E0)
|
||||
L64XX_CLASS(E0) stepperE0(L6470_CHAIN_SS_PIN);
|
||||
#endif
|
||||
@ -217,6 +226,15 @@ void L64XX_Marlin::init_to_defaults() {
|
||||
#if AXIS_IS_L64XX(K)
|
||||
L6470_INIT_CHIP(K);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(U)
|
||||
L6470_INIT_CHIP(U);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(V)
|
||||
L6470_INIT_CHIP(V);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(W)
|
||||
L6470_INIT_CHIP(W);
|
||||
#endif
|
||||
#if AXIS_IS_L64XX(E0)
|
||||
L6470_INIT_CHIP(E0);
|
||||
#endif
|
||||
|
@ -266,6 +266,72 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// U Stepper
|
||||
#if HAS_U_AXIS
|
||||
#if AXIS_IS_L64XX(U)
|
||||
extern L64XX_CLASS(U) stepperU;
|
||||
#define U_ENABLE_INIT() NOOP
|
||||
#define U_ENABLE_WRITE(STATE) (STATE ? stepperU.hardStop() : stepperU.free())
|
||||
#define U_ENABLE_READ() (stepperU.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_U(L6474)
|
||||
#define U_DIR_INIT() SET_OUTPUT(U_DIR_PIN)
|
||||
#define U_DIR_WRITE(STATE) L6474_DIR_WRITE(U, STATE)
|
||||
#define U_DIR_READ() READ(U_DIR_PIN)
|
||||
#else
|
||||
#define U_DIR_INIT() NOOP
|
||||
#define U_DIR_WRITE(STATE) L64XX_DIR_WRITE(U, STATE)
|
||||
#define U_DIR_READ() (stepper##U.getStatus() & STATUS_DIR);
|
||||
#if AXIS_DRIVER_TYPE_U(L6470)
|
||||
#define DISABLE_STEPPER_U() stepperU.free()
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// V Stepper
|
||||
#if HAS_V_AXIS
|
||||
#if AXIS_IS_L64XX(V)
|
||||
extern L64XX_CLASS(V) stepperV;
|
||||
#define V_ENABLE_INIT() NOOP
|
||||
#define V_ENABLE_WRITE(STATE) (STATE ? stepperV.hardStop() : stepperV.free())
|
||||
#define V_ENABLE_READ() (stepperV.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_V(L6474)
|
||||
#define V_DIR_INIT() SET_OUTPUT(V_DIR_PIN)
|
||||
#define V_DIR_WRITE(STATE) L6474_DIR_WRITE(V, STATE)
|
||||
#define V_DIR_READ() READ(V_DIR_PIN)
|
||||
#else
|
||||
#define V_DIR_INIT() NOOP
|
||||
#define V_DIR_WRITE(STATE) L64XX_DIR_WRITE(V, STATE)
|
||||
#define V_DIR_READ() (stepper##V.getStatus() & STATUS_DIR);
|
||||
#if AXIS_DRIVER_TYPE_V(L6470)
|
||||
#define DISABLE_STEPPER_V() stepperV.free()
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// W Stepper
|
||||
#if HAS_W_AXIS
|
||||
#if AXIS_IS_L64XX(W)
|
||||
extern L64XX_CLASS(w) stepperW;
|
||||
#define W_ENABLE_INIT() NOOP
|
||||
#define W_ENABLE_WRITE(STATE) (STATE ? stepperW.hardStop() : stepperW.free())
|
||||
#define W_ENABLE_READ() (stepperW.getStatus() & STATUS_HIZ)
|
||||
#if AXIS_DRIVER_TYPE_W(L6474)
|
||||
#define W_DIR_INIT() SET_OUTPUT(W_DIR_PIN)
|
||||
#define W_DIR_WRITE(STATE) L6474_DIR_WRITE(W, STATE)
|
||||
#define W_DIR_READ() READ(W_DIR_PIN)
|
||||
#else
|
||||
#define W_DIR_INIT() NOOP
|
||||
#define W_DIR_WRITE(STATE) L64XX_DIR_WRITE(W, STATE)
|
||||
#define W_DIR_READ() (stepper##W.getStatus() & STATUS_DIR);
|
||||
#if AXIS_DRIVER_TYPE_W(L6470)
|
||||
#define DISABLE_STEPPER_W() stepperW.free()
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// E0 Stepper
|
||||
#if AXIS_IS_L64XX(E0)
|
||||
extern L64XX_CLASS(E0) stepperE0;
|
||||
|
@ -69,6 +69,15 @@
|
||||
#if AXIS_DRIVER_TYPE_K(TMC26X)
|
||||
_TMC26X_DEFINE(K);
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE_U(TMC26X)
|
||||
_TMC26X_DEFINE(U);
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE_V(TMC26X)
|
||||
_TMC26X_DEFINE(V);
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE_W(TMC26X)
|
||||
_TMC26X_DEFINE(W);
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE_E0(TMC26X)
|
||||
_TMC26X_DEFINE(E0);
|
||||
#endif
|
||||
@ -133,6 +142,15 @@ void tmc26x_init_to_defaults() {
|
||||
#if AXIS_DRIVER_TYPE_K(TMC26X)
|
||||
_TMC26X_INIT(K);
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE_U(TMC26X)
|
||||
_TMC26X_INIT(U);
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE_V(TMC26X)
|
||||
_TMC26X_INIT(V);
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE_W(TMC26X)
|
||||
_TMC26X_INIT(W);
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE_E0(TMC26X)
|
||||
_TMC26X_INIT(E0);
|
||||
#endif
|
||||
|
@ -123,6 +123,30 @@ void tmc26x_init_to_defaults();
|
||||
#define K_ENABLE_READ() stepperK.isEnabled()
|
||||
#endif
|
||||
|
||||
// U Stepper
|
||||
#if HAS_U_ENABLE && AXIS_DRIVER_TYPE_U(TMC26X)
|
||||
extern TMC26XStepper stepperU;
|
||||
#define U_ENABLE_INIT() NOOP
|
||||
#define U_ENABLE_WRITE(STATE) stepperU.setEnabled(STATE)
|
||||
#define U_ENABLE_READ() stepperU.isEnabled()
|
||||
#endif
|
||||
|
||||
// V Stepper
|
||||
#if HAS_V_ENABLE && AXIS_DRIVER_TYPE_V(TMC26X)
|
||||
extern TMC26XStepper stepperV;
|
||||
#define V_ENABLE_INIT() NOOP
|
||||
#define V_ENABLE_WRITE(STATE) stepperV.setEnabled(STATE)
|
||||
#define V_ENABLE_READ() stepperV.isEnabled()
|
||||
#endif
|
||||
|
||||
// W Stepper
|
||||
#if HAS_W_ENABLE && AXIS_DRIVER_TYPE_W(TMC26X)
|
||||
extern TMC26XStepper stepperW;
|
||||
#define W_ENABLE_INIT() NOOP
|
||||
#define W_ENABLE_WRITE(STATE) stepperW.setEnabled(STATE)
|
||||
#define W_ENABLE_READ() stepperW.isEnabled()
|
||||
#endif
|
||||
|
||||
// E0 Stepper
|
||||
#if AXIS_DRIVER_TYPE_E0(TMC26X)
|
||||
extern TMC26XStepper stepperE0;
|
||||
|
@ -262,6 +262,63 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
|
||||
#define K_STEP_READ() bool(READ(K_STEP_PIN))
|
||||
#endif
|
||||
|
||||
// U Stepper
|
||||
#if HAS_U_AXIS
|
||||
#ifndef U_ENABLE_INIT
|
||||
#define U_ENABLE_INIT() SET_OUTPUT(U_ENABLE_PIN)
|
||||
#define U_ENABLE_WRITE(STATE) WRITE(U_ENABLE_PIN,STATE)
|
||||
#define U_ENABLE_READ() bool(READ(U_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef U_DIR_INIT
|
||||
#define U_DIR_INIT() SET_OUTPUT(U_DIR_PIN)
|
||||
#define U_DIR_WRITE(STATE) WRITE(U_DIR_PIN,STATE)
|
||||
#define U_DIR_READ() bool(READ(U_DIR_PIN))
|
||||
#endif
|
||||
#define U_STEP_INIT() SET_OUTPUT(U_STEP_PIN)
|
||||
#ifndef U_STEP_WRITE
|
||||
#define U_STEP_WRITE(STATE) WRITE(U_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define U_STEP_READ() bool(READ(U_STEP_PIN))
|
||||
#endif
|
||||
|
||||
// V Stepper
|
||||
#if HAS_V_AXIS
|
||||
#ifndef V_ENABLE_INIT
|
||||
#define V_ENABLE_INIT() SET_OUTPUT(V_ENABLE_PIN)
|
||||
#define V_ENABLE_WRITE(STATE) WRITE(V_ENABLE_PIN,STATE)
|
||||
#define V_ENABLE_READ() bool(READ(V_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef V_DIR_INIT
|
||||
#define V_DIR_INIT() SET_OUTPUT(V_DIR_PIN)
|
||||
#define V_DIR_WRITE(STATE) WRITE(V_DIR_PIN,STATE)
|
||||
#define V_DIR_READ() bool(READ(V_DIR_PIN))
|
||||
#endif
|
||||
#define V_STEP_INIT() SET_OUTPUT(V_STEP_PIN)
|
||||
#ifndef V_STEP_WRITE
|
||||
#define V_STEP_WRITE(STATE) WRITE(V_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define V_STEP_READ() bool(READ(V_STEP_PIN))
|
||||
#endif
|
||||
|
||||
// W Stepper
|
||||
#if HAS_W_AXIS
|
||||
#ifndef W_ENABLE_INIT
|
||||
#define W_ENABLE_INIT() SET_OUTPUT(W_ENABLE_PIN)
|
||||
#define W_ENABLE_WRITE(STATE) WRITE(W_ENABLE_PIN,STATE)
|
||||
#define W_ENABLE_READ() bool(READ(W_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef W_DIR_INIT
|
||||
#define W_DIR_INIT() SET_OUTPUT(W_DIR_PIN)
|
||||
#define W_DIR_WRITE(STATE) WRITE(W_DIR_PIN,STATE)
|
||||
#define W_DIR_READ() bool(READ(W_DIR_PIN))
|
||||
#endif
|
||||
#define W_STEP_INIT() SET_OUTPUT(W_STEP_PIN)
|
||||
#ifndef W_STEP_WRITE
|
||||
#define W_STEP_WRITE(STATE) WRITE(W_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define W_STEP_READ() bool(READ(W_STEP_PIN))
|
||||
#endif
|
||||
|
||||
// E0 Stepper
|
||||
#ifndef E0_ENABLE_INIT
|
||||
#define E0_ENABLE_INIT() SET_OUTPUT(E0_ENABLE_PIN)
|
||||
@ -743,6 +800,51 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
|
||||
#define DISABLE_STEPPER_K() TERN(HAS_K_ENABLE, K_ENABLE_WRITE(!K_ENABLE_ON), NOOP)
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_U
|
||||
#if HAS_U_ENABLE
|
||||
#define ENABLE_STEPPER_U() U_ENABLE_WRITE( U_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_U() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_U
|
||||
#if HAS_U_ENABLE
|
||||
#define DISABLE_STEPPER_U() U_ENABLE_WRITE(!U_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_U() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_V
|
||||
#if HAS_V_ENABLE
|
||||
#define ENABLE_STEPPER_V() V_ENABLE_WRITE( V_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_V() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_V
|
||||
#if HAS_V_ENABLE
|
||||
#define DISABLE_STEPPER_V() V_ENABLE_WRITE(!V_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_V() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_W
|
||||
#if HAS_W_ENABLE
|
||||
#define ENABLE_STEPPER_W() W_ENABLE_WRITE( W_ENABLE_ON)
|
||||
#else
|
||||
#define ENABLE_STEPPER_W() NOOP
|
||||
#endif
|
||||
#endif
|
||||
#ifndef DISABLE_STEPPER_W
|
||||
#if HAS_W_ENABLE
|
||||
#define DISABLE_STEPPER_W() W_ENABLE_WRITE(!W_ENABLE_ON)
|
||||
#else
|
||||
#define DISABLE_STEPPER_W() NOOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_STEPPER_E0
|
||||
#define ENABLE_STEPPER_E0() TERN(HAS_E0_ENABLE, E0_ENABLE_WRITE( E_ENABLE_ON), NOOP)
|
||||
#endif
|
||||
@ -917,6 +1019,28 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
|
||||
#define DISABLE_AXIS_K() NOOP
|
||||
#endif
|
||||
|
||||
#if HAS_U_AXIS
|
||||
#define ENABLE_AXIS_U() if (SHOULD_ENABLE(u)) { ENABLE_STEPPER_U(); AFTER_CHANGE(u, true); }
|
||||
#define DISABLE_AXIS_U() if (SHOULD_DISABLE(u)) { DISABLE_STEPPER_U(); AFTER_CHANGE(u, false); set_axis_untrusted(U_AXIS); }
|
||||
#else
|
||||
#define ENABLE_AXIS_U() NOOP
|
||||
#define DISABLE_AXIS_U() NOOP
|
||||
#endif
|
||||
#if HAS_V_AXIS
|
||||
#define ENABLE_AXIS_V() if (SHOULD_ENABLE(v)) { ENABLE_STEPPER_V(); AFTER_CHANGE(v, true); }
|
||||
#define DISABLE_AXIS_V() if (SHOULD_DISABLE(v)) { DISABLE_STEPPER_V(); AFTER_CHANGE(v, false); set_axis_untrusted(V_AXIS); }
|
||||
#else
|
||||
#define ENABLE_AXIS_V() NOOP
|
||||
#define DISABLE_AXIS_V() NOOP
|
||||
#endif
|
||||
#if HAS_W_AXIS
|
||||
#define ENABLE_AXIS_W() if (SHOULD_ENABLE(w)) { ENABLE_STEPPER_W(); AFTER_CHANGE(w, true); }
|
||||
#define DISABLE_AXIS_W() if (SHOULD_DISABLE(w)) { DISABLE_STEPPER_W(); AFTER_CHANGE(w, false); set_axis_untrusted(W_AXIS); }
|
||||
#else
|
||||
#define ENABLE_AXIS_W() NOOP
|
||||
#define DISABLE_AXIS_W() NOOP
|
||||
#endif
|
||||
|
||||
//
|
||||
// Extruder steppers enable / disable macros
|
||||
//
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include <SPI.h>
|
||||
|
||||
enum StealthIndex : uint8_t {
|
||||
LOGICAL_AXIS_LIST(STEALTH_AXIS_E, STEALTH_AXIS_X, STEALTH_AXIS_Y, STEALTH_AXIS_Z, STEALTH_AXIS_I, STEALTH_AXIS_J, STEALTH_AXIS_K)
|
||||
LOGICAL_AXIS_LIST(STEALTH_AXIS_E, STEALTH_AXIS_X, STEALTH_AXIS_Y, STEALTH_AXIS_Z, STEALTH_AXIS_I, STEALTH_AXIS_J, STEALTH_AXIS_K, STEALTH_AXIS_U, STEALTH_AXIS_V, STEALTH_AXIS_W)
|
||||
};
|
||||
#define TMC_INIT(ST, STEALTH_INDEX) tmc_init(stepper##ST, ST##_CURRENT, ST##_MICROSTEPS, ST##_HYBRID_THRESHOLD, stealthchop_by_axis[STEALTH_INDEX], chopper_timing_##ST, ST##_INTERPOLATE, ST##_HOLD_MULTIPLIER)
|
||||
|
||||
@ -106,6 +106,15 @@ enum StealthIndex : uint8_t {
|
||||
#if AXIS_HAS_SPI(K)
|
||||
TMC_SPI_DEFINE(K, K);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(U)
|
||||
TMC_SPI_DEFINE(U, U);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(V)
|
||||
TMC_SPI_DEFINE(V, V);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(W)
|
||||
TMC_SPI_DEFINE(W, W);
|
||||
#endif
|
||||
#if AXIS_HAS_SPI(E0)
|
||||
TMC_SPI_DEFINE_E(0);
|
||||
#endif
|
||||
@ -173,6 +182,15 @@ enum StealthIndex : uint8_t {
|
||||
#ifndef TMC_K_BAUD_RATE
|
||||
#define TMC_K_BAUD_RATE TMC_BAUD_RATE
|
||||
#endif
|
||||
#ifndef TMC_U_BAUD_RATE
|
||||
#define TMC_U_BAUD_RATE TMC_BAUD_RATE
|
||||
#endif
|
||||
#ifndef TMC_V_BAUD_RATE
|
||||
#define TMC_V_BAUD_RATE TMC_BAUD_RATE
|
||||
#endif
|
||||
#ifndef TMC_W_BAUD_RATE
|
||||
#define TMC_W_BAUD_RATE TMC_BAUD_RATE
|
||||
#endif
|
||||
#ifndef TMC_E0_BAUD_RATE
|
||||
#define TMC_E0_BAUD_RATE TMC_BAUD_RATE
|
||||
#endif
|
||||
@ -374,6 +392,32 @@ enum StealthIndex : uint8_t {
|
||||
#define K_HAS_SW_SERIAL 1
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(U)
|
||||
#ifdef U_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE(HW, U, U);
|
||||
#define U_HAS_HW_SERIAL 1
|
||||
#else
|
||||
TMC_UART_DEFINE(SW, U, U);
|
||||
#define U_HAS_SW_SERIAL 1
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(V)
|
||||
#ifdef V_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE(HW, V, V);
|
||||
#else
|
||||
TMC_UART_DEFINE(SW, V, V);
|
||||
#define V_HAS_SW_SERIAL 1
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(W)
|
||||
#ifdef W_HARDWARE_SERIAL
|
||||
TMC_UART_DEFINE(HW, W, W);
|
||||
#define W_HAS_HW_SERIAL 1
|
||||
#else
|
||||
TMC_UART_DEFINE(SW, W, W);
|
||||
#define W_HAS_SW_SERIAL 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if AXIS_HAS_UART(E0)
|
||||
#ifdef E0_HARDWARE_SERIAL
|
||||
@ -449,7 +493,7 @@ enum StealthIndex : uint8_t {
|
||||
#endif
|
||||
|
||||
#define _EN_ITEM(N) , E##N
|
||||
enum TMCAxis : uint8_t { LINEAR_AXIS_LIST(X, Y, Z, I, J, K), X2, Y2, Z2, Z3, Z4 REPEAT(EXTRUDERS, _EN_ITEM), TOTAL };
|
||||
enum TMCAxis : uint8_t { NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W), X2, Y2, Z2, Z3, Z4 REPEAT(EXTRUDERS, _EN_ITEM), TOTAL };
|
||||
#undef _EN_ITEM
|
||||
|
||||
void tmc_serial_begin() {
|
||||
@ -543,6 +587,27 @@ enum StealthIndex : uint8_t {
|
||||
stepperK.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(U)
|
||||
#ifdef U_HARDWARE_SERIAL
|
||||
HW_SERIAL_BEGIN(U);
|
||||
#else
|
||||
stepperU.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(V)
|
||||
#ifdef V_HARDWARE_SERIAL
|
||||
HW_SERIAL_BEGIN(V);
|
||||
#else
|
||||
stepperV.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(W)
|
||||
#ifdef W_HARDWARE_SERIAL
|
||||
HW_SERIAL_BEGIN(W);
|
||||
#else
|
||||
stepperW.beginSerial(TMC_BAUD_RATE);
|
||||
#endif
|
||||
#endif
|
||||
#if AXIS_HAS_UART(E0)
|
||||
#ifdef E0_HARDWARE_SERIAL
|
||||
HW_SERIAL_BEGIN(E0);
|
||||
@ -814,6 +879,15 @@ void restore_trinamic_drivers() {
|
||||
#if AXIS_IS_TMC(K)
|
||||
stepperK.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(U)
|
||||
stepperU.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(V)
|
||||
stepperV.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(W)
|
||||
stepperW.push();
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E0)
|
||||
stepperE0.push();
|
||||
#endif
|
||||
@ -844,7 +918,8 @@ void reset_trinamic_drivers() {
|
||||
static constexpr bool stealthchop_by_axis[] = LOGICAL_AXIS_ARRAY(
|
||||
ENABLED(STEALTHCHOP_E),
|
||||
ENABLED(STEALTHCHOP_XY), ENABLED(STEALTHCHOP_XY), ENABLED(STEALTHCHOP_Z),
|
||||
ENABLED(STEALTHCHOP_I), ENABLED(STEALTHCHOP_J), ENABLED(STEALTHCHOP_K)
|
||||
ENABLED(STEALTHCHOP_I), ENABLED(STEALTHCHOP_J), ENABLED(STEALTHCHOP_K),
|
||||
ENABLED(STEALTHCHOP_U), ENABLED(STEALTHCHOP_V), ENABLED(STEALTHCHOP_W)
|
||||
);
|
||||
|
||||
#if AXIS_IS_TMC(X)
|
||||
@ -880,6 +955,15 @@ void reset_trinamic_drivers() {
|
||||
#if AXIS_IS_TMC(K)
|
||||
TMC_INIT(K, STEALTH_AXIS_K);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(U)
|
||||
TMC_INIT(U, STEALTH_AXIS_U);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(V)
|
||||
TMC_INIT(V, STEALTH_AXIS_V);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(W)
|
||||
TMC_INIT(W, STEALTH_AXIS_W);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(E0)
|
||||
TMC_INIT(E0, STEALTH_AXIS_E);
|
||||
#endif
|
||||
@ -917,6 +1001,9 @@ void reset_trinamic_drivers() {
|
||||
TERN_(I_SENSORLESS, stepperI.homing_threshold(I_STALL_SENSITIVITY));
|
||||
TERN_(J_SENSORLESS, stepperJ.homing_threshold(J_STALL_SENSITIVITY));
|
||||
TERN_(K_SENSORLESS, stepperK.homing_threshold(K_STALL_SENSITIVITY));
|
||||
TERN_(U_SENSORLESS, stepperU.homing_threshold(U_STALL_SENSITIVITY));
|
||||
TERN_(V_SENSORLESS, stepperV.homing_threshold(V_STALL_SENSITIVITY));
|
||||
TERN_(W_SENSORLESS, stepperW.homing_threshold(W_STALL_SENSITIVITY));
|
||||
#endif
|
||||
|
||||
#ifdef TMC_ADV
|
||||
@ -946,7 +1033,7 @@ void reset_trinamic_drivers() {
|
||||
TMC_HW_DETAIL(X), TMC_HW_DETAIL(X2),
|
||||
TMC_HW_DETAIL(Y), TMC_HW_DETAIL(Y2),
|
||||
TMC_HW_DETAIL(Z), TMC_HW_DETAIL(Z2), TMC_HW_DETAIL(Z3), TMC_HW_DETAIL(Z4),
|
||||
TMC_HW_DETAIL(I), TMC_HW_DETAIL(J), TMC_HW_DETAIL(K),
|
||||
TMC_HW_DETAIL(I), TMC_HW_DETAIL(J), TMC_HW_DETAIL(K), TMC_HW_DETAIL(U), TMC_HW_DETAIL(V), TMC_HW_DETAIL(W),
|
||||
TMC_HW_DETAIL(E0), TMC_HW_DETAIL(E1), TMC_HW_DETAIL(E2), TMC_HW_DETAIL(E3), TMC_HW_DETAIL(E4), TMC_HW_DETAIL(E5), TMC_HW_DETAIL(E6), TMC_HW_DETAIL(E7)
|
||||
};
|
||||
|
||||
@ -969,7 +1056,7 @@ void reset_trinamic_drivers() {
|
||||
SA_NO_TMC_HW_C(X); SA_NO_TMC_HW_C(X2);
|
||||
SA_NO_TMC_HW_C(Y); SA_NO_TMC_HW_C(Y2);
|
||||
SA_NO_TMC_HW_C(Z); SA_NO_TMC_HW_C(Z2); SA_NO_TMC_HW_C(Z3); SA_NO_TMC_HW_C(Z4);
|
||||
SA_NO_TMC_HW_C(I); SA_NO_TMC_HW_C(J); SA_NO_TMC_HW_C(K);
|
||||
SA_NO_TMC_HW_C(I); SA_NO_TMC_HW_C(J); SA_NO_TMC_HW_C(K); SA_NO_TMC_HW_C(U); SA_NO_TMC_HW_C(V); SA_NO_TMC_HW_C(W);
|
||||
SA_NO_TMC_HW_C(E0); SA_NO_TMC_HW_C(E1); SA_NO_TMC_HW_C(E2); SA_NO_TMC_HW_C(E3); SA_NO_TMC_HW_C(E4); SA_NO_TMC_HW_C(E5); SA_NO_TMC_HW_C(E6); SA_NO_TMC_HW_C(E7);
|
||||
#endif
|
||||
|
||||
@ -981,7 +1068,7 @@ void reset_trinamic_drivers() {
|
||||
TMC_SW_DETAIL(X), TMC_SW_DETAIL(X2),
|
||||
TMC_SW_DETAIL(Y), TMC_SW_DETAIL(Y2),
|
||||
TMC_SW_DETAIL(Z), TMC_SW_DETAIL(Z2), TMC_SW_DETAIL(Z3), TMC_SW_DETAIL(Z4),
|
||||
TMC_SW_DETAIL(I), TMC_SW_DETAIL(J), TMC_SW_DETAIL(K),
|
||||
TMC_SW_DETAIL(I), TMC_SW_DETAIL(J), TMC_SW_DETAIL(K), TMC_SW_DETAIL(U), TMC_SW_DETAIL(V), TMC_SW_DETAIL(W),
|
||||
TMC_SW_DETAIL(E0), TMC_SW_DETAIL(E1), TMC_SW_DETAIL(E2), TMC_SW_DETAIL(E3), TMC_SW_DETAIL(E4), TMC_SW_DETAIL(E5), TMC_SW_DETAIL(E6), TMC_SW_DETAIL(E7)
|
||||
};
|
||||
|
||||
@ -999,7 +1086,7 @@ void reset_trinamic_drivers() {
|
||||
SA_NO_TMC_SW_C(X); SA_NO_TMC_SW_C(X2);
|
||||
SA_NO_TMC_SW_C(Y); SA_NO_TMC_SW_C(Y2);
|
||||
SA_NO_TMC_SW_C(Z); SA_NO_TMC_SW_C(Z2); SA_NO_TMC_SW_C(Z3); SA_NO_TMC_SW_C(Z4);
|
||||
SA_NO_TMC_SW_C(I); SA_NO_TMC_SW_C(J); SA_NO_TMC_SW_C(K);
|
||||
SA_NO_TMC_SW_C(I); SA_NO_TMC_SW_C(J); SA_NO_TMC_SW_C(K); SA_NO_TMC_SW_C(U); SA_NO_TMC_SW_C(V); SA_NO_TMC_SW_C(W);
|
||||
SA_NO_TMC_SW_C(E0); SA_NO_TMC_SW_C(E1); SA_NO_TMC_SW_C(E2); SA_NO_TMC_SW_C(E3); SA_NO_TMC_SW_C(E4); SA_NO_TMC_SW_C(E5); SA_NO_TMC_SW_C(E6); SA_NO_TMC_SW_C(E7);
|
||||
#endif
|
||||
|
||||
|
@ -49,6 +49,9 @@
|
||||
#define TMC_I_LABEL 'I', '0'
|
||||
#define TMC_J_LABEL 'J', '0'
|
||||
#define TMC_K_LABEL 'K', '0'
|
||||
#define TMC_U_LABEL 'U', '0'
|
||||
#define TMC_V_LABEL 'V', '0'
|
||||
#define TMC_W_LABEL 'W', '0'
|
||||
|
||||
#define TMC_X2_LABEL 'X', '2'
|
||||
#define TMC_Y2_LABEL 'Y', '2'
|
||||
@ -92,6 +95,15 @@
|
||||
#if HAS_K_AXIS && !defined(CHOPPER_TIMING_K)
|
||||
#define CHOPPER_TIMING_K CHOPPER_TIMING
|
||||
#endif
|
||||
#if HAS_U_AXIS && !defined(CHOPPER_TIMING_U)
|
||||
#define CHOPPER_TIMING_U CHOPPER_TIMING
|
||||
#endif
|
||||
#if HAS_V_AXIS && !defined(CHOPPER_TIMING_V)
|
||||
#define CHOPPER_TIMING_V CHOPPER_TIMING
|
||||
#endif
|
||||
#if HAS_W_AXIS && !defined(CHOPPER_TIMING_W)
|
||||
#define CHOPPER_TIMING_W CHOPPER_TIMING
|
||||
#endif
|
||||
#if HAS_EXTRUDERS && !defined(CHOPPER_TIMING_E)
|
||||
#define CHOPPER_TIMING_E CHOPPER_TIMING
|
||||
#endif
|
||||
@ -274,6 +286,48 @@ void reset_trinamic_drivers();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// U Stepper
|
||||
#if AXIS_IS_TMC(U)
|
||||
extern TMC_CLASS(U, U) stepperU;
|
||||
static constexpr chopper_timing_t chopper_timing_U = CHOPPER_TIMING_U;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
|
||||
#define U_ENABLE_INIT() NOOP
|
||||
#define U_ENABLE_WRITE(STATE) stepperU.toff((STATE)==U_ENABLE_ON ? chopper_timing_U.toff : 0)
|
||||
#define U_ENABLE_READ() stepperU.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(U)
|
||||
#define U_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(U_STEP_PIN); }while(0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// V Stepper
|
||||
#if AXIS_IS_TMC(V)
|
||||
extern TMC_CLASS(V, V) stepperV;
|
||||
static constexpr chopper_timing_t chopper_timing_V = CHOPPER_TIMING_V;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
|
||||
#define V_ENABLE_INIT() NOOP
|
||||
#define V_ENABLE_WRITE(STATE) stepperV.toff((STATE)==V_ENABLE_ON ? chopper_timing_V.toff : 0)
|
||||
#define V_ENABLE_READ() stepperV.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(V)
|
||||
#define V_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(V_STEP_PIN); }while(0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// W Stepper
|
||||
#if AXIS_IS_TMC(W)
|
||||
extern TMC_CLASS(W, W) stepperW;
|
||||
static constexpr chopper_timing_t chopper_timing_W = CHOPPER_TIMING_W;
|
||||
#if ENABLED(SOFTWARE_DRIVER_ENABLE)
|
||||
#define W_ENABLE_INIT() NOOP
|
||||
#define W_ENABLE_WRITE(STATE) stepperW.toff((STATE)==W_ENABLE_ON ? chopper_timing_W.toff : 0)
|
||||
#define W_ENABLE_READ() stepperW.isEnabled()
|
||||
#endif
|
||||
#if AXIS_HAS_SQUARE_WAVE(W)
|
||||
#define W_STEP_WRITE(STATE) do{ if(STATE) TOGGLE(W_STEP_PIN); }while(0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// E0 Stepper
|
||||
#if AXIS_IS_TMC(E0)
|
||||
extern TMC_CLASS_E(0) stepperE0;
|
||||
|
@ -1052,6 +1052,16 @@ void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.
|
||||
if (ok) {
|
||||
IF_DISABLED(TOOLCHANGE_PARK_Y_ONLY, current_position.x = toolchange_settings.change_point.x);
|
||||
IF_DISABLED(TOOLCHANGE_PARK_X_ONLY, current_position.y = toolchange_settings.change_point.y);
|
||||
#if NONE(TOOLCHANGE_PARK_X_ONLY, TOOLCHANGE_PARK_Y_ONLY)
|
||||
SECONDARY_AXIS_CODE(
|
||||
current_position.i = toolchange_settings.change_point.i,
|
||||
current_position.j = toolchange_settings.change_point.j,
|
||||
current_position.k = toolchange_settings.change_point.k,
|
||||
current_position.u = toolchange_settings.change_point.u,
|
||||
current_position.v = toolchange_settings.change_point.v,
|
||||
current_position.w = toolchange_settings.change_point.w
|
||||
);
|
||||
#endif
|
||||
planner.buffer_line(current_position, MMM_TO_MMS(TOOLCHANGE_PARK_XY_FEEDRATE), active_extruder);
|
||||
planner.synchronize();
|
||||
}
|
||||
@ -1227,6 +1237,16 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
|
||||
if (can_move_away && toolchange_settings.enable_park) {
|
||||
IF_DISABLED(TOOLCHANGE_PARK_Y_ONLY, current_position.x = toolchange_settings.change_point.x);
|
||||
IF_DISABLED(TOOLCHANGE_PARK_X_ONLY, current_position.y = toolchange_settings.change_point.y);
|
||||
#if NONE(TOOLCHANGE_PARK_X_ONLY, TOOLCHANGE_PARK_Y_ONLY)
|
||||
SECONDARY_AXIS_CODE(
|
||||
current_position.i = toolchange_settings.change_point.i,
|
||||
current_position.j = toolchange_settings.change_point.j,
|
||||
current_position.k = toolchange_settings.change_point.k,
|
||||
current_position.u = toolchange_settings.change_point.u,
|
||||
current_position.v = toolchange_settings.change_point.v,
|
||||
current_position.w = toolchange_settings.change_point.w
|
||||
);
|
||||
#endif
|
||||
planner.buffer_line(current_position, MMM_TO_MMS(TOOLCHANGE_PARK_XY_FEEDRATE), old_tool);
|
||||
planner.synchronize();
|
||||
}
|
||||
@ -1281,7 +1301,7 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
|
||||
sync_plan_position();
|
||||
|
||||
#if ENABLED(DELTA)
|
||||
//LOOP_LINEAR_AXES(i) update_software_endstops(i); // or modify the constrain function
|
||||
//LOOP_NUM_AXES(i) update_software_endstops(i); // or modify the constrain function
|
||||
const bool safe_to_move = current_position.z < delta_clip_start_height - 1;
|
||||
#else
|
||||
constexpr bool safe_to_move = true;
|
||||
|
@ -40,7 +40,7 @@
|
||||
#endif
|
||||
#if ENABLED(TOOLCHANGE_PARK)
|
||||
bool enable_park; // M217 W
|
||||
xyz_pos_t change_point; // M217 X Y I J K
|
||||
xyz_pos_t change_point; // M217 X Y I J K C H O
|
||||
#endif
|
||||
float z_raise; // M217 Z
|
||||
} toolchange_settings_t;
|
||||
|
Reference in New Issue
Block a user