mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2024-11-27 05:48:43 +00:00
🚸 Optional X-Axis (#25418)
Co-authored-by: alextrical <35117191+alextrical@users.noreply.github.com> Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
parent
3e9848f49c
commit
1f9bfc5c74
@ -324,10 +324,12 @@
|
||||
//
|
||||
// Endstop Names used by Endstops::report_states
|
||||
//
|
||||
#define STR_X_MIN "x_min"
|
||||
#define STR_X_MAX "x_max"
|
||||
#define STR_X2_MIN "x2_min"
|
||||
#define STR_X2_MAX "x2_max"
|
||||
#if HAS_X_AXIS
|
||||
#define STR_X_MIN "x_min"
|
||||
#define STR_X_MAX "x_max"
|
||||
#define STR_X2_MIN "x2_min"
|
||||
#define STR_X2_MAX "x2_max"
|
||||
#endif
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
#define STR_Y_MIN "y_min"
|
||||
|
@ -96,10 +96,12 @@ void print_bin(uint16_t val) {
|
||||
}
|
||||
}
|
||||
|
||||
void print_pos(NUM_AXIS_ARGS(const_float_t), FSTR_P const prefix/*=nullptr*/, FSTR_P const suffix/*=nullptr*/) {
|
||||
void print_pos(NUM_AXIS_ARGS_(const_float_t) FSTR_P const prefix/*=nullptr*/, FSTR_P const suffix/*=nullptr*/) {
|
||||
if (prefix) serial_print(prefix);
|
||||
SERIAL_ECHOPGM_P(
|
||||
LIST_N(DOUBLE(NUM_AXES), SP_X_STR, x, SP_Y_STR, y, SP_Z_STR, z, SP_I_STR, i, SP_J_STR, j, SP_K_STR, k, SP_U_STR, u, SP_V_STR, v, SP_W_STR, w)
|
||||
);
|
||||
#if NUM_AXES
|
||||
SERIAL_ECHOPGM_P(
|
||||
LIST_N(DOUBLE(NUM_AXES), SP_X_STR, x, SP_Y_STR, y, SP_Z_STR, z, SP_I_STR, i, SP_J_STR, j, SP_K_STR, k, SP_U_STR, u, SP_V_STR, v, SP_W_STR, w)
|
||||
);
|
||||
#endif
|
||||
if (suffix) serial_print(suffix); else SERIAL_EOL();
|
||||
}
|
||||
|
@ -340,10 +340,10 @@ void serial_spaces(uint8_t count);
|
||||
void serial_offset(const_float_t v, const uint8_t sp=0); // For v==0 draw space (sp==1) or plus (sp==2)
|
||||
|
||||
void print_bin(const uint16_t val);
|
||||
void print_pos(NUM_AXIS_ARGS(const_float_t), FSTR_P const prefix=nullptr, FSTR_P const suffix=nullptr);
|
||||
void print_pos(NUM_AXIS_ARGS_(const_float_t) FSTR_P const prefix=nullptr, FSTR_P const suffix=nullptr);
|
||||
|
||||
inline void print_pos(const xyze_pos_t &xyze, FSTR_P const prefix=nullptr, FSTR_P const suffix=nullptr) {
|
||||
print_pos(NUM_AXIS_ELEM(xyze), prefix, suffix);
|
||||
print_pos(NUM_AXIS_ELEM_(xyze) prefix, suffix);
|
||||
}
|
||||
|
||||
#define SERIAL_POS(SUFFIX,VAR) do { print_pos(VAR, F(" " STRINGIFY(VAR) "="), F(" : " SUFFIX "\n")); }while(0)
|
||||
|
@ -36,31 +36,47 @@ template <class L, class R> struct IF<true, L, R> { typedef L type; };
|
||||
|
||||
#define ALL_AXIS_NAMES X, X2, Y, Y2, Z, Z2, Z3, Z4, I, J, K, U, V, W, E0, E1, E2, E3, E4, E5, E6, E7
|
||||
|
||||
#define NUM_AXIS_GANG(V...) GANG_N(NUM_AXES, V)
|
||||
#define NUM_AXIS_CODE(V...) CODE_N(NUM_AXES, V)
|
||||
#define NUM_AXIS_LIST(V...) LIST_N(NUM_AXES, V)
|
||||
#define NUM_AXIS_LIST_1(V) LIST_N_1(NUM_AXES, V)
|
||||
#define NUM_AXIS_ARRAY(V...) { NUM_AXIS_LIST(V) }
|
||||
#define NUM_AXIS_ARRAY_1(V) { NUM_AXIS_LIST_1(V) }
|
||||
#define NUM_AXIS_ARGS(T) NUM_AXIS_LIST(T x, T y, T z, T i, T j, T k, T u, T v, T w)
|
||||
#define NUM_AXIS_ELEM(O) NUM_AXIS_LIST(O.x, O.y, O.z, O.i, O.j, O.k, O.u, O.v, O.w)
|
||||
#define NUM_AXIS_DEFS(T,V) NUM_AXIS_LIST(T x=V, T y=V, T z=V, T i=V, T j=V, T k=V, T u=V, T v=V, T w=V)
|
||||
#define MAIN_AXIS_NAMES NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W)
|
||||
#define MAIN_AXIS_MAP(F) MAP(F, MAIN_AXIS_NAMES)
|
||||
#define STR_AXES_MAIN NUM_AXIS_GANG("X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W)
|
||||
#define NUM_AXIS_GANG(V...) GANG_N(NUM_AXES, V)
|
||||
#define NUM_AXIS_CODE(V...) CODE_N(NUM_AXES, V)
|
||||
#define NUM_AXIS_LIST(V...) LIST_N(NUM_AXES, V)
|
||||
#define NUM_AXIS_LIST_1(V) LIST_N_1(NUM_AXES, V)
|
||||
#define NUM_AXIS_ARRAY(V...) { NUM_AXIS_LIST(V) }
|
||||
#define NUM_AXIS_ARRAY_1(V) { NUM_AXIS_LIST_1(V) }
|
||||
#define NUM_AXIS_ARGS(T) NUM_AXIS_LIST(T x, T y, T z, T i, T j, T k, T u, T v, T w)
|
||||
#define NUM_AXIS_ELEM(O) NUM_AXIS_LIST(O.x, O.y, O.z, O.i, O.j, O.k, O.u, O.v, O.w)
|
||||
#define NUM_AXIS_DEFS(T,V) NUM_AXIS_LIST(T x=V, T y=V, T z=V, T i=V, T j=V, T k=V, T u=V, T v=V, T w=V)
|
||||
#define MAIN_AXIS_NAMES NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W)
|
||||
#define STR_AXES_MAIN NUM_AXIS_GANG("X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W)
|
||||
|
||||
#define LOGICAL_AXIS_GANG(E,V...) NUM_AXIS_GANG(V) GANG_ITEM_E(E)
|
||||
#define LOGICAL_AXIS_CODE(E,V...) NUM_AXIS_CODE(V) CODE_ITEM_E(E)
|
||||
#define LOGICAL_AXIS_LIST(E,V...) NUM_AXIS_LIST(V) LIST_ITEM_E(E)
|
||||
#define LOGICAL_AXIS_LIST_1(V) NUM_AXIS_LIST_1(V) LIST_ITEM_E(V)
|
||||
#if NUM_AXES
|
||||
#define NUM_AXES_SEP ,
|
||||
#define MAIN_AXIS_MAP(F) MAP(F, MAIN_AXIS_NAMES)
|
||||
#define OPTARGS_LOGICAL(T) , LOGICAL_AXIS_ARGS(T)
|
||||
#else
|
||||
#define NUM_AXES_SEP
|
||||
#define MAIN_AXIS_MAP(F)
|
||||
#define OPTARGS_LOGICAL(T)
|
||||
#endif
|
||||
|
||||
#define NUM_AXIS_GANG_(V...) NUM_AXIS_GANG(V) NUM_AXES_SEP
|
||||
#define NUM_AXIS_LIST_(V...) NUM_AXIS_LIST(V) NUM_AXES_SEP
|
||||
#define NUM_AXIS_LIST_1_(V...) NUM_AXIS_LIST_1(V) NUM_AXES_SEP
|
||||
#define NUM_AXIS_ARGS_(T) NUM_AXIS_ARGS(T) NUM_AXES_SEP
|
||||
#define NUM_AXIS_ELEM_(T) NUM_AXIS_ELEM(T) NUM_AXES_SEP
|
||||
#define MAIN_AXIS_NAMES_ MAIN_AXIS_NAMES NUM_AXES_SEP
|
||||
|
||||
#define LOGICAL_AXIS_GANG(E,V...) NUM_AXIS_GANG(V) GANG_ITEM_E(E)
|
||||
#define LOGICAL_AXIS_CODE(E,V...) NUM_AXIS_CODE(V) CODE_ITEM_E(E)
|
||||
#define LOGICAL_AXIS_LIST(E,V...) NUM_AXIS_LIST(V) LIST_ITEM_E(E)
|
||||
#define LOGICAL_AXIS_LIST_1(V) NUM_AXIS_LIST_1(V) LIST_ITEM_E(V)
|
||||
#define LOGICAL_AXIS_ARRAY(E,V...) { LOGICAL_AXIS_LIST(E,V) }
|
||||
#define LOGICAL_AXIS_ARRAY_1(V) { LOGICAL_AXIS_LIST_1(V) }
|
||||
#define LOGICAL_AXIS_ARGS(T) LOGICAL_AXIS_LIST(T e, T x, T y, T z, T i, T j, T k, T u, T v, T w)
|
||||
#define LOGICAL_AXIS_ELEM(O) LOGICAL_AXIS_LIST(O.e, O.x, O.y, O.z, O.i, O.j, O.k, O.u, O.v, O.w)
|
||||
#define LOGICAL_AXIS_DECL(T,V) LOGICAL_AXIS_LIST(T e=V, T x=V, T y=V, T z=V, T i=V, T j=V, T k=V, T u=V, T v=V, T w=V)
|
||||
#define LOGICAL_AXIS_NAMES LOGICAL_AXIS_LIST(E, X, Y, Z, I, J, K, U, V, W)
|
||||
#define LOGICAL_AXIS_MAP(F) MAP(F, LOGICAL_AXIS_NAMES)
|
||||
#define STR_AXES_LOGICAL LOGICAL_AXIS_GANG("E", "X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W)
|
||||
#define LOGICAL_AXIS_ARGS(T) LOGICAL_AXIS_LIST(T e, T x, T y, T z, T i, T j, T k, T u, T v, T w)
|
||||
#define LOGICAL_AXIS_ELEM(O) LOGICAL_AXIS_LIST(O.e, O.x, O.y, O.z, O.i, O.j, O.k, O.u, O.v, O.w)
|
||||
#define LOGICAL_AXIS_DECL(T,V) LOGICAL_AXIS_LIST(T e=V, T x=V, T y=V, T z=V, T i=V, T j=V, T k=V, T u=V, T v=V, T w=V)
|
||||
#define LOGICAL_AXIS_NAMES LOGICAL_AXIS_LIST(E, X, Y, Z, I, J, K, U, V, W)
|
||||
#define LOGICAL_AXIS_MAP(F) MAP(F, LOGICAL_AXIS_NAMES)
|
||||
#define STR_AXES_LOGICAL LOGICAL_AXIS_GANG("E", "X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W)
|
||||
|
||||
#define XYZ_GANG(V...) GANG_N(PRIMARY_LINEAR_AXES, V)
|
||||
#define XYZ_CODE(V...) CODE_N(PRIMARY_LINEAR_AXES, V)
|
||||
@ -75,8 +91,13 @@ template <class L, class R> struct IF<true, L, R> { typedef L type; };
|
||||
#endif
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
#define LIST_ITEM_E(N) , N
|
||||
#define CODE_ITEM_E(N) ; N
|
||||
#if NUM_AXES
|
||||
#define LIST_ITEM_E(N) , N
|
||||
#define CODE_ITEM_E(N) ; N
|
||||
#else
|
||||
#define LIST_ITEM_E(N) N
|
||||
#define CODE_ITEM_E(N) N
|
||||
#endif
|
||||
#define GANG_ITEM_E(N) N
|
||||
#else
|
||||
#define LIST_ITEM_E(N)
|
||||
@ -166,37 +187,38 @@ typedef struct AxisFlags {
|
||||
enum AxisEnum : uint8_t {
|
||||
|
||||
// Linear axes may be controlled directly or indirectly
|
||||
NUM_AXIS_LIST(X_AXIS, Y_AXIS, Z_AXIS, I_AXIS, J_AXIS, K_AXIS, U_AXIS, V_AXIS, W_AXIS)
|
||||
NUM_AXIS_LIST_(X_AXIS, Y_AXIS, Z_AXIS, I_AXIS, J_AXIS, K_AXIS, U_AXIS, V_AXIS, W_AXIS)
|
||||
|
||||
// Extruder axes may be considered distinctly
|
||||
#define _EN_ITEM(N) , E##N##_AXIS
|
||||
#define _EN_ITEM(N) E##N##_AXIS,
|
||||
REPEAT(EXTRUDERS, _EN_ITEM)
|
||||
#undef _EN_ITEM
|
||||
|
||||
// Core also keeps toolhead directions
|
||||
#if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX)
|
||||
, X_HEAD, Y_HEAD, Z_HEAD
|
||||
X_HEAD, Y_HEAD, Z_HEAD,
|
||||
#endif
|
||||
|
||||
// Distinct axes, including all E and Core
|
||||
, NUM_AXIS_ENUMS
|
||||
NUM_AXIS_ENUMS,
|
||||
|
||||
// Most of the time we refer only to the single E_AXIS
|
||||
#if HAS_EXTRUDERS
|
||||
, E_AXIS = E0_AXIS
|
||||
E_AXIS = E0_AXIS,
|
||||
#endif
|
||||
|
||||
// A, B, and C are for DELTA, SCARA, etc.
|
||||
, A_AXIS = X_AXIS
|
||||
#if HAS_X_AXIS
|
||||
A_AXIS = X_AXIS,
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
, B_AXIS = Y_AXIS
|
||||
B_AXIS = Y_AXIS,
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
, C_AXIS = Z_AXIS
|
||||
C_AXIS = Z_AXIS,
|
||||
#endif
|
||||
|
||||
// To refer to all or none
|
||||
, ALL_AXES_ENUM = 0xFE, NO_AXIS_ENUM = 0xFF
|
||||
ALL_AXES_ENUM = 0xFE, NO_AXIS_ENUM = 0xFF
|
||||
};
|
||||
|
||||
//
|
||||
@ -336,7 +358,9 @@ struct XYval {
|
||||
FI void reset() { x = y = 0; }
|
||||
|
||||
// Setters taking struct types and arrays
|
||||
FI void set(const T px) { x = px; }
|
||||
#if HAS_X_AXIS
|
||||
FI void set(const T px) { x = px; }
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
FI void set(const T px, const T py) { x = px; y = py; }
|
||||
FI void set(const T (&arr)[XY]) { x = arr[0]; y = arr[1]; }
|
||||
@ -453,9 +477,9 @@ struct XYval {
|
||||
FI XYval<T>& operator<<=(const int &p) { _LS(x); _LS(y); return *this; }
|
||||
|
||||
// Exact comparisons. For floats a "NEAR" operation may be better.
|
||||
FI bool operator==(const XYval<T> &rs) const { return NUM_AXIS_GANG(x == rs.x, && y == rs.y,,,,,,, ); }
|
||||
FI bool operator==(const XYZval<T> &rs) const { return NUM_AXIS_GANG(x == rs.x, && y == rs.y,,,,,,, ); }
|
||||
FI bool operator==(const XYZEval<T> &rs) const { return NUM_AXIS_GANG(x == rs.x, && y == rs.y,,,,,,, ); }
|
||||
FI bool operator==(const XYval<T> &rs) const { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y,,,,,,, ); }
|
||||
FI bool operator==(const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y,,,,,,, ); }
|
||||
FI bool operator==(const XYZEval<T> &rs) const { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y,,,,,,, ); }
|
||||
FI bool operator!=(const XYval<T> &rs) const { return !operator==(rs); }
|
||||
FI bool operator!=(const XYZval<T> &rs) const { return !operator==(rs); }
|
||||
FI bool operator!=(const XYZEval<T> &rs) const { return !operator==(rs); }
|
||||
@ -467,23 +491,25 @@ struct XYval {
|
||||
template<typename T>
|
||||
struct XYZval {
|
||||
union {
|
||||
struct { T NUM_AXIS_ARGS(); };
|
||||
struct { T NUM_AXIS_LIST(a, b, c, _i, _j, _k, _u, _v, _w); };
|
||||
#if NUM_AXES
|
||||
struct { T NUM_AXIS_ARGS(); };
|
||||
struct { T NUM_AXIS_LIST(a, b, c, _i, _j, _k, _u, _v, _w); };
|
||||
#endif
|
||||
T pos[NUM_AXES];
|
||||
};
|
||||
|
||||
// Set all to 0
|
||||
FI void reset() { NUM_AXIS_GANG(x =, y =, z =, i =, j =, k =, u =, v =, w =) 0; }
|
||||
FI void reset() { NUM_AXIS_CODE(x = 0, y = 0, z = 0, i = 0, j = 0, k = 0, u = 0, v = 0, w = 0); }
|
||||
|
||||
// Setters taking struct types and arrays
|
||||
FI void set(const XYval<T> pxy) { NUM_AXIS_CODE(x = pxy.x, y = pxy.y,,,,,,,); }
|
||||
FI void set(const XYval<T> pxy, const T pz) { NUM_AXIS_CODE(x = pxy.x, y = pxy.y, z = pz,,,,,,); }
|
||||
FI void set(const T (&arr)[NUM_AXES]) { NUM_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); }
|
||||
FI void set(const XYval<T> pxy) { NUM_AXIS_CODE(x = pxy.x, y = pxy.y,,,,,,,); }
|
||||
FI void set(const XYval<T> pxy, const T pz) { NUM_AXIS_CODE(x = pxy.x, y = pxy.y, z = pz,,,,,,); }
|
||||
FI void set(const T (&arr)[NUM_AXES]) { NUM_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); }
|
||||
#if LOGICAL_AXES > NUM_AXES
|
||||
FI void set(const T (&arr)[LOGICAL_AXES]) { NUM_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); }
|
||||
FI void set(LOGICAL_AXIS_ARGS(const T)) { NUM_AXIS_CODE(a = x, b = y, c = z, _i = i, _j = j, _k = k, _u = u, _v = v, _w = w ); }
|
||||
FI void set(const T (&arr)[LOGICAL_AXES]) { NUM_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); }
|
||||
FI void set(LOGICAL_AXIS_ARGS(const T)) { NUM_AXIS_CODE(a = x, b = y, c = z, _i = i, _j = j, _k = k, _u = u, _v = v, _w = w ); }
|
||||
#if DISTINCT_AXES > LOGICAL_AXES
|
||||
FI void set(const T (&arr)[DISTINCT_AXES]) { NUM_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); }
|
||||
FI void set(const T (&arr)[DISTINCT_AXES]) { NUM_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -517,15 +543,15 @@ struct XYZval {
|
||||
#endif
|
||||
|
||||
// Length reduced to one dimension
|
||||
FI T magnitude() const { return (T)sqrtf(NUM_AXIS_GANG(x*x, + y*y, + z*z, + i*i, + j*j, + k*k, + u*u, + v*v, + w*w)); }
|
||||
FI T magnitude() const { return (T)TERN(HAS_X_AXIS, sqrtf(NUM_AXIS_GANG(x*x, + y*y, + z*z, + i*i, + j*j, + k*k, + u*u, + v*v, + w*w)), 0); }
|
||||
// Pointer to the data as a simple array
|
||||
FI operator T* () { return pos; }
|
||||
FI operator T* () { return (T*)this; }
|
||||
// If any element is true then it's true
|
||||
FI operator bool() { return NUM_AXIS_GANG(x, || y, || z, || i, || j, || k, || u, || v, || w); }
|
||||
FI operator bool() { return 0 NUM_AXIS_GANG(|| x, || y, || z, || i, || j, || k, || u, || v, || w); }
|
||||
// Smallest element
|
||||
FI T small() const { return _MIN(NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w)); }
|
||||
FI T small() const { return TERN(HAS_X_AXIS,_MIN(NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w));,0;) }
|
||||
// Largest element
|
||||
FI T large() const { return _MAX(NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w)); }
|
||||
FI T large() const { return TERN(HAS_X_AXIS,_MAX(NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w));,0;) }
|
||||
|
||||
// Explicit copy and copies with conversion
|
||||
FI XYZval<T> copy() const { XYZval<T> o = *this; return o; }
|
||||
@ -634,10 +660,10 @@ struct XYZEval {
|
||||
T pos[LOGICAL_AXES];
|
||||
};
|
||||
// Reset all to 0
|
||||
FI void reset() { LOGICAL_AXIS_GANG(e =, x =, y =, z =, i =, j =, k =, u =, v =, w =) 0; }
|
||||
FI void reset() { LOGICAL_AXIS_GANG(e =, x =, y =, z =, i =, j =, k =, u =, v =, w =) 0; }
|
||||
|
||||
// Setters taking struct types and arrays
|
||||
FI void set(const XYval<T> pxy) { x = pxy.x; OPTCODE(HAS_Y_AXIS, y = pxy.y) }
|
||||
FI void set(const XYval<T> pxy) { OPTCODE(HAS_X_AXIS, x = pxy.x) OPTCODE(HAS_Y_AXIS, y = pxy.y) }
|
||||
FI void set(const XYZval<T> pxyz) { set(NUM_AXIS_ELEM(pxyz)); }
|
||||
FI void set(const XYval<T> pxy, const T pz) { set(pxy); TERN_(HAS_Z_AXIS, z = pz); }
|
||||
FI void set(const T (&arr)[NUM_AXES]) { NUM_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); }
|
||||
|
@ -195,8 +195,6 @@ void FWRetract::retract(const bool retracting E_OPTARG(bool swapping/*=false*/))
|
||||
//*/
|
||||
}
|
||||
|
||||
//extern const char SP_Z_STR[];
|
||||
|
||||
/**
|
||||
* M207: Set firmware retraction values
|
||||
*
|
||||
|
@ -773,8 +773,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
static void tmc_debug_loop(const TMC_debug_enum n, LOGICAL_AXIS_ARGS(const bool)) {
|
||||
if (x) {
|
||||
static void tmc_debug_loop(const TMC_debug_enum n OPTARGS_LOGICAL(const bool)) {
|
||||
if (TERN0(HAS_X_AXIS, x)) {
|
||||
#if AXIS_IS_TMC(X)
|
||||
tmc_status(stepperX, n);
|
||||
#endif
|
||||
@ -856,8 +856,8 @@
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
static void drv_status_loop(const TMC_drv_status_enum n, LOGICAL_AXIS_ARGS(const bool)) {
|
||||
if (x) {
|
||||
static void drv_status_loop(const TMC_drv_status_enum n OPTARGS_LOGICAL(const bool)) {
|
||||
if (TERN0(HAS_X_AXIS, x)) {
|
||||
#if AXIS_IS_TMC(X)
|
||||
tmc_parse_drv_status(stepperX, n);
|
||||
#endif
|
||||
@ -944,8 +944,8 @@
|
||||
*/
|
||||
|
||||
void tmc_report_all(LOGICAL_AXIS_ARGS(const bool)) {
|
||||
#define TMC_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_debug_loop(ITEM, LOGICAL_AXIS_ARGS()); }while(0)
|
||||
#define DRV_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); drv_status_loop(ITEM, LOGICAL_AXIS_ARGS()); }while(0)
|
||||
#define TMC_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_debug_loop(ITEM OPTARGS_LOGICAL()); }while(0)
|
||||
#define DRV_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); drv_status_loop(ITEM OPTARGS_LOGICAL()); }while(0)
|
||||
|
||||
TMC_REPORT("\t", TMC_CODES);
|
||||
#if HAS_DRIVER(TMC2209)
|
||||
@ -1070,8 +1070,8 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
static void tmc_get_registers(TMC_get_registers_enum n, LOGICAL_AXIS_ARGS(const bool)) {
|
||||
if (x) {
|
||||
static void tmc_get_registers(TMC_get_registers_enum n OPTARGS_LOGICAL(const bool)) {
|
||||
if (TERN0(HAS_X_AXIS, x)) {
|
||||
#if AXIS_IS_TMC(X)
|
||||
tmc_get_registers(stepperX, n);
|
||||
#endif
|
||||
@ -1154,7 +1154,7 @@
|
||||
}
|
||||
|
||||
void tmc_get_registers(LOGICAL_AXIS_ARGS(bool)) {
|
||||
#define _TMC_GET_REG(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_get_registers(ITEM, LOGICAL_AXIS_ARGS()); }while(0)
|
||||
#define _TMC_GET_REG(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_get_registers(ITEM OPTARGS_LOGICAL()); }while(0)
|
||||
#define TMC_GET_REG(NAME, TABS) _TMC_GET_REG(STRINGIFY(NAME) TABS, TMC_GET_##NAME)
|
||||
_TMC_GET_REG("\t", TMC_AXIS_CODES);
|
||||
TMC_GET_REG(GCONF, "\t\t");
|
||||
@ -1236,7 +1236,7 @@ static bool test_connection(TMC &st) {
|
||||
void test_tmc_connection(LOGICAL_AXIS_ARGS(const bool)) {
|
||||
uint8_t axis_connection = 0;
|
||||
|
||||
if (x) {
|
||||
if (TERN0(HAS_X_AXIS, x)) {
|
||||
#if AXIS_IS_TMC(X)
|
||||
axis_connection += test_connection(stepperX);
|
||||
#endif
|
||||
|
@ -348,7 +348,7 @@ void test_tmc_connection(LOGICAL_AXIS_DECL(const bool, true));
|
||||
#if USE_SENSORLESS
|
||||
|
||||
// Track enabled status of stealthChop and only re-enable where applicable
|
||||
struct sensorless_t { bool NUM_AXIS_ARGS(), x2, y2, z2, z3, z4; };
|
||||
struct sensorless_t { bool NUM_AXIS_ARGS_() x2, y2, z2, z3, z4; };
|
||||
|
||||
#if ENABLED(IMPROVE_HOMING_RELIABILITY)
|
||||
extern millis_t sg_guard_period;
|
||||
|
@ -206,20 +206,6 @@ void GcodeSuite::G28() {
|
||||
DEBUG_SECTION(log_G28, "G28", DEBUGGING(LEVELING));
|
||||
if (DEBUGGING(LEVELING)) log_machine_info();
|
||||
|
||||
TERN_(BD_SENSOR, bdl.config_state = 0);
|
||||
|
||||
/**
|
||||
* Set the laser power to false to stop the planner from processing the current power setting.
|
||||
*/
|
||||
#if ENABLED(LASER_FEATURE)
|
||||
planner.laser_inline.status.isPowered = false;
|
||||
#endif
|
||||
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
bool IDEX_saved_duplication_state = extruder_duplication_enabled;
|
||||
DualXMode IDEX_saved_mode = dual_x_carriage_mode;
|
||||
#endif
|
||||
|
||||
#if ENABLED(MARLIN_DEV_MODE)
|
||||
if (parser.seen_test('S')) {
|
||||
LOOP_NUM_AXES(a) set_axis_is_at_home((AxisEnum)a);
|
||||
@ -230,12 +216,21 @@ void GcodeSuite::G28() {
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set the laser power to false to stop the planner from processing the current power setting.
|
||||
*/
|
||||
#if ENABLED(LASER_FEATURE)
|
||||
planner.laser_inline.status.isPowered = false;
|
||||
#endif
|
||||
|
||||
// Home (O)nly if position is unknown
|
||||
if (!axes_should_home() && parser.seen_test('O')) {
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> homing not needed, skip");
|
||||
return;
|
||||
}
|
||||
|
||||
TERN_(BD_SENSOR, bdl.config_state = 0);
|
||||
|
||||
#if ENABLED(FULL_REPORT_TO_HOST_FEATURE)
|
||||
const M_StateEnum old_grblstate = M_State_grbl;
|
||||
set_and_report_grblstate(M_HOMING);
|
||||
@ -246,220 +241,322 @@ void GcodeSuite::G28() {
|
||||
|
||||
planner.synchronize(); // Wait for planner moves to finish!
|
||||
|
||||
SET_SOFT_ENDSTOP_LOOSE(false); // Reset a leftover 'loose' motion state
|
||||
|
||||
// Disable the leveling matrix before homing
|
||||
#if CAN_SET_LEVELING_AFTER_G28
|
||||
const bool leveling_restore_state = parser.boolval('L', TERN1(RESTORE_LEVELING_AFTER_G28, planner.leveling_active));
|
||||
#endif
|
||||
|
||||
// Cancel any prior G29 session
|
||||
TERN_(PROBE_MANUALLY, g29_in_progress = false);
|
||||
|
||||
// Disable leveling before homing
|
||||
TERN_(HAS_LEVELING, set_bed_leveling_enabled(false));
|
||||
|
||||
// Reset to the XY plane
|
||||
TERN_(CNC_WORKSPACE_PLANES, workspace_plane = PLANE_XY);
|
||||
|
||||
// Count this command as movement / activity
|
||||
reset_stepper_timeout();
|
||||
|
||||
#define HAS_CURRENT_HOME(N) (defined(N##_CURRENT_HOME) && N##_CURRENT_HOME != N##_CURRENT)
|
||||
#if HAS_CURRENT_HOME(X) || HAS_CURRENT_HOME(X2) || HAS_CURRENT_HOME(Y) || HAS_CURRENT_HOME(Y2) || (ENABLED(DELTA) && HAS_CURRENT_HOME(Z)) || HAS_CURRENT_HOME(I) || HAS_CURRENT_HOME(J) || HAS_CURRENT_HOME(K) || HAS_CURRENT_HOME(U) || HAS_CURRENT_HOME(V) || HAS_CURRENT_HOME(W)
|
||||
#define HAS_HOMING_CURRENT 1
|
||||
#endif
|
||||
#if NUM_AXES
|
||||
|
||||
#if HAS_HOMING_CURRENT
|
||||
auto debug_current = [](FSTR_P const s, const int16_t a, const int16_t b) {
|
||||
DEBUG_ECHOF(s); DEBUG_ECHOLNPGM(" current: ", a, " -> ", b);
|
||||
};
|
||||
#if HAS_CURRENT_HOME(X)
|
||||
const int16_t tmc_save_current_X = stepperX.getMilliamps();
|
||||
stepperX.rms_current(X_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_X), tmc_save_current_X, X_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(X2)
|
||||
const int16_t tmc_save_current_X2 = stepperX2.getMilliamps();
|
||||
stepperX2.rms_current(X2_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_X2), tmc_save_current_X2, X2_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(Y)
|
||||
const int16_t tmc_save_current_Y = stepperY.getMilliamps();
|
||||
stepperY.rms_current(Y_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_Y), tmc_save_current_Y, Y_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(Y2)
|
||||
const int16_t tmc_save_current_Y2 = stepperY2.getMilliamps();
|
||||
stepperY2.rms_current(Y2_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_Y2), tmc_save_current_Y2, Y2_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(Z) && ENABLED(DELTA)
|
||||
const int16_t tmc_save_current_Z = stepperZ.getMilliamps();
|
||||
stepperZ.rms_current(Z_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_Z), tmc_save_current_Z, Z_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(I)
|
||||
const int16_t tmc_save_current_I = stepperI.getMilliamps();
|
||||
stepperI.rms_current(I_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_I), tmc_save_current_I, I_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(J)
|
||||
const int16_t tmc_save_current_J = stepperJ.getMilliamps();
|
||||
stepperJ.rms_current(J_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_J), tmc_save_current_J, J_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(K)
|
||||
const int16_t tmc_save_current_K = stepperK.getMilliamps();
|
||||
stepperK.rms_current(K_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_K), tmc_save_current_K, K_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(U)
|
||||
const int16_t tmc_save_current_U = stepperU.getMilliamps();
|
||||
stepperU.rms_current(U_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_U), tmc_save_current_U, U_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(V)
|
||||
const int16_t tmc_save_current_V = stepperV.getMilliamps();
|
||||
stepperV.rms_current(V_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_V), tmc_save_current_V, V_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(W)
|
||||
const int16_t tmc_save_current_W = stepperW.getMilliamps();
|
||||
stepperW.rms_current(W_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_W), tmc_save_current_W, W_CURRENT_HOME);
|
||||
#endif
|
||||
#if SENSORLESS_STALLGUARD_DELAY
|
||||
safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
|
||||
#endif
|
||||
#endif // HAS_HOMING_CURRENT
|
||||
|
||||
#if ENABLED(IMPROVE_HOMING_RELIABILITY)
|
||||
motion_state_t saved_motion_state = begin_slow_homing();
|
||||
#endif
|
||||
|
||||
// Always home with tool 0 active
|
||||
#if HAS_MULTI_HOTEND
|
||||
#if DISABLED(DELTA) || ENABLED(DELTA_HOME_TO_SAFE_ZONE)
|
||||
const uint8_t old_tool_index = active_extruder;
|
||||
#endif
|
||||
// PARKING_EXTRUDER homing requires different handling of movement / solenoid activation, depending on the side of homing
|
||||
#if ENABLED(PARKING_EXTRUDER)
|
||||
const bool pe_final_change_must_unpark = parking_extruder_unpark_after_homing(old_tool_index, X_HOME_DIR + 1 == old_tool_index * 2);
|
||||
#endif
|
||||
tool_change(0, true);
|
||||
#endif
|
||||
|
||||
TERN_(HAS_DUPLICATION_MODE, set_duplication_enabled(false));
|
||||
|
||||
remember_feedrate_scaling_off();
|
||||
|
||||
endstops.enable(true); // Enable endstops for next homing move
|
||||
|
||||
bool finalRaiseZ = false;
|
||||
|
||||
#if ENABLED(DELTA)
|
||||
|
||||
constexpr bool doZ = true; // for NANODLP_Z_SYNC if your DLP is on a DELTA
|
||||
|
||||
home_delta();
|
||||
|
||||
TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(saved_motion_state));
|
||||
|
||||
#elif ENABLED(AXEL_TPARA)
|
||||
|
||||
constexpr bool doZ = true; // for NANODLP_Z_SYNC if your DLP is on a TPARA
|
||||
|
||||
home_TPARA();
|
||||
|
||||
#else
|
||||
|
||||
#define _UNSAFE(A) (homeZ && TERN0(Z_SAFE_HOMING, axes_should_home(_BV(A##_AXIS))))
|
||||
|
||||
const bool homeZ = TERN0(HAS_Z_AXIS, parser.seen_test('Z')),
|
||||
NUM_AXIS_LIST( // Other axes should be homed before Z safe-homing
|
||||
needX = _UNSAFE(X), needY = _UNSAFE(Y), needZ = false, // UNUSED
|
||||
needI = _UNSAFE(I), needJ = _UNSAFE(J), needK = _UNSAFE(K),
|
||||
needU = _UNSAFE(U), needV = _UNSAFE(V), needW = _UNSAFE(W)
|
||||
),
|
||||
NUM_AXIS_LIST( // Home each axis if needed or flagged
|
||||
homeX = needX || parser.seen_test('X'),
|
||||
homeY = needY || parser.seen_test('Y'),
|
||||
homeZZ = homeZ,
|
||||
homeI = needI || parser.seen_test(AXIS4_NAME), homeJ = needJ || parser.seen_test(AXIS5_NAME),
|
||||
homeK = needK || parser.seen_test(AXIS6_NAME), homeU = needU || parser.seen_test(AXIS7_NAME),
|
||||
homeV = needV || parser.seen_test(AXIS8_NAME), homeW = needW || parser.seen_test(AXIS9_NAME)
|
||||
),
|
||||
home_all = NUM_AXIS_GANG( // Home-all if all or none are flagged
|
||||
homeX == homeX, && homeY == homeX, && homeZ == homeX,
|
||||
&& homeI == homeX, && homeJ == homeX, && homeK == homeX,
|
||||
&& homeU == homeX, && homeV == homeX, && homeW == homeX
|
||||
),
|
||||
NUM_AXIS_LIST(
|
||||
doX = home_all || homeX, doY = home_all || homeY, doZ = home_all || homeZ,
|
||||
doI = home_all || homeI, doJ = home_all || homeJ, doK = home_all || homeK,
|
||||
doU = home_all || homeU, doV = home_all || homeV, doW = home_all || homeW
|
||||
);
|
||||
|
||||
#if !HAS_Y_AXIS
|
||||
constexpr bool doY = false;
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
bool IDEX_saved_duplication_state = extruder_duplication_enabled;
|
||||
DualXMode IDEX_saved_mode = dual_x_carriage_mode;
|
||||
#endif
|
||||
|
||||
#if HAS_Z_AXIS
|
||||
SET_SOFT_ENDSTOP_LOOSE(false); // Reset a leftover 'loose' motion state
|
||||
|
||||
UNUSED(needZ); UNUSED(homeZZ);
|
||||
// Disable the leveling matrix before homing
|
||||
#if CAN_SET_LEVELING_AFTER_G28
|
||||
const bool leveling_restore_state = parser.boolval('L', TERN1(RESTORE_LEVELING_AFTER_G28, planner.leveling_active));
|
||||
#endif
|
||||
|
||||
// Z may home first, e.g., when homing away from the bed.
|
||||
// This is also permitted when homing with a Z endstop.
|
||||
if (TERN0(HOME_Z_FIRST, doZ)) homeaxis(Z_AXIS);
|
||||
// Cancel any prior G29 session
|
||||
TERN_(PROBE_MANUALLY, g29_in_progress = false);
|
||||
|
||||
// 'R' to specify a specific raise. 'R0' indicates no raise, e.g., for recovery.resume
|
||||
// When 'R0' is used, there should already be adequate clearance, e.g., from homing Z to max.
|
||||
const bool seenR = parser.seenval('R');
|
||||
// Disable leveling before homing
|
||||
TERN_(HAS_LEVELING, set_bed_leveling_enabled(false));
|
||||
|
||||
// Use raise given by 'R' or Z_CLEARANCE_FOR_HOMING (above the probe trigger point)
|
||||
float z_homing_height = seenR ? parser.value_linear_units() : Z_CLEARANCE_FOR_HOMING;
|
||||
// Reset to the XY plane
|
||||
TERN_(CNC_WORKSPACE_PLANES, workspace_plane = PLANE_XY);
|
||||
|
||||
// Check for any lateral motion that might require clearance
|
||||
const bool may_skate = seenR || NUM_AXIS_GANG(doX, || doY, || TERN0(Z_SAFE_HOMING, doZ), || doI, || doJ, || doK, || doU, || doV, || doW);
|
||||
#define HAS_CURRENT_HOME(N) (defined(N##_CURRENT_HOME) && N##_CURRENT_HOME != N##_CURRENT)
|
||||
#if HAS_CURRENT_HOME(X) || HAS_CURRENT_HOME(X2) || HAS_CURRENT_HOME(Y) || HAS_CURRENT_HOME(Y2) || (ENABLED(DELTA) && HAS_CURRENT_HOME(Z)) || HAS_CURRENT_HOME(I) || HAS_CURRENT_HOME(J) || HAS_CURRENT_HOME(K) || HAS_CURRENT_HOME(U) || HAS_CURRENT_HOME(V) || HAS_CURRENT_HOME(W)
|
||||
#define HAS_HOMING_CURRENT 1
|
||||
#endif
|
||||
|
||||
if (seenR && z_homing_height == 0) {
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("R0 = No Z raise");
|
||||
}
|
||||
else {
|
||||
bool with_probe = ENABLED(HOMING_Z_WITH_PROBE);
|
||||
// Raise above the current Z (which should be synced in the planner)
|
||||
// The "height" for Z is a coordinate. But if Z is not trusted/homed make it relative.
|
||||
if (seenR || !TERN(HOME_AFTER_DEACTIVATE, axis_is_trusted, axis_was_homed)(Z_AXIS)) {
|
||||
z_homing_height += current_position.z;
|
||||
with_probe = false;
|
||||
#if HAS_HOMING_CURRENT
|
||||
auto debug_current = [](FSTR_P const s, const int16_t a, const int16_t b) {
|
||||
DEBUG_ECHOF(s); DEBUG_ECHOLNPGM(" current: ", a, " -> ", b);
|
||||
};
|
||||
#if HAS_CURRENT_HOME(X)
|
||||
const int16_t tmc_save_current_X = stepperX.getMilliamps();
|
||||
stepperX.rms_current(X_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_X), tmc_save_current_X, X_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(X2)
|
||||
const int16_t tmc_save_current_X2 = stepperX2.getMilliamps();
|
||||
stepperX2.rms_current(X2_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_X2), tmc_save_current_X2, X2_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(Y)
|
||||
const int16_t tmc_save_current_Y = stepperY.getMilliamps();
|
||||
stepperY.rms_current(Y_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_Y), tmc_save_current_Y, Y_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(Y2)
|
||||
const int16_t tmc_save_current_Y2 = stepperY2.getMilliamps();
|
||||
stepperY2.rms_current(Y2_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_Y2), tmc_save_current_Y2, Y2_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(Z) && ENABLED(DELTA)
|
||||
const int16_t tmc_save_current_Z = stepperZ.getMilliamps();
|
||||
stepperZ.rms_current(Z_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_Z), tmc_save_current_Z, Z_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(I)
|
||||
const int16_t tmc_save_current_I = stepperI.getMilliamps();
|
||||
stepperI.rms_current(I_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_I), tmc_save_current_I, I_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(J)
|
||||
const int16_t tmc_save_current_J = stepperJ.getMilliamps();
|
||||
stepperJ.rms_current(J_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_J), tmc_save_current_J, J_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(K)
|
||||
const int16_t tmc_save_current_K = stepperK.getMilliamps();
|
||||
stepperK.rms_current(K_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_K), tmc_save_current_K, K_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(U)
|
||||
const int16_t tmc_save_current_U = stepperU.getMilliamps();
|
||||
stepperU.rms_current(U_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_U), tmc_save_current_U, U_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(V)
|
||||
const int16_t tmc_save_current_V = stepperV.getMilliamps();
|
||||
stepperV.rms_current(V_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_V), tmc_save_current_V, V_CURRENT_HOME);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(W)
|
||||
const int16_t tmc_save_current_W = stepperW.getMilliamps();
|
||||
stepperW.rms_current(W_CURRENT_HOME);
|
||||
if (DEBUGGING(LEVELING)) debug_current(F(STR_W), tmc_save_current_W, W_CURRENT_HOME);
|
||||
#endif
|
||||
#if SENSORLESS_STALLGUARD_DELAY
|
||||
safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
|
||||
#endif
|
||||
#endif // HAS_HOMING_CURRENT
|
||||
|
||||
#if ENABLED(IMPROVE_HOMING_RELIABILITY)
|
||||
motion_state_t saved_motion_state = begin_slow_homing();
|
||||
#endif
|
||||
|
||||
// Always home with tool 0 active
|
||||
#if HAS_MULTI_HOTEND
|
||||
#if DISABLED(DELTA) || ENABLED(DELTA_HOME_TO_SAFE_ZONE)
|
||||
const uint8_t old_tool_index = active_extruder;
|
||||
#endif
|
||||
// PARKING_EXTRUDER homing requires different handling of movement / solenoid activation, depending on the side of homing
|
||||
#if ENABLED(PARKING_EXTRUDER)
|
||||
const bool pe_final_change_must_unpark = parking_extruder_unpark_after_homing(old_tool_index, X_HOME_DIR + 1 == old_tool_index * 2);
|
||||
#endif
|
||||
tool_change(0, true);
|
||||
#endif
|
||||
|
||||
TERN_(HAS_DUPLICATION_MODE, set_duplication_enabled(false));
|
||||
|
||||
remember_feedrate_scaling_off();
|
||||
|
||||
endstops.enable(true); // Enable endstops for next homing move
|
||||
|
||||
bool finalRaiseZ = false;
|
||||
|
||||
#if ENABLED(DELTA)
|
||||
|
||||
constexpr bool doZ = true; // for NANODLP_Z_SYNC if your DLP is on a DELTA
|
||||
|
||||
home_delta();
|
||||
|
||||
TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(saved_motion_state));
|
||||
|
||||
#elif ENABLED(AXEL_TPARA)
|
||||
|
||||
constexpr bool doZ = true; // for NANODLP_Z_SYNC if your DLP is on a TPARA
|
||||
|
||||
home_TPARA();
|
||||
|
||||
#else // !DELTA && !AXEL_TPARA
|
||||
|
||||
#define _UNSAFE(A) (homeZ && TERN0(Z_SAFE_HOMING, axes_should_home(_BV(A##_AXIS))))
|
||||
|
||||
const bool homeZ = TERN0(HAS_Z_AXIS, parser.seen_test('Z')),
|
||||
NUM_AXIS_LIST_( // Other axes should be homed before Z safe-homing
|
||||
needX = _UNSAFE(X), needY = _UNSAFE(Y), needZ = false, // UNUSED
|
||||
needI = _UNSAFE(I), needJ = _UNSAFE(J), needK = _UNSAFE(K),
|
||||
needU = _UNSAFE(U), needV = _UNSAFE(V), needW = _UNSAFE(W)
|
||||
)
|
||||
NUM_AXIS_LIST_( // Home each axis if needed or flagged
|
||||
homeX = needX || parser.seen_test('X'),
|
||||
homeY = needY || parser.seen_test('Y'),
|
||||
homeZZ = homeZ,
|
||||
homeI = needI || parser.seen_test(AXIS4_NAME), homeJ = needJ || parser.seen_test(AXIS5_NAME),
|
||||
homeK = needK || parser.seen_test(AXIS6_NAME), homeU = needU || parser.seen_test(AXIS7_NAME),
|
||||
homeV = needV || parser.seen_test(AXIS8_NAME), homeW = needW || parser.seen_test(AXIS9_NAME)
|
||||
)
|
||||
home_all = NUM_AXIS_GANG_( // Home-all if all or none are flagged
|
||||
homeX == homeX, && homeY == homeX, && homeZ == homeX,
|
||||
&& homeI == homeX, && homeJ == homeX, && homeK == homeX,
|
||||
&& homeU == homeX, && homeV == homeX, && homeW == homeX
|
||||
)
|
||||
NUM_AXIS_LIST(
|
||||
doX = home_all || homeX, doY = home_all || homeY, doZ = home_all || homeZ,
|
||||
doI = home_all || homeI, doJ = home_all || homeJ, doK = home_all || homeK,
|
||||
doU = home_all || homeU, doV = home_all || homeV, doW = home_all || homeW
|
||||
);
|
||||
|
||||
#if !HAS_Y_AXIS
|
||||
constexpr bool doY = false;
|
||||
#endif
|
||||
|
||||
#if HAS_Z_AXIS
|
||||
|
||||
UNUSED(needZ); UNUSED(homeZZ);
|
||||
|
||||
// Z may home first, e.g., when homing away from the bed.
|
||||
// This is also permitted when homing with a Z endstop.
|
||||
if (TERN0(HOME_Z_FIRST, doZ)) homeaxis(Z_AXIS);
|
||||
|
||||
// 'R' to specify a specific raise. 'R0' indicates no raise, e.g., for recovery.resume
|
||||
// When 'R0' is used, there should already be adequate clearance, e.g., from homing Z to max.
|
||||
const bool seenR = parser.seenval('R');
|
||||
|
||||
// Use raise given by 'R' or Z_CLEARANCE_FOR_HOMING (above the probe trigger point)
|
||||
float z_homing_height = seenR ? parser.value_linear_units() : Z_CLEARANCE_FOR_HOMING;
|
||||
|
||||
// Check for any lateral motion that might require clearance
|
||||
const bool may_skate = seenR NUM_AXIS_GANG(|| doX, || doY, || TERN0(Z_SAFE_HOMING, doZ), || doI, || doJ, || doK, || doU, || doV, || doW);
|
||||
|
||||
if (seenR && z_homing_height == 0) {
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("R0 = No Z raise");
|
||||
}
|
||||
else {
|
||||
bool with_probe = ENABLED(HOMING_Z_WITH_PROBE);
|
||||
// Raise above the current Z (which should be synced in the planner)
|
||||
// The "height" for Z is a coordinate. But if Z is not trusted/homed make it relative.
|
||||
if (seenR || !TERN(HOME_AFTER_DEACTIVATE, axis_is_trusted, axis_was_homed)(Z_AXIS)) {
|
||||
z_homing_height += current_position.z;
|
||||
with_probe = false;
|
||||
}
|
||||
|
||||
if (may_skate) {
|
||||
// Apply Z clearance before doing any lateral motion
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Raise Z before homing:");
|
||||
do_z_clearance(z_homing_height, with_probe);
|
||||
}
|
||||
}
|
||||
|
||||
if (may_skate) {
|
||||
// Apply Z clearance before doing any lateral motion
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Raise Z before homing:");
|
||||
do_z_clearance(z_homing_height, with_probe);
|
||||
// Init BLTouch ahead of any lateral motion, even if not homing with the probe
|
||||
TERN_(BLTOUCH, if (may_skate) bltouch.init());
|
||||
|
||||
#endif // HAS_Z_AXIS
|
||||
|
||||
// Diagonal move first if both are homing
|
||||
TERN_(QUICK_HOME, if (doX && doY) quick_home_xy());
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
// Home Y (before X)
|
||||
if (ENABLED(HOME_Y_BEFORE_X) && (doY || TERN0(CODEPENDENT_XY_HOMING, doX)))
|
||||
homeaxis(Y_AXIS);
|
||||
#endif
|
||||
|
||||
// Home X
|
||||
#if HAS_X_AXIS
|
||||
if (doX || (doY && ENABLED(CODEPENDENT_XY_HOMING) && DISABLED(HOME_Y_BEFORE_X))) {
|
||||
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
|
||||
// Always home the 2nd (right) extruder first
|
||||
active_extruder = 1;
|
||||
homeaxis(X_AXIS);
|
||||
|
||||
// Remember this extruder's position for later tool change
|
||||
inactive_extruder_x = current_position.x;
|
||||
|
||||
// Home the 1st (left) extruder
|
||||
active_extruder = 0;
|
||||
homeaxis(X_AXIS);
|
||||
|
||||
// Consider the active extruder to be in its "parked" position
|
||||
idex_set_parked();
|
||||
|
||||
#else
|
||||
|
||||
homeaxis(X_AXIS);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif // HAS_X_AXIS
|
||||
|
||||
// Init BLTouch ahead of any lateral motion, even if not homing with the probe
|
||||
TERN_(BLTOUCH, if (may_skate) bltouch.init());
|
||||
#if BOTH(FOAMCUTTER_XYUV, HAS_I_AXIS)
|
||||
// Home I (after X)
|
||||
if (doI) homeaxis(I_AXIS);
|
||||
#endif
|
||||
|
||||
#endif // HAS_Z_AXIS
|
||||
#if HAS_Y_AXIS
|
||||
// Home Y (after X)
|
||||
if (DISABLED(HOME_Y_BEFORE_X) && doY)
|
||||
homeaxis(Y_AXIS);
|
||||
#endif
|
||||
|
||||
// Diagonal move first if both are homing
|
||||
TERN_(QUICK_HOME, if (doX && doY) quick_home_xy());
|
||||
#if BOTH(FOAMCUTTER_XYUV, HAS_J_AXIS)
|
||||
// Home J (after Y)
|
||||
if (doJ) homeaxis(J_AXIS);
|
||||
#endif
|
||||
|
||||
TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(saved_motion_state));
|
||||
|
||||
#if ENABLED(FOAMCUTTER_XYUV)
|
||||
|
||||
// Skip homing of unused Z axis for foamcutters
|
||||
if (doZ) set_axis_is_at_home(Z_AXIS);
|
||||
|
||||
#elif HAS_Z_AXIS
|
||||
|
||||
// Home Z last if homing towards the bed
|
||||
#if DISABLED(HOME_Z_FIRST)
|
||||
if (doZ) {
|
||||
#if EITHER(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
|
||||
stepper.set_all_z_lock(false);
|
||||
stepper.set_separate_multi_axis(false);
|
||||
#endif
|
||||
|
||||
#if ENABLED(Z_SAFE_HOMING)
|
||||
if (TERN1(POWER_LOSS_RECOVERY, !parser.seen_test('H'))) home_z_safely(); else homeaxis(Z_AXIS);
|
||||
#else
|
||||
homeaxis(Z_AXIS);
|
||||
#endif
|
||||
|
||||
#if EITHER(Z_HOME_TO_MIN, ALLOW_Z_AFTER_HOMING)
|
||||
finalRaiseZ = true;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
SECONDARY_AXIS_CODE(
|
||||
if (doI) homeaxis(I_AXIS),
|
||||
if (doJ) homeaxis(J_AXIS),
|
||||
if (doK) homeaxis(K_AXIS),
|
||||
if (doU) homeaxis(U_AXIS),
|
||||
if (doV) homeaxis(V_AXIS),
|
||||
if (doW) homeaxis(W_AXIS)
|
||||
);
|
||||
|
||||
#endif // HAS_Z_AXIS
|
||||
|
||||
sync_plan_position();
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
// Home Y (before X)
|
||||
if (ENABLED(HOME_Y_BEFORE_X) && (doY || TERN0(CODEPENDENT_XY_HOMING, doX)))
|
||||
homeaxis(Y_AXIS);
|
||||
#endif
|
||||
|
||||
// Home X
|
||||
if (doX || (doY && ENABLED(CODEPENDENT_XY_HOMING) && DISABLED(HOME_Y_BEFORE_X))) {
|
||||
/**
|
||||
* Preserve DXC mode across a G28 for IDEX printers in DXC_DUPLICATION_MODE.
|
||||
* This is important because it lets a user use the LCD Panel to set an IDEX Duplication mode, and
|
||||
* then print a standard GCode file that contains a single print that does a G28 and has no other
|
||||
* IDEX specific commands in it.
|
||||
*/
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
if (idex_is_duplicating()) {
|
||||
|
||||
TERN_(IMPROVE_HOMING_RELIABILITY, saved_motion_state = begin_slow_homing());
|
||||
|
||||
// Always home the 2nd (right) extruder first
|
||||
active_extruder = 1;
|
||||
@ -472,171 +569,83 @@ void GcodeSuite::G28() {
|
||||
active_extruder = 0;
|
||||
homeaxis(X_AXIS);
|
||||
|
||||
// Consider the active extruder to be in its "parked" position
|
||||
// Consider the active extruder to be parked
|
||||
idex_set_parked();
|
||||
|
||||
#else
|
||||
dual_x_carriage_mode = IDEX_saved_mode;
|
||||
set_duplication_enabled(IDEX_saved_duplication_state);
|
||||
|
||||
homeaxis(X_AXIS);
|
||||
TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(saved_motion_state));
|
||||
}
|
||||
|
||||
#endif // DUAL_X_CARRIAGE
|
||||
|
||||
endstops.not_homing();
|
||||
|
||||
// Clear endstop state for polled stallGuard endstops
|
||||
TERN_(SPI_ENDSTOPS, endstops.clear_endstop_state());
|
||||
|
||||
#if HAS_HOMING_CURRENT
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Restore driver current...");
|
||||
#if HAS_CURRENT_HOME(X)
|
||||
stepperX.rms_current(tmc_save_current_X);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BOTH(FOAMCUTTER_XYUV, HAS_I_AXIS)
|
||||
// Home I (after X)
|
||||
if (doI) homeaxis(I_AXIS);
|
||||
#endif
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
// Home Y (after X)
|
||||
if (DISABLED(HOME_Y_BEFORE_X) && doY)
|
||||
homeaxis(Y_AXIS);
|
||||
#endif
|
||||
|
||||
#if BOTH(FOAMCUTTER_XYUV, HAS_J_AXIS)
|
||||
// Home J (after Y)
|
||||
if (doJ) homeaxis(J_AXIS);
|
||||
#endif
|
||||
|
||||
TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(saved_motion_state));
|
||||
|
||||
#if ENABLED(FOAMCUTTER_XYUV)
|
||||
|
||||
// Skip homing of unused Z axis for foamcutters
|
||||
if (doZ) set_axis_is_at_home(Z_AXIS);
|
||||
|
||||
#elif HAS_Z_AXIS
|
||||
|
||||
// Home Z last if homing towards the bed
|
||||
#if DISABLED(HOME_Z_FIRST)
|
||||
if (doZ) {
|
||||
#if EITHER(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
|
||||
stepper.set_all_z_lock(false);
|
||||
stepper.set_separate_multi_axis(false);
|
||||
#endif
|
||||
|
||||
#if ENABLED(Z_SAFE_HOMING)
|
||||
if (TERN1(POWER_LOSS_RECOVERY, !parser.seen_test('H'))) home_z_safely(); else homeaxis(Z_AXIS);
|
||||
#else
|
||||
homeaxis(Z_AXIS);
|
||||
#endif
|
||||
|
||||
#if EITHER(Z_HOME_TO_MIN, ALLOW_Z_AFTER_HOMING)
|
||||
finalRaiseZ = true;
|
||||
#endif
|
||||
}
|
||||
#if HAS_CURRENT_HOME(X2)
|
||||
stepperX2.rms_current(tmc_save_current_X2);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(Y)
|
||||
stepperY.rms_current(tmc_save_current_Y);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(Y2)
|
||||
stepperY2.rms_current(tmc_save_current_Y2);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(Z) && ENABLED(DELTA)
|
||||
stepperZ.rms_current(tmc_save_current_Z);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(I)
|
||||
stepperI.rms_current(tmc_save_current_I);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(J)
|
||||
stepperJ.rms_current(tmc_save_current_J);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(K)
|
||||
stepperK.rms_current(tmc_save_current_K);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(U)
|
||||
stepperU.rms_current(tmc_save_current_U);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(V)
|
||||
stepperV.rms_current(tmc_save_current_V);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(W)
|
||||
stepperW.rms_current(tmc_save_current_W);
|
||||
#endif
|
||||
#if SENSORLESS_STALLGUARD_DELAY
|
||||
safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
|
||||
#endif
|
||||
#endif // HAS_HOMING_CURRENT
|
||||
|
||||
SECONDARY_AXIS_CODE(
|
||||
if (doI) homeaxis(I_AXIS),
|
||||
if (doJ) homeaxis(J_AXIS),
|
||||
if (doK) homeaxis(K_AXIS),
|
||||
if (doU) homeaxis(U_AXIS),
|
||||
if (doV) homeaxis(V_AXIS),
|
||||
if (doW) homeaxis(W_AXIS)
|
||||
);
|
||||
// Move to a height where we can use the full xy-area
|
||||
TERN_(DELTA_HOME_TO_SAFE_ZONE, do_blocking_move_to_z(delta_clip_start_height));
|
||||
|
||||
#endif // HAS_Z_AXIS
|
||||
// Move to the configured Z only if Z was homed to MIN, because machines that
|
||||
// home to MAX historically expect 'G28 Z' to be safe to use at the end of a
|
||||
// print, and do_move_after_z_homing is not very nuanced.
|
||||
if (finalRaiseZ) do_move_after_z_homing();
|
||||
|
||||
sync_plan_position();
|
||||
TERN_(CAN_SET_LEVELING_AFTER_G28, if (leveling_restore_state) set_bed_leveling_enabled());
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Preserve DXC mode across a G28 for IDEX printers in DXC_DUPLICATION_MODE.
|
||||
* This is important because it lets a user use the LCD Panel to set an IDEX Duplication mode, and
|
||||
* then print a standard GCode file that contains a single print that does a G28 and has no other
|
||||
* IDEX specific commands in it.
|
||||
*/
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
|
||||
if (idex_is_duplicating()) {
|
||||
|
||||
TERN_(IMPROVE_HOMING_RELIABILITY, saved_motion_state = begin_slow_homing());
|
||||
|
||||
// Always home the 2nd (right) extruder first
|
||||
active_extruder = 1;
|
||||
homeaxis(X_AXIS);
|
||||
|
||||
// Remember this extruder's position for later tool change
|
||||
inactive_extruder_x = current_position.x;
|
||||
|
||||
// Home the 1st (left) extruder
|
||||
active_extruder = 0;
|
||||
homeaxis(X_AXIS);
|
||||
|
||||
// Consider the active extruder to be parked
|
||||
idex_set_parked();
|
||||
|
||||
dual_x_carriage_mode = IDEX_saved_mode;
|
||||
set_duplication_enabled(IDEX_saved_duplication_state);
|
||||
|
||||
TERN_(IMPROVE_HOMING_RELIABILITY, end_slow_homing(saved_motion_state));
|
||||
}
|
||||
|
||||
#endif // DUAL_X_CARRIAGE
|
||||
|
||||
endstops.not_homing();
|
||||
|
||||
// Clear endstop state for polled stallGuard endstops
|
||||
TERN_(SPI_ENDSTOPS, endstops.clear_endstop_state());
|
||||
|
||||
#if HAS_HOMING_CURRENT
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Restore driver current...");
|
||||
#if HAS_CURRENT_HOME(X)
|
||||
stepperX.rms_current(tmc_save_current_X);
|
||||
// Restore the active tool after homing
|
||||
#if HAS_MULTI_HOTEND && (DISABLED(DELTA) || ENABLED(DELTA_HOME_TO_SAFE_ZONE))
|
||||
tool_change(old_tool_index, TERN(PARKING_EXTRUDER, !pe_final_change_must_unpark, DISABLED(DUAL_X_CARRIAGE))); // Do move if one of these
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(X2)
|
||||
stepperX2.rms_current(tmc_save_current_X2);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(Y)
|
||||
stepperY.rms_current(tmc_save_current_Y);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(Y2)
|
||||
stepperY2.rms_current(tmc_save_current_Y2);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(Z) && ENABLED(DELTA)
|
||||
stepperZ.rms_current(tmc_save_current_Z);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(I)
|
||||
stepperI.rms_current(tmc_save_current_I);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(J)
|
||||
stepperJ.rms_current(tmc_save_current_J);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(K)
|
||||
stepperK.rms_current(tmc_save_current_K);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(U)
|
||||
stepperU.rms_current(tmc_save_current_U);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(V)
|
||||
stepperV.rms_current(tmc_save_current_V);
|
||||
#endif
|
||||
#if HAS_CURRENT_HOME(W)
|
||||
stepperW.rms_current(tmc_save_current_W);
|
||||
#endif
|
||||
#if SENSORLESS_STALLGUARD_DELAY
|
||||
safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
|
||||
#endif
|
||||
#endif // HAS_HOMING_CURRENT
|
||||
|
||||
// Move to a height where we can use the full xy-area
|
||||
TERN_(DELTA_HOME_TO_SAFE_ZONE, do_blocking_move_to_z(delta_clip_start_height));
|
||||
restore_feedrate_and_scaling();
|
||||
|
||||
// Move to the configured Z only if Z was homed to MIN, because machines that
|
||||
// home to MAX historically expect 'G28 Z' to be safe to use at the end of a
|
||||
// print, and do_move_after_z_homing is not very nuanced.
|
||||
if (finalRaiseZ) do_move_after_z_homing();
|
||||
if (ENABLED(NANODLP_Z_SYNC) && (ENABLED(NANODLP_ALL_AXIS) || TERN0(HAS_Z_AXIS, doZ)))
|
||||
SERIAL_ECHOLNPGM(STR_Z_MOVE_COMP);
|
||||
|
||||
TERN_(CAN_SET_LEVELING_AFTER_G28, if (leveling_restore_state) set_bed_leveling_enabled());
|
||||
|
||||
// Restore the active tool after homing
|
||||
#if HAS_MULTI_HOTEND && (DISABLED(DELTA) || ENABLED(DELTA_HOME_TO_SAFE_ZONE))
|
||||
tool_change(old_tool_index, TERN(PARKING_EXTRUDER, !pe_final_change_must_unpark, DISABLED(DUAL_X_CARRIAGE))); // Do move if one of these
|
||||
#endif
|
||||
|
||||
restore_feedrate_and_scaling();
|
||||
#endif // NUM_AXES
|
||||
|
||||
ui.refresh();
|
||||
|
||||
@ -645,9 +654,6 @@ void GcodeSuite::G28() {
|
||||
|
||||
report_current_position();
|
||||
|
||||
if (ENABLED(NANODLP_Z_SYNC) && (ENABLED(NANODLP_ALL_AXIS) || TERN0(HAS_Z_AXIS, doZ)))
|
||||
SERIAL_ECHOLNPGM(STR_Z_MOVE_COMP);
|
||||
|
||||
TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(old_grblstate));
|
||||
|
||||
}
|
||||
|
@ -70,7 +70,7 @@
|
||||
#define CALIBRATION_MEASUREMENT_CERTAIN 0.5 // mm
|
||||
#endif
|
||||
|
||||
#if BOTH(CALIBRATION_MEASURE_LEFT, CALIBRATION_MEASURE_RIGHT)
|
||||
#if ALL(HAS_X_AXIS, CALIBRATION_MEASURE_LEFT, CALIBRATION_MEASURE_RIGHT)
|
||||
#define HAS_X_CENTER 1
|
||||
#endif
|
||||
#if ALL(HAS_Y_AXIS, CALIBRATION_MEASURE_FRONT, CALIBRATION_MEASURE_BACK)
|
||||
@ -398,11 +398,13 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
|
||||
#if AXIS_CAN_CALIBRATE(Z)
|
||||
SERIAL_ECHOLNPGM(" Top: ", m.obj_side[TOP]);
|
||||
#endif
|
||||
#if ENABLED(CALIBRATION_MEASURE_LEFT)
|
||||
SERIAL_ECHOLNPGM(" Left: ", m.obj_side[LEFT]);
|
||||
#endif
|
||||
#if ENABLED(CALIBRATION_MEASURE_RIGHT)
|
||||
SERIAL_ECHOLNPGM(" Right: ", m.obj_side[RIGHT]);
|
||||
#if HAS_X_AXIS
|
||||
#if ENABLED(CALIBRATION_MEASURE_LEFT)
|
||||
SERIAL_ECHOLNPGM(" Left: ", m.obj_side[LEFT]);
|
||||
#endif
|
||||
#if ENABLED(CALIBRATION_MEASURE_RIGHT)
|
||||
SERIAL_ECHOLNPGM(" Right: ", m.obj_side[RIGHT]);
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
#if ENABLED(CALIBRATION_MEASURE_FRONT)
|
||||
|
@ -112,17 +112,19 @@ void GcodeSuite::M425_report(const bool forReplay/*=true*/) {
|
||||
#ifdef BACKLASH_SMOOTHING_MM
|
||||
, PSTR(" S"), LINEAR_UNIT(backlash.get_smoothing_mm())
|
||||
#endif
|
||||
, LIST_N(DOUBLE(NUM_AXES),
|
||||
SP_X_STR, LINEAR_UNIT(backlash.get_distance_mm(X_AXIS)),
|
||||
SP_Y_STR, LINEAR_UNIT(backlash.get_distance_mm(Y_AXIS)),
|
||||
SP_Z_STR, LINEAR_UNIT(backlash.get_distance_mm(Z_AXIS)),
|
||||
SP_I_STR, I_AXIS_UNIT(backlash.get_distance_mm(I_AXIS)),
|
||||
SP_J_STR, J_AXIS_UNIT(backlash.get_distance_mm(J_AXIS)),
|
||||
SP_K_STR, K_AXIS_UNIT(backlash.get_distance_mm(K_AXIS)),
|
||||
SP_U_STR, U_AXIS_UNIT(backlash.get_distance_mm(U_AXIS)),
|
||||
SP_V_STR, V_AXIS_UNIT(backlash.get_distance_mm(V_AXIS)),
|
||||
SP_W_STR, W_AXIS_UNIT(backlash.get_distance_mm(W_AXIS))
|
||||
)
|
||||
#if NUM_AXES
|
||||
, LIST_N(DOUBLE(NUM_AXES),
|
||||
SP_X_STR, LINEAR_UNIT(backlash.get_distance_mm(X_AXIS)),
|
||||
SP_Y_STR, LINEAR_UNIT(backlash.get_distance_mm(Y_AXIS)),
|
||||
SP_Z_STR, LINEAR_UNIT(backlash.get_distance_mm(Z_AXIS)),
|
||||
SP_I_STR, I_AXIS_UNIT(backlash.get_distance_mm(I_AXIS)),
|
||||
SP_J_STR, J_AXIS_UNIT(backlash.get_distance_mm(J_AXIS)),
|
||||
SP_K_STR, K_AXIS_UNIT(backlash.get_distance_mm(K_AXIS)),
|
||||
SP_U_STR, U_AXIS_UNIT(backlash.get_distance_mm(U_AXIS)),
|
||||
SP_V_STR, V_AXIS_UNIT(backlash.get_distance_mm(V_AXIS)),
|
||||
SP_W_STR, W_AXIS_UNIT(backlash.get_distance_mm(W_AXIS))
|
||||
)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -143,22 +143,30 @@ void GcodeSuite::M201() {
|
||||
|
||||
void GcodeSuite::M201_report(const bool forReplay/*=true*/) {
|
||||
report_heading_etc(forReplay, F(STR_MAX_ACCELERATION));
|
||||
SERIAL_ECHOLNPGM_P(
|
||||
LIST_N(DOUBLE(NUM_AXES),
|
||||
PSTR(" M201 X"), LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[X_AXIS]),
|
||||
SP_Y_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Y_AXIS]),
|
||||
SP_Z_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Z_AXIS]),
|
||||
SP_I_STR, I_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[I_AXIS]),
|
||||
SP_J_STR, J_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[J_AXIS]),
|
||||
SP_K_STR, K_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[K_AXIS]),
|
||||
SP_U_STR, U_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[U_AXIS]),
|
||||
SP_V_STR, V_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[V_AXIS]),
|
||||
SP_W_STR, W_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[W_AXIS])
|
||||
)
|
||||
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
|
||||
, SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_acceleration_mm_per_s2[E_AXIS])
|
||||
#endif
|
||||
);
|
||||
#if NUM_AXES
|
||||
SERIAL_ECHOPGM_P(
|
||||
LIST_N(DOUBLE(NUM_AXES),
|
||||
PSTR(" M201 X"), LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[X_AXIS]),
|
||||
SP_Y_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Y_AXIS]),
|
||||
SP_Z_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Z_AXIS]),
|
||||
SP_I_STR, I_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[I_AXIS]),
|
||||
SP_J_STR, J_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[J_AXIS]),
|
||||
SP_K_STR, K_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[K_AXIS]),
|
||||
SP_U_STR, U_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[U_AXIS]),
|
||||
SP_V_STR, V_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[V_AXIS]),
|
||||
SP_W_STR, W_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[W_AXIS])
|
||||
)
|
||||
);
|
||||
#endif
|
||||
|
||||
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
|
||||
SERIAL_ECHOPGM_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_acceleration_mm_per_s2[E_AXIS]));
|
||||
#endif
|
||||
|
||||
#if NUM_AXES || (HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS))
|
||||
SERIAL_EOL();
|
||||
#endif
|
||||
|
||||
#if ENABLED(DISTINCT_E_FACTORS)
|
||||
LOOP_L_N(i, E_STEPPERS) {
|
||||
report_echo_start(forReplay);
|
||||
@ -191,22 +199,30 @@ void GcodeSuite::M203() {
|
||||
|
||||
void GcodeSuite::M203_report(const bool forReplay/*=true*/) {
|
||||
report_heading_etc(forReplay, F(STR_MAX_FEEDRATES));
|
||||
SERIAL_ECHOLNPGM_P(
|
||||
LIST_N(DOUBLE(NUM_AXES),
|
||||
PSTR(" M203 X"), LINEAR_UNIT(planner.settings.max_feedrate_mm_s[X_AXIS]),
|
||||
SP_Y_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Y_AXIS]),
|
||||
SP_Z_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Z_AXIS]),
|
||||
SP_I_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[I_AXIS]),
|
||||
SP_J_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[J_AXIS]),
|
||||
SP_K_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[K_AXIS]),
|
||||
SP_U_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[U_AXIS]),
|
||||
SP_V_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[V_AXIS]),
|
||||
SP_W_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[W_AXIS])
|
||||
)
|
||||
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
|
||||
, SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_feedrate_mm_s[E_AXIS])
|
||||
#endif
|
||||
);
|
||||
#if NUM_AXES
|
||||
SERIAL_ECHOPGM_P(
|
||||
LIST_N(DOUBLE(NUM_AXES),
|
||||
PSTR(" M203 X"), LINEAR_UNIT(planner.settings.max_feedrate_mm_s[X_AXIS]),
|
||||
SP_Y_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Y_AXIS]),
|
||||
SP_Z_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Z_AXIS]),
|
||||
SP_I_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[I_AXIS]),
|
||||
SP_J_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[J_AXIS]),
|
||||
SP_K_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[K_AXIS]),
|
||||
SP_U_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[U_AXIS]),
|
||||
SP_V_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[V_AXIS]),
|
||||
SP_W_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[W_AXIS])
|
||||
)
|
||||
);
|
||||
#endif
|
||||
|
||||
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
|
||||
SERIAL_ECHOPGM_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_feedrate_mm_s[E_AXIS]));
|
||||
#endif
|
||||
|
||||
#if NUM_AXES || (HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS))
|
||||
SERIAL_EOL();
|
||||
#endif
|
||||
|
||||
#if ENABLED(DISTINCT_E_FACTORS)
|
||||
LOOP_L_N(i, E_STEPPERS) {
|
||||
if (!forReplay) SERIAL_ECHO_START();
|
||||
@ -336,7 +352,7 @@ void GcodeSuite::M205_report(const bool forReplay/*=true*/) {
|
||||
#if HAS_JUNCTION_DEVIATION
|
||||
, PSTR(" J"), LINEAR_UNIT(planner.junction_deviation_mm)
|
||||
#endif
|
||||
#if HAS_CLASSIC_JERK
|
||||
#if HAS_CLASSIC_JERK && NUM_AXES
|
||||
, LIST_N(DOUBLE(NUM_AXES),
|
||||
SP_X_STR, LINEAR_UNIT(planner.max_jerk.x),
|
||||
SP_Y_STR, LINEAR_UNIT(planner.max_jerk.y),
|
||||
|
@ -95,7 +95,9 @@ void GcodeSuite::M217() {
|
||||
|
||||
#if ENABLED(TOOLCHANGE_PARK)
|
||||
if (parser.seenval('W')) { toolchange_settings.enable_park = parser.value_linear_units(); }
|
||||
if (parser.seenval('X')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.x = constrain(v, X_MIN_POS, X_MAX_POS); }
|
||||
#if HAS_X_AXIS
|
||||
if (parser.seenval('X')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.x = constrain(v, X_MIN_POS, X_MAX_POS); }
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
if (parser.seenval('Y')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.y = constrain(v, Y_MIN_POS, Y_MAX_POS); }
|
||||
#endif
|
||||
@ -183,25 +185,27 @@ void GcodeSuite::M217_report(const bool forReplay/*=true*/) {
|
||||
#endif
|
||||
|
||||
#if ENABLED(TOOLCHANGE_PARK)
|
||||
{
|
||||
SERIAL_ECHOPGM(" W", LINEAR_UNIT(toolchange_settings.enable_park));
|
||||
SERIAL_ECHOPGM_P(
|
||||
SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x)
|
||||
#if HAS_Y_AXIS
|
||||
, SP_Y_STR, LINEAR_UNIT(toolchange_settings.change_point.y)
|
||||
#endif
|
||||
#if SECONDARY_AXES >= 1
|
||||
, LIST_N(DOUBLE(SECONDARY_AXES)
|
||||
, SP_I_STR, I_AXIS_UNIT(toolchange_settings.change_point.i)
|
||||
, SP_J_STR, J_AXIS_UNIT(toolchange_settings.change_point.j)
|
||||
, SP_K_STR, K_AXIS_UNIT(toolchange_settings.change_point.k)
|
||||
, SP_C_STR, U_AXIS_UNIT(toolchange_settings.change_point.u)
|
||||
, PSTR(" H"), V_AXIS_UNIT(toolchange_settings.change_point.v)
|
||||
, PSTR(" O"), W_AXIS_UNIT(toolchange_settings.change_point.w)
|
||||
)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
#if NUM_AXES
|
||||
{
|
||||
SERIAL_ECHOPGM_P(
|
||||
SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x)
|
||||
#if HAS_Y_AXIS
|
||||
, SP_Y_STR, LINEAR_UNIT(toolchange_settings.change_point.y)
|
||||
#endif
|
||||
#if SECONDARY_AXES >= 1
|
||||
, LIST_N(DOUBLE(SECONDARY_AXES)
|
||||
, SP_I_STR, I_AXIS_UNIT(toolchange_settings.change_point.i)
|
||||
, SP_J_STR, J_AXIS_UNIT(toolchange_settings.change_point.j)
|
||||
, SP_K_STR, K_AXIS_UNIT(toolchange_settings.change_point.k)
|
||||
, SP_C_STR, U_AXIS_UNIT(toolchange_settings.change_point.u)
|
||||
, PSTR(" H"), V_AXIS_UNIT(toolchange_settings.change_point.v)
|
||||
, PSTR(" O"), W_AXIS_UNIT(toolchange_settings.change_point.w)
|
||||
)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
|
||||
|
@ -46,9 +46,15 @@ void GcodeSuite::M218() {
|
||||
const int8_t target_extruder = get_target_extruder_from_command();
|
||||
if (target_extruder < 0) return;
|
||||
|
||||
if (parser.seenval('X')) hotend_offset[target_extruder].x = parser.value_linear_units();
|
||||
if (parser.seenval('Y')) hotend_offset[target_extruder].y = parser.value_linear_units();
|
||||
if (parser.seenval('Z')) hotend_offset[target_extruder].z = parser.value_linear_units();
|
||||
#if HAS_X_AXIS
|
||||
if (parser.seenval('X')) hotend_offset[target_extruder].x = parser.value_linear_units();
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
if (parser.seenval('Y')) hotend_offset[target_extruder].y = parser.value_linear_units();
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
if (parser.seenval('Z')) hotend_offset[target_extruder].z = parser.value_linear_units();
|
||||
#endif
|
||||
|
||||
#if ENABLED(DELTA)
|
||||
if (target_extruder == active_extruder)
|
||||
|
@ -92,21 +92,27 @@ void GcodeSuite::M92() {
|
||||
|
||||
void GcodeSuite::M92_report(const bool forReplay/*=true*/, const int8_t e/*=-1*/) {
|
||||
report_heading_etc(forReplay, F(STR_STEPS_PER_UNIT));
|
||||
SERIAL_ECHOPGM_P(LIST_N(DOUBLE(NUM_AXES),
|
||||
PSTR(" M92 X"), LINEAR_UNIT(planner.settings.axis_steps_per_mm[X_AXIS]),
|
||||
SP_Y_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Y_AXIS]),
|
||||
SP_Z_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Z_AXIS]),
|
||||
SP_I_STR, I_AXIS_UNIT(planner.settings.axis_steps_per_mm[I_AXIS]),
|
||||
SP_J_STR, J_AXIS_UNIT(planner.settings.axis_steps_per_mm[J_AXIS]),
|
||||
SP_K_STR, K_AXIS_UNIT(planner.settings.axis_steps_per_mm[K_AXIS]),
|
||||
SP_U_STR, U_AXIS_UNIT(planner.settings.axis_steps_per_mm[U_AXIS]),
|
||||
SP_V_STR, V_AXIS_UNIT(planner.settings.axis_steps_per_mm[V_AXIS]),
|
||||
SP_W_STR, W_AXIS_UNIT(planner.settings.axis_steps_per_mm[W_AXIS])
|
||||
));
|
||||
#if NUM_AXES
|
||||
SERIAL_ECHOPGM_P(LIST_N(DOUBLE(NUM_AXES),
|
||||
PSTR(" M92 X"), LINEAR_UNIT(planner.settings.axis_steps_per_mm[X_AXIS]),
|
||||
SP_Y_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Y_AXIS]),
|
||||
SP_Z_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Z_AXIS]),
|
||||
SP_I_STR, I_AXIS_UNIT(planner.settings.axis_steps_per_mm[I_AXIS]),
|
||||
SP_J_STR, J_AXIS_UNIT(planner.settings.axis_steps_per_mm[J_AXIS]),
|
||||
SP_K_STR, K_AXIS_UNIT(planner.settings.axis_steps_per_mm[K_AXIS]),
|
||||
SP_U_STR, U_AXIS_UNIT(planner.settings.axis_steps_per_mm[U_AXIS]),
|
||||
SP_V_STR, V_AXIS_UNIT(planner.settings.axis_steps_per_mm[V_AXIS]),
|
||||
SP_W_STR, W_AXIS_UNIT(planner.settings.axis_steps_per_mm[W_AXIS])
|
||||
));
|
||||
#endif
|
||||
|
||||
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
|
||||
SERIAL_ECHOPGM_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS]));
|
||||
#endif
|
||||
SERIAL_EOL();
|
||||
|
||||
#if NUM_AXES || (HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS))
|
||||
SERIAL_EOL();
|
||||
#endif
|
||||
|
||||
#if ENABLED(DISTINCT_E_FACTORS)
|
||||
LOOP_L_N(i, E_STEPPERS) {
|
||||
|
@ -48,17 +48,19 @@ inline stepper_flags_t selected_axis_bits() {
|
||||
selected.bits = e_axis_mask;
|
||||
}
|
||||
#endif
|
||||
selected.bits |= NUM_AXIS_GANG(
|
||||
(parser.seen_test('X') << X_AXIS),
|
||||
| (parser.seen_test('Y') << Y_AXIS),
|
||||
| (parser.seen_test('Z') << Z_AXIS),
|
||||
| (parser.seen_test(AXIS4_NAME) << I_AXIS),
|
||||
| (parser.seen_test(AXIS5_NAME) << J_AXIS),
|
||||
| (parser.seen_test(AXIS6_NAME) << K_AXIS),
|
||||
| (parser.seen_test(AXIS7_NAME) << U_AXIS),
|
||||
| (parser.seen_test(AXIS8_NAME) << V_AXIS),
|
||||
| (parser.seen_test(AXIS9_NAME) << W_AXIS)
|
||||
);
|
||||
#if NUM_AXES
|
||||
selected.bits |= NUM_AXIS_GANG(
|
||||
(parser.seen_test('X') << X_AXIS),
|
||||
| (parser.seen_test('Y') << Y_AXIS),
|
||||
| (parser.seen_test('Z') << Z_AXIS),
|
||||
| (parser.seen_test(AXIS4_NAME) << I_AXIS),
|
||||
| (parser.seen_test(AXIS5_NAME) << J_AXIS),
|
||||
| (parser.seen_test(AXIS6_NAME) << K_AXIS),
|
||||
| (parser.seen_test(AXIS7_NAME) << U_AXIS),
|
||||
| (parser.seen_test(AXIS8_NAME) << V_AXIS),
|
||||
| (parser.seen_test(AXIS9_NAME) << W_AXIS)
|
||||
);
|
||||
#endif
|
||||
return selected;
|
||||
}
|
||||
|
||||
|
@ -50,16 +50,19 @@ void GcodeSuite::G60() {
|
||||
{
|
||||
const xyze_pos_t &pos = stored_position[slot];
|
||||
DEBUG_ECHOPGM(STR_SAVED_POS " S", slot, " :");
|
||||
DEBUG_ECHOLNPGM_P(
|
||||
LIST_N(DOUBLE(NUM_AXES),
|
||||
SP_X_LBL, pos.x, SP_Y_LBL, pos.y, SP_Z_LBL, pos.z,
|
||||
SP_I_LBL, pos.i, SP_J_LBL, pos.j, SP_K_LBL, pos.k,
|
||||
SP_U_LBL, pos.u, SP_V_LBL, pos.v, SP_W_LBL, pos.w
|
||||
)
|
||||
#if HAS_EXTRUDERS
|
||||
, SP_E_LBL, pos.e
|
||||
#endif
|
||||
);
|
||||
#if NUM_AXES
|
||||
DEBUG_ECHOPGM_P(
|
||||
LIST_N(DOUBLE(NUM_AXES),
|
||||
SP_X_LBL, pos.x, SP_Y_LBL, pos.y, SP_Z_LBL, pos.z,
|
||||
SP_I_LBL, pos.i, SP_J_LBL, pos.j, SP_K_LBL, pos.k,
|
||||
SP_U_LBL, pos.u, SP_V_LBL, pos.v, SP_W_LBL, pos.w
|
||||
)
|
||||
);
|
||||
#endif
|
||||
#if HAS_EXTRUDERS
|
||||
DEBUG_ECHOPGM_P(SP_E_LBL, pos.e);
|
||||
#endif
|
||||
DEBUG_EOL();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -57,10 +57,12 @@ static void set_stealth_status(const bool enable, const int8_t eindex) {
|
||||
|
||||
LOOP_LOGICAL_AXES(i) if (parser.seen(AXIS_CHAR(i))) {
|
||||
switch (i) {
|
||||
case X_AXIS:
|
||||
TERN_(X_HAS_STEALTHCHOP, if (index < 0 || index == 0) TMC_SET_STEALTH(X));
|
||||
TERN_(X2_HAS_STEALTHCHOP, if (index < 0 || index == 1) TMC_SET_STEALTH(X2));
|
||||
break;
|
||||
#if HAS_X_AXIS
|
||||
case X_AXIS:
|
||||
TERN_(X_HAS_STEALTHCHOP, if (index < 0 || index == 0) TMC_SET_STEALTH(X));
|
||||
TERN_(X2_HAS_STEALTHCHOP, if (index < 0 || index == 1) TMC_SET_STEALTH(X2));
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
case Y_AXIS:
|
||||
@ -198,13 +200,13 @@ void GcodeSuite::M569_report(const bool forReplay/*=true*/) {
|
||||
|
||||
if (chop_x2 || chop_y2 || chop_z2) {
|
||||
say_M569(forReplay, F("I1"));
|
||||
if (chop_x2) SERIAL_ECHOPGM_P(SP_X_STR);
|
||||
#if HAS_Y_AXIS
|
||||
if (chop_y2) SERIAL_ECHOPGM_P(SP_Y_STR);
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
if (chop_z2) SERIAL_ECHOPGM_P(SP_Z_STR);
|
||||
#endif
|
||||
NUM_AXIS_CODE(
|
||||
if (chop_x2) SERIAL_ECHOPGM_P(SP_X_STR),
|
||||
if (chop_y2) SERIAL_ECHOPGM_P(SP_Y_STR),
|
||||
if (chop_z2) SERIAL_ECHOPGM_P(SP_Z_STR),
|
||||
NOOP, NOOP, NOOP,
|
||||
NOOP, NOOP, NOOP
|
||||
);
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
||||
#define M91x_USE(ST) (AXIS_DRIVER_TYPE(ST, TMC2130) || AXIS_DRIVER_TYPE(ST, TMC2160) || AXIS_DRIVER_TYPE(ST, TMC2208) || AXIS_DRIVER_TYPE(ST, TMC2209) || AXIS_DRIVER_TYPE(ST, TMC2660) || AXIS_DRIVER_TYPE(ST, TMC5130) || AXIS_DRIVER_TYPE(ST, TMC5160))
|
||||
#define M91x_USE_E(N) (E_STEPPERS > N && M91x_USE(E##N))
|
||||
|
||||
#if M91x_USE(X) || M91x_USE(X2)
|
||||
#if HAS_X_AXIS && (M91x_USE(X) || M91x_USE(X2))
|
||||
#define M91x_SOME_X 1
|
||||
#endif
|
||||
#if HAS_Y_AXIS && (M91x_USE(Y) || M91x_USE(Y2))
|
||||
|
@ -796,10 +796,14 @@
|
||||
#define NUM_AXES 3
|
||||
#elif defined(Y_DRIVER_TYPE)
|
||||
#define NUM_AXES 2
|
||||
#else
|
||||
#elif defined(X_DRIVER_TYPE)
|
||||
#define NUM_AXES 1
|
||||
#else
|
||||
#define NUM_AXES 0
|
||||
#endif
|
||||
#if NUM_AXES >= 1
|
||||
#define HAS_X_AXIS 1
|
||||
#endif
|
||||
#define HAS_X_AXIS 1
|
||||
#if NUM_AXES >= XY
|
||||
#define HAS_Y_AXIS 1
|
||||
#endif
|
||||
@ -825,6 +829,23 @@
|
||||
#define HAS_W_AXIS 1
|
||||
#endif
|
||||
|
||||
#if !HAS_X_AXIS
|
||||
#undef ENDSTOPPULLUP_XMIN
|
||||
#undef ENDSTOPPULLUP_XMAX
|
||||
#undef X_MIN_ENDSTOP_INVERTING
|
||||
#undef X_MAX_ENDSTOP_INVERTING
|
||||
#undef X2_DRIVER_TYPE
|
||||
#undef X_ENABLE_ON
|
||||
#undef DISABLE_X
|
||||
#undef INVERT_X_DIR
|
||||
#undef X_HOME_DIR
|
||||
#undef X_MIN_POS
|
||||
#undef X_MAX_POS
|
||||
#undef MANUAL_X_HOME_POS
|
||||
#undef MIN_SOFTWARE_ENDSTOPS
|
||||
#undef MAX_SOFTWARE_ENDSTOPS
|
||||
#endif
|
||||
|
||||
#if !HAS_Y_AXIS
|
||||
#undef AVOID_OBSTACLES
|
||||
#undef ENDSTOPPULLUP_YMIN
|
||||
@ -1318,10 +1339,12 @@
|
||||
#endif // FILAMENT_SWITCH_AND_MOTION
|
||||
|
||||
// Homing to Min or Max
|
||||
#if X_HOME_DIR > 0
|
||||
#define X_HOME_TO_MAX 1
|
||||
#elif X_HOME_DIR < 0
|
||||
#define X_HOME_TO_MIN 1
|
||||
#if HAS_X_AXIS
|
||||
#if X_HOME_DIR > 0
|
||||
#define X_HOME_TO_MAX 1
|
||||
#elif X_HOME_DIR < 0
|
||||
#define X_HOME_TO_MIN 1
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
#if Y_HOME_DIR > 0
|
||||
|
@ -94,8 +94,26 @@
|
||||
#endif
|
||||
|
||||
// Some options are disallowed without required axes
|
||||
#if !HAS_X_AXIS
|
||||
//#define LCD_SHOW_E_TOTAL
|
||||
#define NO_WORKSPACE_OFFSETS
|
||||
#undef AUTOTEMP
|
||||
#undef CALIBRATION_MEASURE_LEFT
|
||||
#undef CALIBRATION_MEASURE_RIGHT
|
||||
#undef CALIBRATION_MEASURE_XMAX
|
||||
#undef CALIBRATION_MEASURE_XMIN
|
||||
#undef DISABLE_IDLE_X
|
||||
#undef INPUT_SHAPING_X
|
||||
#undef SAFE_BED_LEVELING_START_X
|
||||
#undef SHAPING_BUFFER_X
|
||||
#undef SHAPING_FREQ_X
|
||||
#undef STEALTHCHOP_X
|
||||
#endif
|
||||
|
||||
#if !HAS_Y_AXIS
|
||||
#undef ARC_SUPPORT
|
||||
#undef CALIBRATION_MEASURE_BACK
|
||||
#undef CALIBRATION_MEASURE_FRONT
|
||||
#undef CALIBRATION_MEASURE_YMAX
|
||||
#undef CALIBRATION_MEASURE_YMIN
|
||||
#undef DISABLE_IDLE_Y
|
||||
|
@ -105,7 +105,9 @@
|
||||
#define HAS_ROTATIONAL_AXES 1
|
||||
#endif
|
||||
|
||||
#define X_MAX_LENGTH (X_MAX_POS - (X_MIN_POS))
|
||||
#if HAS_X_AXIS
|
||||
#define X_MAX_LENGTH (X_MAX_POS - (X_MIN_POS))
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
#define Y_MAX_LENGTH (Y_MAX_POS - (Y_MIN_POS))
|
||||
#endif
|
||||
@ -134,7 +136,7 @@
|
||||
#endif
|
||||
|
||||
// Defined only if the sanity-check is bypassed
|
||||
#ifndef X_BED_SIZE
|
||||
#if HAS_X_AXIS && !defined(X_BED_SIZE)
|
||||
#define X_BED_SIZE X_MAX_LENGTH
|
||||
#endif
|
||||
#if HAS_Y_AXIS && !defined(Y_BED_SIZE)
|
||||
@ -165,7 +167,9 @@
|
||||
#endif
|
||||
|
||||
// Define center values for future use
|
||||
#define _X_HALF_BED ((X_BED_SIZE) / 2)
|
||||
#if HAS_X_AXIS
|
||||
#define _X_HALF_BED ((X_BED_SIZE) / 2)
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
#define _Y_HALF_BED ((Y_BED_SIZE) / 2)
|
||||
#endif
|
||||
@ -188,7 +192,9 @@
|
||||
#define _W_HALF_WMAX ((W_BED_SIZE) / 2)
|
||||
#endif
|
||||
|
||||
#define X_CENTER TERN(BED_CENTER_AT_0_0, 0, _X_HALF_BED)
|
||||
#if HAS_X_AXIS
|
||||
#define X_CENTER TERN(BED_CENTER_AT_0_0, 0, _X_HALF_BED)
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
#define Y_CENTER TERN(BED_CENTER_AT_0_0, 0, _Y_HALF_BED)
|
||||
#define XY_CENTER { X_CENTER, Y_CENTER }
|
||||
@ -213,8 +219,10 @@
|
||||
#endif
|
||||
|
||||
// Get the linear boundaries of the bed
|
||||
#define X_MIN_BED (X_CENTER - _X_HALF_BED)
|
||||
#define X_MAX_BED (X_MIN_BED + X_BED_SIZE)
|
||||
#if HAS_X_AXIS
|
||||
#define X_MIN_BED (X_CENTER - _X_HALF_BED)
|
||||
#define X_MAX_BED (X_MIN_BED + X_BED_SIZE)
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
#define Y_MIN_BED (Y_CENTER - _Y_HALF_BED)
|
||||
#define Y_MAX_BED (Y_MIN_BED + Y_BED_SIZE)
|
||||
@ -292,14 +300,16 @@
|
||||
/**
|
||||
* Set the home position based on settings or manual overrides
|
||||
*/
|
||||
#ifdef MANUAL_X_HOME_POS
|
||||
#define X_HOME_POS MANUAL_X_HOME_POS
|
||||
#else
|
||||
#define X_END_POS TERN(X_HOME_TO_MIN, X_MIN_POS, X_MAX_POS)
|
||||
#if ENABLED(BED_CENTER_AT_0_0)
|
||||
#define X_HOME_POS TERN(DELTA, 0, X_END_POS)
|
||||
#if HAS_X_AXIS
|
||||
#ifdef MANUAL_X_HOME_POS
|
||||
#define X_HOME_POS MANUAL_X_HOME_POS
|
||||
#else
|
||||
#define X_HOME_POS TERN(DELTA, X_MIN_POS + (X_BED_SIZE) * 0.5, X_END_POS)
|
||||
#define X_END_POS TERN(X_HOME_TO_MIN, X_MIN_POS, X_MAX_POS)
|
||||
#if ENABLED(BED_CENTER_AT_0_0)
|
||||
#define X_HOME_POS TERN(DELTA, 0, X_END_POS)
|
||||
#else
|
||||
#define X_HOME_POS TERN(DELTA, X_MIN_POS + (X_BED_SIZE) * 0.5, X_END_POS)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -1021,30 +1031,32 @@
|
||||
*/
|
||||
|
||||
// Steppers
|
||||
#if PIN_EXISTS(X_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(X))
|
||||
#define HAS_X_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(X_DIR)
|
||||
#define HAS_X_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(X_STEP)
|
||||
#define HAS_X_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(X_MS1)
|
||||
#define HAS_X_MS_PINS 1
|
||||
#endif
|
||||
#if HAS_X_AXIS
|
||||
#if PIN_EXISTS(X_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(X))
|
||||
#define HAS_X_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(X_DIR)
|
||||
#define HAS_X_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(X_STEP)
|
||||
#define HAS_X_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(X_MS1)
|
||||
#define HAS_X_MS_PINS 1
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(X2_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(X2))
|
||||
#define HAS_X2_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(X2_DIR)
|
||||
#define HAS_X2_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(X2_STEP)
|
||||
#define HAS_X2_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(X2_MS1)
|
||||
#define HAS_X2_MS_PINS 1
|
||||
#if PIN_EXISTS(X2_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(X2))
|
||||
#define HAS_X2_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(X2_DIR)
|
||||
#define HAS_X2_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(X2_STEP)
|
||||
#define HAS_X2_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(X2_MS1)
|
||||
#define HAS_X2_MS_PINS 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -260,7 +260,7 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L
|
||||
* Validate bed size
|
||||
*/
|
||||
#if !defined(X_BED_SIZE) || !defined(Y_BED_SIZE)
|
||||
#error "X_BED_SIZE and Y_BED_SIZE are now required!"
|
||||
#error "X_BED_SIZE and Y_BED_SIZE are required!"
|
||||
#else
|
||||
#if HAS_X_AXIS
|
||||
static_assert(X_MAX_LENGTH >= X_BED_SIZE, "Movement bounds (X_MIN_POS, X_MAX_POS) are too narrow to contain X_BED_SIZE.");
|
||||
@ -3372,9 +3372,11 @@ static_assert(COUNT(sanity_arr_3) >= LOGICAL_AXES, "DEFAULT_MAX_ACCELERATION re
|
||||
static_assert(COUNT(sanity_arr_3) <= DISTINCT_AXES, "DEFAULT_MAX_ACCELERATION has too many elements." _EXTRA_NOTE);
|
||||
static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive.");
|
||||
|
||||
constexpr float sanity_arr_4[] = HOMING_FEEDRATE_MM_M;
|
||||
static_assert(COUNT(sanity_arr_4) == NUM_AXES, "HOMING_FEEDRATE_MM_M requires " _NUM_AXES_STR "elements (and no others).");
|
||||
static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive.");
|
||||
#if NUM_AXES
|
||||
constexpr float sanity_arr_4[] = HOMING_FEEDRATE_MM_M;
|
||||
static_assert(COUNT(sanity_arr_4) == NUM_AXES, "HOMING_FEEDRATE_MM_M requires " _NUM_AXES_STR "elements (and no others).");
|
||||
static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive.");
|
||||
#endif
|
||||
|
||||
#ifdef MAX_ACCEL_EDIT_VALUES
|
||||
constexpr float sanity_arr_5[] = MAX_ACCEL_EDIT_VALUES;
|
||||
@ -3571,7 +3573,7 @@ static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive.");
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
#error "DUAL_X_CARRIAGE requires both MIN_ and MAX_SOFTWARE_ENDSTOPS."
|
||||
#elif HAS_HOTEND_OFFSET
|
||||
#error "MIN_ and MAX_SOFTWARE_ENDSTOPS are both required with offset hotends."
|
||||
#error "Multi-hotends with offset requires both MIN_ and MAX_SOFTWARE_ENDSTOPS."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -975,7 +975,7 @@ void MarlinUI::draw_status_screen() {
|
||||
|
||||
#else // !HAS_DUAL_MIXING
|
||||
|
||||
const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive());
|
||||
const bool show_e_total = TERN1(HAS_X_AXIS, TERN0(LCD_SHOW_E_TOTAL, printingIsActive()));
|
||||
|
||||
if (show_e_total) {
|
||||
#if ENABLED(LCD_SHOW_E_TOTAL)
|
||||
@ -986,10 +986,14 @@ void MarlinUI::draw_status_screen() {
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
const xy_pos_t lpos = current_position.asLogical();
|
||||
_draw_axis_value(X_AXIS, ftostr4sign(lpos.x), blink);
|
||||
lcd_put_u8str(F(" "));
|
||||
_draw_axis_value(Y_AXIS, ftostr4sign(lpos.y), blink);
|
||||
#if HAS_X_AXIS
|
||||
const xy_pos_t lpos = current_position.asLogical();
|
||||
_draw_axis_value(X_AXIS, ftostr4sign(lpos.x), blink);
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
TERN_(HAS_X_AXIS, lcd_put_u8str(F(" ")));
|
||||
_draw_axis_value(Y_AXIS, ftostr4sign(lpos.y), blink);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // !HAS_DUAL_MIXING
|
||||
@ -1065,8 +1069,10 @@ void MarlinUI::draw_status_screen() {
|
||||
//
|
||||
// Z Coordinate
|
||||
//
|
||||
lcd_moveto(LCD_WIDTH - 9, 0);
|
||||
_draw_axis_value(Z_AXIS, ftostr52sp(LOGICAL_Z_POSITION(current_position.z)), blink);
|
||||
#if HAS_Z_AXIS
|
||||
lcd_moveto(LCD_WIDTH - 9, 0);
|
||||
_draw_axis_value(Z_AXIS, ftostr52sp(LOGICAL_Z_POSITION(current_position.z)), blink);
|
||||
#endif
|
||||
|
||||
#if HAS_LEVELING && (HAS_MULTI_HOTEND || !HAS_HEATED_BED)
|
||||
lcd_put_lchar(LCD_WIDTH - 1, 0, planner.leveling_active || blink ? '_' : ' ');
|
||||
|
@ -820,11 +820,17 @@ void MarlinUI::draw_status_screen() {
|
||||
// Line 1 - XYZ coordinates
|
||||
//
|
||||
|
||||
lcd_moveto(0, 0);
|
||||
const xyz_pos_t lpos = current_position.asLogical();
|
||||
_draw_axis_value(X_AXIS, ftostr4sign(lpos.x), blink); lcd.write(' ');
|
||||
_draw_axis_value(Y_AXIS, ftostr4sign(lpos.y), blink); lcd.write(' ');
|
||||
_draw_axis_value(Z_AXIS, ftostr52sp(lpos.z), blink);
|
||||
#if NUM_AXES
|
||||
lcd_moveto(0, 0);
|
||||
const xyz_pos_t lpos = current_position.asLogical();
|
||||
_draw_axis_value(X_AXIS, ftostr4sign(lpos.x), blink);
|
||||
#if HAS_Y_AXIS
|
||||
lcd.write(' '); _draw_axis_value(Y_AXIS, ftostr4sign(lpos.y), blink);
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
lcd.write(' '); _draw_axis_value(Z_AXIS, ftostr52sp(lpos.z), blink);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_LEVELING && !HAS_HEATED_BED
|
||||
lcd.write(planner.leveling_active || blink ? '_' : ' ');
|
||||
|
@ -510,20 +510,24 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
|
||||
* Use the PAGE_CONTAINS macros to avoid pointless draw calls.
|
||||
*/
|
||||
void MarlinUI::draw_status_screen() {
|
||||
constexpr int xystorage = TERN(INCH_MODE_SUPPORT, 8, 5);
|
||||
static char xstring[TERN(LCD_SHOW_E_TOTAL, 12, xystorage)];
|
||||
#if HAS_Y_AXIS
|
||||
static char ystring[xystorage];
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
static char zstring[8];
|
||||
#if NUM_AXES
|
||||
constexpr int xystorage = TERN(INCH_MODE_SUPPORT, 8, 5);
|
||||
#if EITHER(HAS_X_AXIS, LCD_SHOW_E_TOTAL)
|
||||
static char xstring[TERN(LCD_SHOW_E_TOTAL, 12, xystorage)];
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
static char ystring[xystorage];
|
||||
#endif
|
||||
#if HAS_Z_AXIS
|
||||
static char zstring[8];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ENABLED(FILAMENT_LCD_DISPLAY)
|
||||
static char wstring[5], mstring[4];
|
||||
#endif
|
||||
|
||||
const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive());
|
||||
const bool show_e_total = TERN1(HAS_X_AXIS, TERN0(LCD_SHOW_E_TOTAL, printingIsActive()));
|
||||
|
||||
#if HAS_PRINT_PROGRESS
|
||||
static u8g_uint_t progress_bar_solid_width = 0;
|
||||
@ -544,10 +548,9 @@ void MarlinUI::draw_status_screen() {
|
||||
draw_bits = new_bits;
|
||||
#endif
|
||||
|
||||
const xyz_pos_t lpos = current_position.asLogical();
|
||||
const bool is_inch = parser.using_inch_units();
|
||||
#if HAS_Z_AXIS
|
||||
strcpy(zstring, is_inch ? ftostr42_52(LINEAR_UNIT(lpos.z)) : ftostr52sp(lpos.z));
|
||||
#if NUM_AXES
|
||||
const xyz_pos_t lpos = current_position.asLogical();
|
||||
const bool is_inch = parser.using_inch_units();
|
||||
#endif
|
||||
|
||||
if (show_e_total) {
|
||||
@ -557,10 +560,12 @@ void MarlinUI::draw_status_screen() {
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
strcpy(xstring, is_inch ? ftostr53_63(LINEAR_UNIT(lpos.x)) : ftostr4sign(lpos.x));
|
||||
TERN_(HAS_X_AXIS, strcpy(xstring, is_inch ? ftostr53_63(LINEAR_UNIT(lpos.x)) : ftostr4sign(lpos.x)));
|
||||
TERN_(HAS_Y_AXIS, strcpy(ystring, is_inch ? ftostr53_63(LINEAR_UNIT(lpos.y)) : ftostr4sign(lpos.y)));
|
||||
}
|
||||
|
||||
TERN_(HAS_Z_AXIS, strcpy(zstring, is_inch ? ftostr42_52(LINEAR_UNIT(lpos.z)) : ftostr52sp(lpos.z)));
|
||||
|
||||
#if ENABLED(FILAMENT_LCD_DISPLAY)
|
||||
strcpy(wstring, ftostr12ns(filwidth.measured_mm));
|
||||
strcpy(mstring, i16tostr3rj(planner.volumetric_percent(parser.volumetric_enabled)));
|
||||
@ -839,15 +844,13 @@ void MarlinUI::draw_status_screen() {
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
_draw_axis_value(X_AXIS, xstring, blink);
|
||||
TERN_(HAS_X_AXIS, _draw_axis_value(X_AXIS, xstring, blink));
|
||||
TERN_(HAS_Y_AXIS, _draw_axis_value(Y_AXIS, ystring, blink));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if HAS_Z_AXIS
|
||||
_draw_axis_value(Z_AXIS, zstring, blink);
|
||||
#endif
|
||||
TERN_(HAS_Z_AXIS, _draw_axis_value(Z_AXIS, zstring, blink));
|
||||
|
||||
#if NONE(XYZ_NO_FRAME, XYZ_HOLLOW_FRAME)
|
||||
u8g.setColorIndex(1); // black on white
|
||||
|
@ -2365,14 +2365,16 @@ void CrealityDWINClass::Menu_Item_Handler(const uint8_t menu, const uint8_t item
|
||||
else
|
||||
Draw_Menu(Motion, MOTION_SPEED);
|
||||
break;
|
||||
case SPEED_X:
|
||||
if (draw) {
|
||||
Draw_Menu_Item(row, ICON_MaxSpeedX, F("X Axis"));
|
||||
Draw_Float(planner.settings.max_feedrate_mm_s[X_AXIS], row, false, 1);
|
||||
}
|
||||
else
|
||||
Modify_Value(planner.settings.max_feedrate_mm_s[X_AXIS], 0, default_max_feedrate[X_AXIS] * 2, 1);
|
||||
break;
|
||||
#if HAS_X_AXIS
|
||||
case SPEED_X:
|
||||
if (draw) {
|
||||
Draw_Menu_Item(row, ICON_MaxSpeedX, F("X Axis"));
|
||||
Draw_Float(planner.settings.max_feedrate_mm_s[X_AXIS], row, false, 1);
|
||||
}
|
||||
else
|
||||
Modify_Value(planner.settings.max_feedrate_mm_s[X_AXIS], 0, default_max_feedrate[X_AXIS] * 2, 1);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
case SPEED_Y:
|
||||
|
@ -308,14 +308,14 @@ void MarlinUI::draw_status_screen() {
|
||||
|
||||
// Axis values
|
||||
const xyz_pos_t lpos = current_position.asLogical();
|
||||
const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive()); UNUSED(show_e_total);
|
||||
const bool show_e_total = TERN1(HAS_X_AXIS, TERN0(LCD_SHOW_E_TOTAL, printingIsActive()));
|
||||
|
||||
constexpr int16_t cpy = TERN(DWIN_MARLINUI_PORTRAIT, 195, 117);
|
||||
if (show_e_total) {
|
||||
TERN_(LCD_SHOW_E_TOTAL, _draw_e_value(e_move_accumulator, TERN(DWIN_MARLINUI_PORTRAIT, 6, 75), cpy));
|
||||
}
|
||||
else {
|
||||
_draw_axis_value(X_AXIS, ftostr4sign(lpos.x), blink, TERN(DWIN_MARLINUI_PORTRAIT, 6, 75), cpy);
|
||||
TERN_(HAS_X_AXIS, _draw_axis_value(X_AXIS, ftostr4sign(lpos.x), blink, TERN(DWIN_MARLINUI_PORTRAIT, 6, 75), cpy));
|
||||
TERN_(HAS_Y_AXIS, _draw_axis_value(Y_AXIS, ftostr4sign(lpos.y), blink, TERN(DWIN_MARLINUI_PORTRAIT, 95, 184), cpy));
|
||||
}
|
||||
TERN_(HAS_Z_AXIS, _draw_axis_value(Z_AXIS, ftostr52sp(lpos.z), blink, TERN(DWIN_MARLINUI_PORTRAIT, 165, 300), cpy));
|
||||
|
@ -162,10 +162,12 @@ void DGUSScreenHandler::HandleManualMove(DGUS_VP_Variable &var, void *val_ptr) {
|
||||
switch (var.VP) {
|
||||
default: return;
|
||||
|
||||
case VP_MOVE_X:
|
||||
axiscode = 'X';
|
||||
if (!ExtUI::canMove(ExtUI::axis_t::X)) goto cannotmove;
|
||||
break;
|
||||
#if HAS_X_AXIS
|
||||
case VP_MOVE_X:
|
||||
axiscode = 'X';
|
||||
if (!ExtUI::canMove(ExtUI::axis_t::X)) goto cannotmove;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
case VP_MOVE_Y:
|
||||
|
@ -162,10 +162,12 @@ void DGUSScreenHandler::HandleManualMove(DGUS_VP_Variable &var, void *val_ptr) {
|
||||
switch (var.VP) {
|
||||
default: return;
|
||||
|
||||
case VP_MOVE_X:
|
||||
axiscode = 'X';
|
||||
if (!ExtUI::canMove(ExtUI::axis_t::X)) goto cannotmove;
|
||||
break;
|
||||
#if HAS_X_AXIS
|
||||
case VP_MOVE_X:
|
||||
axiscode = 'X';
|
||||
if (!ExtUI::canMove(ExtUI::axis_t::X)) goto cannotmove;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
case VP_MOVE_Y:
|
||||
|
@ -743,10 +743,12 @@ void DGUSScreenHandler::HandleManualMove(DGUS_VP_Variable &var, void *val_ptr) {
|
||||
|
||||
switch (var.VP) { // switch X Y Z or Home
|
||||
default: return;
|
||||
case VP_MOVE_X:
|
||||
axiscode = 'X';
|
||||
if (!ExtUI::canMove(ExtUI::axis_t::X)) goto cannotmove;
|
||||
break;
|
||||
#if HAS_X_AXIS
|
||||
case VP_MOVE_X:
|
||||
axiscode = 'X';
|
||||
if (!ExtUI::canMove(ExtUI::axis_t::X)) goto cannotmove;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
case VP_MOVE_Y:
|
||||
@ -773,10 +775,12 @@ void DGUSScreenHandler::HandleManualMove(DGUS_VP_Variable &var, void *val_ptr) {
|
||||
movevalue = 0; // ignore value sent from display, this VP is _ONLY_ for homing.
|
||||
break;
|
||||
|
||||
case VP_X_HOME:
|
||||
axiscode = 'X';
|
||||
movevalue = 0;
|
||||
break;
|
||||
#if HAS_X_AXIS
|
||||
case VP_X_HOME:
|
||||
axiscode = 'X';
|
||||
movevalue = 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
case VP_Y_HOME:
|
||||
|
@ -162,10 +162,12 @@ void DGUSScreenHandler::HandleManualMove(DGUS_VP_Variable &var, void *val_ptr) {
|
||||
switch (var.VP) {
|
||||
default: return;
|
||||
|
||||
case VP_MOVE_X:
|
||||
axiscode = 'X';
|
||||
if (!ExtUI::canMove(ExtUI::axis_t::X)) goto cannotmove;
|
||||
break;
|
||||
#if HAS_X_AXIS
|
||||
case VP_MOVE_X:
|
||||
axiscode = 'X';
|
||||
if (!ExtUI::canMove(ExtUI::axis_t::X)) goto cannotmove;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
case VP_MOVE_Y:
|
||||
|
@ -77,8 +77,10 @@ bool BaseMoveAxisScreen::onTouchHeld(const uint8_t tag) {
|
||||
#define UI_DECREMENT_AXIS(axis) setManualFeedrate(axis, increment); UI_DECREMENT(AxisPosition_mm, axis);
|
||||
const float increment = getIncrement();
|
||||
switch (tag) {
|
||||
case 2: UI_DECREMENT_AXIS(X); break;
|
||||
case 3: UI_INCREMENT_AXIS(X); break;
|
||||
#if HAS_X_AXIS
|
||||
case 2: UI_DECREMENT_AXIS(X); break;
|
||||
case 3: UI_INCREMENT_AXIS(X); break;
|
||||
#endif
|
||||
#if HAS_EXTRUDERS
|
||||
// For extruders, also update relative distances.
|
||||
case 8: UI_DECREMENT_AXIS(E0); mydata.e_rel[0] -= increment; break;
|
||||
|
@ -124,8 +124,10 @@ void lv_draw_acceleration_settings() {
|
||||
lv_screen_menu_item_1_edit(scr, machine_menu.TravelAcceleration, PARA_UI_POS_X, y, event_handler, ID_ACCE_TRAVEL, 2, public_buf_l);
|
||||
|
||||
y += PARA_UI_POS_Y;
|
||||
itoa(planner.settings.max_acceleration_mm_per_s2[X_AXIS], public_buf_l, 10);
|
||||
lv_screen_menu_item_1_edit(scr, machine_menu.X_Acceleration, PARA_UI_POS_X, y, event_handler, ID_ACCE_X, 3, public_buf_l);
|
||||
#if HAS_X_AXIS
|
||||
itoa(planner.settings.max_acceleration_mm_per_s2[X_AXIS], public_buf_l, 10);
|
||||
lv_screen_menu_item_1_edit(scr, machine_menu.X_Acceleration, PARA_UI_POS_X, y, event_handler, ID_ACCE_X, 3, public_buf_l);
|
||||
#endif
|
||||
|
||||
lv_big_button_create(scr, "F:/bmp_back70x40.bin", machine_menu.next, PARA_UI_TURN_PAGE_POS_X, PARA_UI_TURN_PAGE_POS_Y, event_handler, ID_ACCE_DOWN, true);
|
||||
}
|
||||
|
@ -194,7 +194,9 @@
|
||||
void mks_hardware_test() {
|
||||
if (millis() % 2000 < 1000) {
|
||||
thermalManager.fan_speed[0] = 255;
|
||||
WRITE(X_DIR_PIN, LOW);
|
||||
#if HAS_X_AXIS
|
||||
WRITE(X_DIR_PIN, LOW);
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
WRITE(Y_DIR_PIN, LOW);
|
||||
#endif
|
||||
@ -219,7 +221,9 @@
|
||||
}
|
||||
else {
|
||||
thermalManager.fan_speed[0] = 0;
|
||||
WRITE(X_DIR_PIN, HIGH);
|
||||
#if HAS_X_AXIS
|
||||
WRITE(X_DIR_PIN, HIGH);
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
WRITE(Y_DIR_PIN, HIGH);
|
||||
#endif
|
||||
|
@ -375,7 +375,7 @@ namespace ExtUI {
|
||||
bool canMove(const axis_t axis) {
|
||||
switch (axis) {
|
||||
#if IS_KINEMATIC || ENABLED(NO_MOTION_BEFORE_HOMING)
|
||||
case X: return !axis_should_home(X_AXIS);
|
||||
OPTCODE(HAS_X_AXIS, case X: return !axis_should_home(X_AXIS))
|
||||
OPTCODE(HAS_Y_AXIS, case Y: return !axis_should_home(Y_AXIS))
|
||||
OPTCODE(HAS_Z_AXIS, case Z: return !axis_should_home(Z_AXIS))
|
||||
#else
|
||||
@ -773,7 +773,9 @@ namespace ExtUI {
|
||||
bool babystepAxis_steps(const int16_t steps, const axis_t axis) {
|
||||
switch (axis) {
|
||||
#if ENABLED(BABYSTEP_XY)
|
||||
case X: babystep.add_steps(X_AXIS, steps); break;
|
||||
#if HAS_X_AXIS
|
||||
case X: babystep.add_steps(X_AXIS, steps); break;
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
case Y: babystep.add_steps(Y_AXIS, steps); break;
|
||||
#endif
|
||||
@ -818,7 +820,7 @@ namespace ExtUI {
|
||||
if (e != active_extruder)
|
||||
hotend_offset[e][axis] += mm;
|
||||
|
||||
normalizeNozzleOffset(X);
|
||||
TERN_(HAS_X_AXIS, normalizeNozzleOffset(X));
|
||||
TERN_(HAS_Y_AXIS, normalizeNozzleOffset(Y));
|
||||
TERN_(HAS_Z_AXIS, normalizeNozzleOffset(Z));
|
||||
}
|
||||
|
@ -506,7 +506,7 @@ void MarlinUI::init() {
|
||||
ui.manual_move.menu_scale = REPRAPWORLD_KEYPAD_MOVE_STEP;
|
||||
ui.encoderPosition = dir;
|
||||
switch (axis) {
|
||||
case X_AXIS:
|
||||
TERN_(HAS_X_AXIS, case X_AXIS:)
|
||||
TERN_(HAS_Y_AXIS, case Y_AXIS:)
|
||||
TERN_(HAS_Z_AXIS, case Z_AXIS:)
|
||||
lcd_move_axis(axis);
|
||||
|
@ -475,9 +475,23 @@ void menu_backlash();
|
||||
|
||||
// M201 / M204 Accelerations
|
||||
void menu_advanced_acceleration() {
|
||||
float max_accel = planner.settings.max_acceleration_mm_per_s2[A_AXIS];
|
||||
TERN_(HAS_Y_AXIS, NOLESS(max_accel, planner.settings.max_acceleration_mm_per_s2[B_AXIS]));
|
||||
TERN_(HAS_Z_AXIS, NOLESS(max_accel, planner.settings.max_acceleration_mm_per_s2[C_AXIS]));
|
||||
float max_accel = (
|
||||
#if NUM_AXES
|
||||
_MAX(NUM_AXIS_LIST(
|
||||
planner.settings.max_acceleration_mm_per_s2[A_AXIS],
|
||||
planner.settings.max_acceleration_mm_per_s2[B_AXIS],
|
||||
planner.settings.max_acceleration_mm_per_s2[C_AXIS],
|
||||
planner.settings.max_acceleration_mm_per_s2[I_AXIS],
|
||||
planner.settings.max_acceleration_mm_per_s2[J_AXIS],
|
||||
planner.settings.max_acceleration_mm_per_s2[K_AXIS],
|
||||
planner.settings.max_acceleration_mm_per_s2[U_AXIS],
|
||||
planner.settings.max_acceleration_mm_per_s2[V_AXIS],
|
||||
planner.settings.max_acceleration_mm_per_s2[W_AXIS]
|
||||
))
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
);
|
||||
|
||||
// M201 settings
|
||||
constexpr xyze_ulong_t max_accel_edit =
|
||||
|
@ -50,7 +50,9 @@ void menu_backlash() {
|
||||
EDIT_ITEM_FAST_N(float43, _AXIS(N), MSG_BACKLASH_N, &editable.decimal, 0.0f, 9.9f, []{ backlash.set_distance_mm(_AXIS(N), editable.decimal); }); \
|
||||
} while (0);
|
||||
|
||||
if (_CAN_CALI(A)) EDIT_BACKLASH_DISTANCE(A);
|
||||
#if HAS_X_AXIS && _CAN_CALI(A)
|
||||
EDIT_BACKLASH_DISTANCE(A);
|
||||
#endif
|
||||
#if HAS_Y_AXIS && _CAN_CALI(B)
|
||||
EDIT_BACKLASH_DISTANCE(B);
|
||||
#endif
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#if HAS_MARLINUI_MENU
|
||||
|
||||
#define HAS_LARGE_AREA ((X_BED_SIZE) >= 1000 || TERN0(HAS_Y_AXIS, (Y_BED_SIZE) >= 1000) || TERN0(HAS_Z_AXIS, (Z_MAX_POS) >= 1000))
|
||||
#define HAS_LARGE_AREA (TERN0(HAS_X_AXIS, (X_BED_SIZE) >= 1000) || TERN0(HAS_Y_AXIS, (Y_BED_SIZE) >= 1000) || TERN0(HAS_Z_AXIS, (Z_MAX_POS) >= 1000))
|
||||
#if ENABLED(LARGE_MOVE_ITEMS)
|
||||
#define HAS_LARGE_MOVES true
|
||||
#elif ENABLED(SLIM_LCD_MENUS)
|
||||
@ -214,7 +214,9 @@ void menu_move() {
|
||||
// Move submenu for each axis
|
||||
if (NONE(IS_KINEMATIC, NO_MOTION_BEFORE_HOMING) || all_axes_homed()) {
|
||||
if (TERN1(DELTA, current_position.z <= delta_clip_start_height)) {
|
||||
SUBMENU_N(X_AXIS, MSG_MOVE_N, []{ _menu_move_distance(X_AXIS, []{ lcd_move_axis(X_AXIS); }); });
|
||||
#if HAS_X_AXIS
|
||||
SUBMENU_N(X_AXIS, MSG_MOVE_N, []{ _menu_move_distance(X_AXIS, []{ lcd_move_axis(X_AXIS); }); });
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
SUBMENU_N(Y_AXIS, MSG_MOVE_N, []{ _menu_move_distance(Y_AXIS, []{ lcd_move_axis(Y_AXIS); }); });
|
||||
#endif
|
||||
|
@ -50,9 +50,9 @@ struct vector_3 {
|
||||
float pos[3];
|
||||
};
|
||||
vector_3(const_float_t _x, const_float_t _y, const_float_t _z) : x(_x), y(_y), z(_z) {}
|
||||
vector_3(const xy_float_t &in) { x = in.x; TERN_(HAS_Y_AXIS, y = in.y); }
|
||||
vector_3(const xyz_float_t &in) { x = in.x; TERN_(HAS_Y_AXIS, y = in.y); TERN_(HAS_Z_AXIS, z = in.z); }
|
||||
vector_3(const xyze_float_t &in) { x = in.x; TERN_(HAS_Y_AXIS, y = in.y); TERN_(HAS_Z_AXIS, z = in.z); }
|
||||
vector_3(const xy_float_t &in) { TERN_(HAS_X_AXIS, x = in.x); TERN_(HAS_Y_AXIS, y = in.y); }
|
||||
vector_3(const xyz_float_t &in) { TERN_(HAS_X_AXIS, x = in.x); TERN_(HAS_Y_AXIS, y = in.y); TERN_(HAS_Z_AXIS, z = in.z); }
|
||||
vector_3(const xyze_float_t &in) { TERN_(HAS_X_AXIS, x = in.x); TERN_(HAS_Y_AXIS, y = in.y); TERN_(HAS_Z_AXIS, z = in.z); }
|
||||
vector_3() { x = y = z = 0; }
|
||||
|
||||
// Factory method
|
||||
@ -75,8 +75,8 @@ struct vector_3 {
|
||||
vector_3 operator-(const vector_3 &v) { return vector_3(x - v.x, y - v.y, z - v.z); }
|
||||
vector_3 operator*(const float &v) { return vector_3(x * v, y * v, z * v); }
|
||||
|
||||
operator xy_float_t() { return xy_float_t({ x OPTARG(HAS_Y_AXIS, y) }); }
|
||||
operator xyz_float_t() { return xyz_float_t({ x OPTARG(HAS_Y_AXIS, y) OPTARG(HAS_Z_AXIS, z) }); }
|
||||
operator xy_float_t() { return xy_float_t({ TERN_(HAS_X_AXIS, x) OPTARG(HAS_Y_AXIS, y) }); }
|
||||
operator xyz_float_t() { return xyz_float_t({ TERN_(HAS_X_AXIS, x) OPTARG(HAS_Y_AXIS, y) OPTARG(HAS_Z_AXIS, z) }); }
|
||||
|
||||
void debug(FSTR_P const title);
|
||||
};
|
||||
|
@ -300,7 +300,7 @@ void Endstops::event_handler() {
|
||||
prev_hit_state = hit_state;
|
||||
if (hit_state) {
|
||||
#if HAS_STATUS_MESSAGE
|
||||
char NUM_AXIS_LIST(chrX = ' ', chrY = ' ', chrZ = ' ', chrI = ' ', chrJ = ' ', chrK = ' ', chrU = ' ', chrV = ' ', chrW = ' '),
|
||||
char NUM_AXIS_LIST_(chrX = ' ', chrY = ' ', chrZ = ' ', chrI = ' ', chrJ = ' ', chrK = ' ', chrU = ' ', chrV = ' ', chrW = ' ')
|
||||
chrP = ' ';
|
||||
#define _SET_STOP_CHAR(A,C) (chr## A = C)
|
||||
#else
|
||||
@ -348,7 +348,7 @@ void Endstops::event_handler() {
|
||||
ui.status_printf(0,
|
||||
F(S_FMT GANG_N_1(NUM_AXES, " %c") " %c"),
|
||||
GET_TEXT(MSG_LCD_ENDSTOPS),
|
||||
NUM_AXIS_LIST(chrX, chrY, chrZ, chrI, chrJ, chrK, chrU, chrV, chrW), chrP
|
||||
NUM_AXIS_LIST_(chrX, chrY, chrZ, chrI, chrJ, chrK, chrU, chrV, chrW) chrP
|
||||
)
|
||||
);
|
||||
|
||||
@ -367,19 +367,23 @@ void Endstops::event_handler() {
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#if GCC_VERSION <= 50000
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#if NUM_AXES
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#if GCC_VERSION <= 50000
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
static void print_es_state(const bool is_hit, FSTR_P const flabel=nullptr) {
|
||||
if (flabel) SERIAL_ECHOF(flabel);
|
||||
SERIAL_ECHOPGM(": ");
|
||||
SERIAL_ECHOLNF(is_hit ? F(STR_ENDSTOP_HIT) : F(STR_ENDSTOP_OPEN));
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#endif
|
||||
|
||||
static void print_es_state(const bool is_hit, FSTR_P const flabel=nullptr) {
|
||||
if (flabel) SERIAL_ECHOF(flabel);
|
||||
SERIAL_ECHOPGM(": ");
|
||||
SERIAL_ECHOLNF(is_hit ? F(STR_ENDSTOP_HIT) : F(STR_ENDSTOP_OPEN));
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
void __O2 Endstops::report_states() {
|
||||
TERN_(BLTOUCH, bltouch._set_SW_mode());
|
||||
SERIAL_ECHOLNPGM(STR_M119_REPORT);
|
||||
|
@ -203,22 +203,24 @@ inline void report_more_positions() {
|
||||
// Report the logical position for a given machine position
|
||||
inline void report_logical_position(const xyze_pos_t &rpos) {
|
||||
const xyze_pos_t lpos = rpos.asLogical();
|
||||
SERIAL_ECHOPGM_P(
|
||||
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_U_LBL, lpos.u,
|
||||
SP_V_LBL, lpos.v,
|
||||
SP_W_LBL, lpos.w
|
||||
)
|
||||
#if HAS_EXTRUDERS
|
||||
, SP_E_LBL, lpos.e
|
||||
#endif
|
||||
);
|
||||
#if NUM_AXES
|
||||
SERIAL_ECHOPGM_P(
|
||||
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_U_LBL, lpos.u,
|
||||
SP_V_LBL, lpos.v,
|
||||
SP_W_LBL, lpos.w
|
||||
)
|
||||
);
|
||||
#endif
|
||||
#if HAS_EXTRUDERS
|
||||
SERIAL_ECHOPGM_P(SP_E_LBL, lpos.e);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Report the real current position according to the steppers.
|
||||
@ -367,7 +369,7 @@ void report_current_position_projected() {
|
||||
#else // CARTESIAN
|
||||
|
||||
// Return true if the given position is within the machine bounds.
|
||||
bool position_is_reachable(const_float_t rx, const_float_t ry) {
|
||||
bool position_is_reachable(TERN_(HAS_X_AXIS, const_float_t rx) OPTARG(HAS_Y_AXIS, const_float_t ry)) {
|
||||
if (TERN0(HAS_Y_AXIS, !COORDINATE_OKAY(ry, Y_MIN_POS - fslop, Y_MAX_POS + fslop))) return false;
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
if (active_extruder)
|
||||
@ -375,7 +377,8 @@ void report_current_position_projected() {
|
||||
else
|
||||
return COORDINATE_OKAY(rx, X1_MIN_POS - fslop, X1_MAX_POS + fslop);
|
||||
#else
|
||||
return COORDINATE_OKAY(rx, X_MIN_POS - fslop, X_MAX_POS + fslop);
|
||||
if (TERN0(HAS_X_AXIS, !COORDINATE_OKAY(rx, X_MIN_POS - fslop, X_MAX_POS + fslop))) return false;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -567,7 +570,7 @@ 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(NUM_AXIS_ARGS(const_float_t), const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
void do_blocking_move_to(NUM_AXIS_ARGS_(const_float_t) const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
DEBUG_SECTION(log_move, "do_blocking_move_to", DEBUGGING(LEVELING));
|
||||
if (DEBUGGING(LEVELING)) DEBUG_XYZ("> ", NUM_AXIS_ARGS());
|
||||
|
||||
@ -642,7 +645,7 @@ void do_blocking_move_to(NUM_AXIS_ARGS(const_float_t), const_feedRate_t fr_mm_s/
|
||||
if (current_position.z < z) { current_position.z = z; line_to_current_position(z_feedrate); }
|
||||
#endif
|
||||
|
||||
current_position.set(x OPTARG(HAS_Y_AXIS, y)); line_to_current_position(xy_feedrate);
|
||||
current_position.set(TERN_(HAS_X_AXIS, x) OPTARG(HAS_Y_AXIS, y)); line_to_current_position(xy_feedrate);
|
||||
|
||||
#if SECONDARY_AXES
|
||||
secondary_axis_moves(SECONDARY_AXIS_LIST(i, j, k, u, v, w), fr_mm_s);
|
||||
@ -659,30 +662,33 @@ void do_blocking_move_to(NUM_AXIS_ARGS(const_float_t), 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(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);
|
||||
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(NUM_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(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*/) {
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("do_blocking_move_to_x(", rx, ", ", fr_mm_s, ")");
|
||||
do_blocking_move_to(
|
||||
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
|
||||
);
|
||||
do_blocking_move_to(NUM_AXIS_ELEM_(raw) fr_mm_s);
|
||||
}
|
||||
|
||||
#if HAS_X_AXIS
|
||||
void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("do_blocking_move_to_x(", rx, ", ", fr_mm_s, ")");
|
||||
do_blocking_move_to(
|
||||
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
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
void do_blocking_move_to_y(const_float_t ry, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("do_blocking_move_to_y(", ry, ", ", fr_mm_s, ")");
|
||||
do_blocking_move_to(
|
||||
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),
|
||||
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
|
||||
);
|
||||
}
|
||||
@ -701,7 +707,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(
|
||||
NUM_AXIS_LIST(raw.x, raw.y, raw.z, i, raw.j, raw.k, raw.u, raw.v, raw.w),
|
||||
NUM_AXIS_LIST_(raw.x, raw.y, raw.z, i, raw.j, raw.k, raw.u, raw.v, raw.w)
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
@ -713,7 +719,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(
|
||||
NUM_AXIS_LIST(raw.x, raw.y, raw.z, raw.i, j, raw.k, raw.u, raw.v, raw.w),
|
||||
NUM_AXIS_LIST_(raw.x, raw.y, raw.z, raw.i, j, raw.k, raw.u, raw.v, raw.w)
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
@ -725,7 +731,7 @@ 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(
|
||||
NUM_AXIS_LIST(raw.x, raw.y, raw.z, raw.i, raw.j, k, raw.u, raw.v, raw.w),
|
||||
NUM_AXIS_LIST_(raw.x, raw.y, raw.z, raw.i, raw.j, k, raw.u, raw.v, raw.w)
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
@ -737,7 +743,7 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
}
|
||||
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),
|
||||
NUM_AXIS_LIST_(raw.x, raw.y, raw.z, raw.i, raw.j, raw.k, u, raw.v, raw.w)
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
@ -749,7 +755,7 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
}
|
||||
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),
|
||||
NUM_AXIS_LIST_(raw.x, raw.y, raw.z, raw.i, raw.j, raw.k, raw.u, v, raw.w)
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
@ -761,7 +767,7 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
}
|
||||
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),
|
||||
NUM_AXIS_LIST_(raw.x, raw.y, raw.z, raw.i, raw.j, raw.k, raw.u, raw.v, w)
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
@ -771,8 +777,8 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
void do_blocking_move_to_xy(const_float_t rx, const_float_t ry, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("do_blocking_move_to_xy(", rx, ", ", ry, ", ", fr_mm_s, ")");
|
||||
do_blocking_move_to(
|
||||
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),
|
||||
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
|
||||
);
|
||||
}
|
||||
@ -784,8 +790,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(
|
||||
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),
|
||||
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
|
||||
);
|
||||
}
|
||||
@ -966,14 +972,16 @@ void restore_feedrate_and_scaling() {
|
||||
|
||||
#else
|
||||
|
||||
if (axis_was_homed(X_AXIS)) {
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_X)
|
||||
NOLESS(target.x, soft_endstop.min.x);
|
||||
#endif
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_X)
|
||||
NOMORE(target.x, soft_endstop.max.x);
|
||||
#endif
|
||||
}
|
||||
#if HAS_X_AXIS
|
||||
if (axis_was_homed(X_AXIS)) {
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_X)
|
||||
NOLESS(target.x, soft_endstop.min.x);
|
||||
#endif
|
||||
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MAX_SOFTWARE_ENDSTOP_X)
|
||||
NOMORE(target.x, soft_endstop.max.x);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
if (axis_was_homed(Y_AXIS)) {
|
||||
@ -1079,82 +1087,90 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) {
|
||||
* Get distance from displacements along axes and, if required, update move type.
|
||||
*/
|
||||
float get_move_distance(const xyze_pos_t &diff OPTARG(HAS_ROTATIONAL_AXES, bool &is_cartesian_move)) {
|
||||
if (!(NUM_AXIS_GANG(diff.x, || diff.y, /* skip z */, || diff.i, || diff.j, || diff.k, || diff.u, || diff.v, || diff.w)))
|
||||
return TERN0(HAS_Z_AXIS, ABS(diff.z));
|
||||
#if NUM_AXES
|
||||
|
||||
#if ENABLED(ARTICULATED_ROBOT_ARM)
|
||||
if (!(NUM_AXIS_GANG(diff.x, || diff.y, /* skip z */, || diff.i, || diff.j, || diff.k, || diff.u, || diff.v, || diff.w)))
|
||||
return TERN0(HAS_Z_AXIS, ABS(diff.z));
|
||||
|
||||
// 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.
|
||||
const float distance_sqr = NUM_AXIS_GANG(
|
||||
sq(diff.x), + sq(diff.y), + sq(diff.z),
|
||||
+ sq(diff.i), + sq(diff.j), + sq(diff.k),
|
||||
+ sq(diff.u), + sq(diff.v), + sq(diff.w)
|
||||
);
|
||||
#if ENABLED(ARTICULATED_ROBOT_ARM)
|
||||
|
||||
#elif ENABLED(FOAMCUTTER_XYUV)
|
||||
// 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.
|
||||
const float distance_sqr = NUM_AXIS_GANG(
|
||||
sq(diff.x), + sq(diff.y), + sq(diff.z),
|
||||
+ sq(diff.i), + sq(diff.j), + sq(diff.k),
|
||||
+ sq(diff.u), + sq(diff.v), + sq(diff.w)
|
||||
);
|
||||
|
||||
const float distance_sqr = (
|
||||
#if HAS_J_AXIS
|
||||
_MAX(sq(diff.x) + sq(diff.y), sq(diff.i) + sq(diff.j)) // Special 5 axis kinematics. Return the larger of plane X/Y or I/J
|
||||
#else
|
||||
sq(diff.x) + sq(diff.y) // Foamcutter with only two axes (XY)
|
||||
#elif ENABLED(FOAMCUTTER_XYUV)
|
||||
|
||||
const float distance_sqr = (
|
||||
#if HAS_J_AXIS
|
||||
_MAX(sq(diff.x) + sq(diff.y), sq(diff.i) + sq(diff.j)) // Special 5 axis kinematics. Return the larger of plane X/Y or I/J
|
||||
#else
|
||||
sq(diff.x) + sq(diff.y) // Foamcutter with only two axes (XY)
|
||||
#endif
|
||||
);
|
||||
|
||||
#else
|
||||
|
||||
/**
|
||||
* Calculate distance for feedrate interpretation in accordance with NIST RS274NGC interpreter - version 3) and its default CANON_XYZ feed reference mode.
|
||||
* Assume:
|
||||
* - X, Y, Z are the primary linear axes;
|
||||
* - U, V, W are secondary linear axes;
|
||||
* - A, B, C are rotational axes.
|
||||
*
|
||||
* Then:
|
||||
* - dX, dY, dZ are the displacements of the primary linear axes;
|
||||
* - dU, dV, dW are the displacements of linear axes;
|
||||
* - dA, dB, dC are the displacements of rotational axes.
|
||||
*
|
||||
* The time it takes to execute a move command with feedrate F is t = D/F,
|
||||
* plus any time for acceleration and deceleration.
|
||||
* Here, 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 = XYZ_GANG(sq(diff.x), + sq(diff.y), + sq(diff.z));
|
||||
|
||||
#if SECONDARY_LINEAR_AXES
|
||||
if (UNEAR_ZERO(distance_sqr)) {
|
||||
// Move does not involve any primary linear axes (xyz) but might involve secondary linear axes
|
||||
distance_sqr = (
|
||||
SECONDARY_AXIS_GANG(
|
||||
IF_DISABLED(AXIS4_ROTATES, + sq(diff.i)),
|
||||
IF_DISABLED(AXIS5_ROTATES, + sq(diff.j)),
|
||||
IF_DISABLED(AXIS6_ROTATES, + sq(diff.k)),
|
||||
IF_DISABLED(AXIS7_ROTATES, + sq(diff.u)),
|
||||
IF_DISABLED(AXIS8_ROTATES, + sq(diff.v)),
|
||||
IF_DISABLED(AXIS9_ROTATES, + sq(diff.w))
|
||||
)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
);
|
||||
|
||||
#if HAS_ROTATIONAL_AXES
|
||||
if (UNEAR_ZERO(distance_sqr)) {
|
||||
// Move involves only rotational axes. Calculate angular distance in accordance with LinuxCNC
|
||||
is_cartesian_move = false;
|
||||
distance_sqr = ROTATIONAL_AXIS_GANG(sq(diff.i), + sq(diff.j), + sq(diff.k), + sq(diff.u), + sq(diff.v), + sq(diff.w));
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
return SQRT(distance_sqr);
|
||||
|
||||
#else
|
||||
|
||||
/**
|
||||
* Calculate distance for feedrate interpretation in accordance with NIST RS274NGC interpreter - version 3) and its default CANON_XYZ feed reference mode.
|
||||
* Assume:
|
||||
* - X, Y, Z are the primary linear axes;
|
||||
* - U, V, W are secondary linear axes;
|
||||
* - A, B, C are rotational axes.
|
||||
*
|
||||
* Then:
|
||||
* - dX, dY, dZ are the displacements of the primary linear axes;
|
||||
* - dU, dV, dW are the displacements of linear axes;
|
||||
* - dA, dB, dC are the displacements of rotational axes.
|
||||
*
|
||||
* The time it takes to execute a move command with feedrate F is t = D/F,
|
||||
* plus any time for acceleration and deceleration.
|
||||
* Here, 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 = XYZ_GANG(sq(diff.x), + sq(diff.y), + sq(diff.z));
|
||||
|
||||
#if SECONDARY_LINEAR_AXES
|
||||
if (UNEAR_ZERO(distance_sqr)) {
|
||||
// Move does not involve any primary linear axes (xyz) but might involve secondary linear axes
|
||||
distance_sqr = (
|
||||
SECONDARY_AXIS_GANG(
|
||||
IF_DISABLED(AXIS4_ROTATES, + sq(diff.i)),
|
||||
IF_DISABLED(AXIS5_ROTATES, + sq(diff.j)),
|
||||
IF_DISABLED(AXIS6_ROTATES, + sq(diff.k)),
|
||||
IF_DISABLED(AXIS7_ROTATES, + sq(diff.u)),
|
||||
IF_DISABLED(AXIS8_ROTATES, + sq(diff.v)),
|
||||
IF_DISABLED(AXIS9_ROTATES, + sq(diff.w))
|
||||
)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_ROTATIONAL_AXES
|
||||
if (UNEAR_ZERO(distance_sqr)) {
|
||||
// Move involves only rotational axes. Calculate angular distance in accordance with LinuxCNC
|
||||
is_cartesian_move = false;
|
||||
distance_sqr = ROTATIONAL_AXIS_GANG(sq(diff.i), + sq(diff.j), + sq(diff.k), + sq(diff.u), + sq(diff.v), + sq(diff.w));
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
|
||||
return SQRT(distance_sqr);
|
||||
}
|
||||
|
||||
#if IS_KINEMATIC
|
||||
@ -1702,7 +1718,9 @@ void prepare_line_to_destination() {
|
||||
|
||||
#if ENABLED(SPI_ENDSTOPS)
|
||||
switch (axis) {
|
||||
case X_AXIS: if (ENABLED(X_SPI_SENSORLESS)) endstops.tmc_spi_homing.x = true; break;
|
||||
#if HAS_X_AXIS
|
||||
case X_AXIS: if (ENABLED(X_SPI_SENSORLESS)) endstops.tmc_spi_homing.x = true; break;
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
case Y_AXIS: if (ENABLED(Y_SPI_SENSORLESS)) endstops.tmc_spi_homing.y = true; break;
|
||||
#endif
|
||||
@ -1796,7 +1814,9 @@ void prepare_line_to_destination() {
|
||||
|
||||
#if ENABLED(SPI_ENDSTOPS)
|
||||
switch (axis) {
|
||||
case X_AXIS: if (ENABLED(X_SPI_SENSORLESS)) endstops.tmc_spi_homing.x = false; break;
|
||||
#if HAS_X_AXIS
|
||||
case X_AXIS: if (ENABLED(X_SPI_SENSORLESS)) endstops.tmc_spi_homing.x = false; break;
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
case Y_AXIS: if (ENABLED(Y_SPI_SENSORLESS)) endstops.tmc_spi_homing.y = false; break;
|
||||
#endif
|
||||
|
@ -153,9 +153,9 @@ inline float home_bump_mm(const AxisEnum axis) {
|
||||
extern xyz_pos_t hotend_offset[HOTENDS];
|
||||
void reset_hotend_offsets();
|
||||
#elif HOTENDS
|
||||
constexpr xyz_pos_t hotend_offset[HOTENDS] = { { 0 } };
|
||||
constexpr xyz_pos_t hotend_offset[HOTENDS] = { { TERN_(HAS_X_AXIS, 0) } };
|
||||
#else
|
||||
constexpr xyz_pos_t hotend_offset[1] = { { 0 } };
|
||||
constexpr xyz_pos_t hotend_offset[1] = { { TERN_(HAS_X_AXIS, 0) } };
|
||||
#endif
|
||||
|
||||
#if HAS_SOFTWARE_ENDSTOPS
|
||||
@ -169,10 +169,12 @@ inline float home_bump_mm(const AxisEnum axis) {
|
||||
amin = -100000; amax = 100000; // "No limits"
|
||||
#if HAS_SOFTWARE_ENDSTOPS
|
||||
if (enabled()) switch (axis) {
|
||||
case X_AXIS:
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_X, amin = min.x);
|
||||
TERN_(MAX_SOFTWARE_ENDSTOP_X, amax = max.x);
|
||||
break;
|
||||
#if HAS_X_AXIS
|
||||
case X_AXIS:
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_X, amin = min.x);
|
||||
TERN_(MAX_SOFTWARE_ENDSTOP_X, amax = max.x);
|
||||
break;
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
case Y_AXIS:
|
||||
TERN_(MIN_SOFTWARE_ENDSTOP_Y, amin = min.y);
|
||||
@ -350,12 +352,14 @@ 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(NUM_AXIS_ARGS(const_float_t), const_feedRate_t fr_mm_s=0.0f);
|
||||
void do_blocking_move_to(NUM_AXIS_ARGS_(const_float_t) 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);
|
||||
|
||||
void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s=0.0f);
|
||||
#if HAS_X_AXIS
|
||||
void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s=0.0f);
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
void do_blocking_move_to_y(const_float_t ry, const_feedRate_t fr_mm_s=0.0f);
|
||||
#endif
|
||||
@ -515,8 +519,10 @@ void home_if_needed(const bool keeplev=false);
|
||||
FORCE_INLINE void toNative(xyz_pos_t&) {}
|
||||
FORCE_INLINE void toNative(xyze_pos_t&) {}
|
||||
#endif
|
||||
#define LOGICAL_X_POSITION(POS) NATIVE_TO_LOGICAL(POS, X_AXIS)
|
||||
#define RAW_X_POSITION(POS) LOGICAL_TO_NATIVE(POS, X_AXIS)
|
||||
#if HAS_X_AXIS
|
||||
#define LOGICAL_X_POSITION(POS) NATIVE_TO_LOGICAL(POS, X_AXIS)
|
||||
#define RAW_X_POSITION(POS) LOGICAL_TO_NATIVE(POS, X_AXIS)
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
#define LOGICAL_Y_POSITION(POS) NATIVE_TO_LOGICAL(POS, Y_AXIS)
|
||||
#define RAW_Y_POSITION(POS) LOGICAL_TO_NATIVE(POS, Y_AXIS)
|
||||
@ -569,9 +575,9 @@ void home_if_needed(const bool keeplev=false);
|
||||
#else
|
||||
|
||||
// Return true if the given position is within the machine bounds.
|
||||
bool position_is_reachable(const_float_t rx, const_float_t ry);
|
||||
bool position_is_reachable(TERN_(HAS_X_AXIS, const_float_t rx) OPTARG(HAS_Y_AXIS, const_float_t ry));
|
||||
inline bool position_is_reachable(const xy_pos_t &pos) {
|
||||
return position_is_reachable(pos.x, pos.y);
|
||||
return position_is_reachable(TERN_(HAS_X_AXIS, pos.x) OPTARG(HAS_Y_AXIS, pos.y));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1903,7 +1903,9 @@ bool Planner::_populate_block(
|
||||
/* <-- add a slash to enable
|
||||
SERIAL_ECHOLNPGM(
|
||||
" _populate_block FR:", fr_mm_s,
|
||||
" A:", target.a, " (", da, " steps)"
|
||||
#if HAS_X_AXIS
|
||||
" A:", target.a, " (", da, " steps)"
|
||||
#endif
|
||||
#if HAS_Y_AXIS
|
||||
" B:", target.b, " (", db, " steps)"
|
||||
#endif
|
||||
@ -2204,11 +2206,17 @@ bool Planner::_populate_block(
|
||||
|
||||
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->steps.u, block->steps.v, block->steps.w
|
||||
));
|
||||
block->step_event_count = (
|
||||
#if NUM_AXES
|
||||
_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
|
||||
))
|
||||
#elif HAS_EXTRUDERS
|
||||
esteps
|
||||
#endif
|
||||
);
|
||||
|
||||
// Bail if this is a zero-length block
|
||||
if (block->step_event_count < MIN_STEPS_PER_SEGMENT) return false;
|
||||
@ -2474,8 +2482,8 @@ bool Planner::_populate_block(
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
bool use_advance_lead = false;
|
||||
#endif
|
||||
if (NUM_AXIS_GANG(
|
||||
!block->steps.a, && !block->steps.b, && !block->steps.c,
|
||||
if (true NUM_AXIS_GANG(
|
||||
&& !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)
|
||||
) { // Is this a retract / recover move?
|
||||
|
@ -182,7 +182,7 @@ public:
|
||||
|
||||
static bool set_deployed(const bool, const bool=false) { return false; }
|
||||
|
||||
static bool can_reach(const_float_t rx, const_float_t ry, const bool=true) { return position_is_reachable(rx, ry); }
|
||||
static bool can_reach(const_float_t rx, const_float_t ry, const bool=true) { return position_is_reachable(TERN_(HAS_X_AXIS, rx) OPTARG(HAS_Y_AXIS, ry)); }
|
||||
|
||||
#endif // !HAS_BED_PROBE
|
||||
|
||||
|
@ -181,10 +181,10 @@
|
||||
#define _EN_ITEM(N) , E##N
|
||||
#define _EN1_ITEM(N) , E##N:1
|
||||
|
||||
typedef struct { uint16_t MAIN_AXIS_NAMES, X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } per_stepper_uint16_t;
|
||||
typedef struct { uint32_t MAIN_AXIS_NAMES, X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } per_stepper_uint32_t;
|
||||
typedef struct { int16_t MAIN_AXIS_NAMES, 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;
|
||||
typedef struct { uint16_t MAIN_AXIS_NAMES_ X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } per_stepper_uint16_t;
|
||||
typedef struct { uint32_t MAIN_AXIS_NAMES_ X2, Y2, Z2, Z3, Z4 REPEAT(E_STEPPERS, _EN_ITEM); } per_stepper_uint32_t;
|
||||
typedef struct { int16_t MAIN_AXIS_NAMES_ 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
|
||||
|
||||
@ -225,7 +225,9 @@ typedef struct SettingsDataStruct {
|
||||
//
|
||||
// Home Offset
|
||||
//
|
||||
xyz_pos_t home_offset; // M206 XYZ / M665 TPZ
|
||||
#if NUM_AXES
|
||||
xyz_pos_t home_offset; // M206 XYZ / M665 TPZ
|
||||
#endif
|
||||
|
||||
//
|
||||
// Hotend Offset
|
||||
@ -264,8 +266,9 @@ typedef struct SettingsDataStruct {
|
||||
//
|
||||
// HAS_BED_PROBE
|
||||
//
|
||||
|
||||
xyz_pos_t probe_offset; // M851 X Y Z
|
||||
#if NUM_AXES
|
||||
xyz_pos_t probe_offset; // M851 X Y Z
|
||||
#endif
|
||||
|
||||
//
|
||||
// ABL_PLANAR
|
||||
@ -475,7 +478,9 @@ typedef struct SettingsDataStruct {
|
||||
//
|
||||
// CNC_COORDINATE_SYSTEMS
|
||||
//
|
||||
xyz_pos_t coordinate_system[MAX_COORDINATE_SYSTEMS]; // G54-G59.3
|
||||
#if NUM_AXES
|
||||
xyz_pos_t coordinate_system[MAX_COORDINATE_SYSTEMS]; // G54-G59.3
|
||||
#endif
|
||||
|
||||
//
|
||||
// SKEW_CORRECTION
|
||||
@ -501,9 +506,11 @@ typedef struct SettingsDataStruct {
|
||||
//
|
||||
// BACKLASH_COMPENSATION
|
||||
//
|
||||
xyz_float_t backlash_distance_mm; // M425 X Y Z
|
||||
uint8_t backlash_correction; // M425 F
|
||||
float backlash_smoothing_mm; // M425 S
|
||||
#if NUM_AXES
|
||||
xyz_float_t backlash_distance_mm; // M425 X Y Z
|
||||
uint8_t backlash_correction; // M425 F
|
||||
float backlash_smoothing_mm; // M425 S
|
||||
#endif
|
||||
|
||||
//
|
||||
// EXTENSIBLE_UI
|
||||
@ -813,6 +820,7 @@ void MarlinSettings::postprocess() {
|
||||
//
|
||||
// Home Offset
|
||||
//
|
||||
#if NUM_AXES
|
||||
{
|
||||
_FIELD_TEST(home_offset);
|
||||
|
||||
@ -825,6 +833,7 @@ void MarlinSettings::postprocess() {
|
||||
EEPROM_WRITE(home_offset);
|
||||
#endif
|
||||
}
|
||||
#endif // NUM_AXES
|
||||
|
||||
//
|
||||
// Hotend Offsets, if any
|
||||
@ -905,6 +914,7 @@ void MarlinSettings::postprocess() {
|
||||
//
|
||||
// Probe XYZ Offsets
|
||||
//
|
||||
#if NUM_AXES
|
||||
{
|
||||
_FIELD_TEST(probe_offset);
|
||||
#if HAS_BED_PROBE
|
||||
@ -914,6 +924,7 @@ void MarlinSettings::postprocess() {
|
||||
#endif
|
||||
EEPROM_WRITE(zpo);
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// Planar Bed Leveling matrix
|
||||
@ -1364,7 +1375,7 @@ void MarlinSettings::postprocess() {
|
||||
#else
|
||||
#define _EN_ITEM(N) , .E##N = 30
|
||||
const per_stepper_uint32_t tmc_hybrid_threshold = {
|
||||
NUM_AXIS_LIST(.X = 100, .Y = 100, .Z = 3, .I = 3, .J = 3, .K = 3, .U = 3, .V = 3, .W = 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)
|
||||
};
|
||||
@ -1462,13 +1473,13 @@ void MarlinSettings::postprocess() {
|
||||
//
|
||||
// CNC Coordinate Systems
|
||||
//
|
||||
|
||||
_FIELD_TEST(coordinate_system);
|
||||
|
||||
#if DISABLED(CNC_COORDINATE_SYSTEMS)
|
||||
const xyz_pos_t coordinate_system[MAX_COORDINATE_SYSTEMS] = { { 0 } };
|
||||
#if NUM_AXES
|
||||
_FIELD_TEST(coordinate_system);
|
||||
#if DISABLED(CNC_COORDINATE_SYSTEMS)
|
||||
const xyz_pos_t coordinate_system[MAX_COORDINATE_SYSTEMS] = { { 0 } };
|
||||
#endif
|
||||
EEPROM_WRITE(TERN(CNC_COORDINATE_SYSTEMS, gcode.coordinate_system, coordinate_system));
|
||||
#endif
|
||||
EEPROM_WRITE(TERN(CNC_COORDINATE_SYSTEMS, gcode.coordinate_system, coordinate_system));
|
||||
|
||||
//
|
||||
// Skew correction factors
|
||||
@ -1503,6 +1514,7 @@ void MarlinSettings::postprocess() {
|
||||
//
|
||||
// Backlash Compensation
|
||||
//
|
||||
#if NUM_AXES
|
||||
{
|
||||
#if ENABLED(BACKLASH_GCODE)
|
||||
xyz_float_t backlash_distance_mm;
|
||||
@ -1522,6 +1534,7 @@ void MarlinSettings::postprocess() {
|
||||
EEPROM_WRITE(backlash_correction);
|
||||
EEPROM_WRITE(backlash_smoothing_mm);
|
||||
}
|
||||
#endif // NUM_AXES
|
||||
|
||||
//
|
||||
// Extensible UI User Data
|
||||
@ -1775,6 +1788,7 @@ void MarlinSettings::postprocess() {
|
||||
//
|
||||
// Home Offset (M206 / M665)
|
||||
//
|
||||
#if NUM_AXES
|
||||
{
|
||||
_FIELD_TEST(home_offset);
|
||||
|
||||
@ -1787,6 +1801,7 @@ void MarlinSettings::postprocess() {
|
||||
EEPROM_READ(home_offset);
|
||||
#endif
|
||||
}
|
||||
#endif // NUM_AXES
|
||||
|
||||
//
|
||||
// Hotend Offsets, if any
|
||||
@ -1862,6 +1877,7 @@ void MarlinSettings::postprocess() {
|
||||
//
|
||||
// Probe Z Offset
|
||||
//
|
||||
#if NUM_AXES
|
||||
{
|
||||
_FIELD_TEST(probe_offset);
|
||||
#if HAS_BED_PROBE
|
||||
@ -1871,6 +1887,7 @@ void MarlinSettings::postprocess() {
|
||||
#endif
|
||||
EEPROM_READ(zpo);
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// Planar Bed Leveling matrix
|
||||
@ -2439,6 +2456,7 @@ void MarlinSettings::postprocess() {
|
||||
//
|
||||
// CNC Coordinate System
|
||||
//
|
||||
#if NUM_AXES
|
||||
{
|
||||
_FIELD_TEST(coordinate_system);
|
||||
#if ENABLED(CNC_COORDINATE_SYSTEMS)
|
||||
@ -2449,6 +2467,7 @@ void MarlinSettings::postprocess() {
|
||||
EEPROM_READ(coordinate_system);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// Skew correction factors
|
||||
@ -2494,6 +2513,7 @@ void MarlinSettings::postprocess() {
|
||||
//
|
||||
// Backlash Compensation
|
||||
//
|
||||
#if NUM_AXES
|
||||
{
|
||||
xyz_float_t backlash_distance_mm;
|
||||
uint8_t backlash_correction;
|
||||
@ -2512,6 +2532,7 @@ void MarlinSettings::postprocess() {
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif // NUM_AXES
|
||||
|
||||
//
|
||||
// Extensible UI User Data
|
||||
@ -2903,7 +2924,7 @@ void MarlinSettings::reset() {
|
||||
planner.settings.min_travel_feedrate_mm_s = feedRate_t(DEFAULT_MINTRAVELFEEDRATE);
|
||||
|
||||
#if HAS_CLASSIC_JERK
|
||||
#ifndef DEFAULT_XJERK
|
||||
#if HAS_X_AXIS && !defined(DEFAULT_XJERK)
|
||||
#define DEFAULT_XJERK 0
|
||||
#endif
|
||||
#if HAS_Y_AXIS && !defined(DEFAULT_YJERK)
|
||||
|
@ -398,7 +398,7 @@ xyze_int8_t Stepper::count_direction{0};
|
||||
if (extruder_duplication_enabled || ALWAYS) { X_STEP_WRITE(v); X2_STEP_WRITE(v); } \
|
||||
else if (last_moved_extruder) X2_STEP_WRITE(v); else X_STEP_WRITE(v); \
|
||||
}while(0)
|
||||
#else
|
||||
#elif HAS_X_AXIS
|
||||
#define X_APPLY_DIR(v,Q) X_DIR_WRITE(v)
|
||||
#define X_APPLY_STEP(v,Q) X_STEP_WRITE(v)
|
||||
#endif
|
||||
@ -3407,19 +3407,21 @@ int32_t Stepper::triggered_position(const AxisEnum axis) {
|
||||
#endif
|
||||
|
||||
void Stepper::report_a_position(const xyz_long_t &pos) {
|
||||
SERIAL_ECHOLNPGM_P(
|
||||
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_U_LBL, pos.u,
|
||||
SP_V_LBL, pos.v,
|
||||
SP_W_LBL, pos.w
|
||||
)
|
||||
);
|
||||
#if NUM_AXES
|
||||
SERIAL_ECHOLNPGM_P(
|
||||
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_U_LBL, pos.u,
|
||||
SP_V_LBL, pos.v,
|
||||
SP_W_LBL, pos.w
|
||||
)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Stepper::report_positions() {
|
||||
|
@ -83,7 +83,7 @@ typedef struct {
|
||||
|
||||
// All the stepper enable pins
|
||||
constexpr pin_t ena_pins[] = {
|
||||
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),
|
||||
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)
|
||||
};
|
||||
|
||||
|
@ -83,21 +83,23 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
|
||||
#define INVERT_DIR(AXIS, D) (TERN_(INVERT_## AXIS ##_DIR, !)(D))
|
||||
|
||||
// X Stepper
|
||||
#ifndef X_ENABLE_INIT
|
||||
#define X_ENABLE_INIT() SET_OUTPUT(X_ENABLE_PIN)
|
||||
#define X_ENABLE_WRITE(STATE) WRITE(X_ENABLE_PIN,STATE)
|
||||
#define X_ENABLE_READ() bool(READ(X_ENABLE_PIN))
|
||||
#if HAS_X_AXIS
|
||||
#ifndef X_ENABLE_INIT
|
||||
#define X_ENABLE_INIT() SET_OUTPUT(X_ENABLE_PIN)
|
||||
#define X_ENABLE_WRITE(STATE) WRITE(X_ENABLE_PIN,STATE)
|
||||
#define X_ENABLE_READ() bool(READ(X_ENABLE_PIN))
|
||||
#endif
|
||||
#ifndef X_DIR_INIT
|
||||
#define X_DIR_INIT() SET_OUTPUT(X_DIR_PIN)
|
||||
#define X_DIR_WRITE(STATE) WRITE(X_DIR_PIN,INVERT_DIR(X, STATE))
|
||||
#define X_DIR_READ() INVERT_DIR(X, bool(READ(X_DIR_PIN)))
|
||||
#endif
|
||||
#define X_STEP_INIT() SET_OUTPUT(X_STEP_PIN)
|
||||
#ifndef X_STEP_WRITE
|
||||
#define X_STEP_WRITE(STATE) WRITE(X_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define X_STEP_READ() bool(READ(X_STEP_PIN))
|
||||
#endif
|
||||
#ifndef X_DIR_INIT
|
||||
#define X_DIR_INIT() SET_OUTPUT(X_DIR_PIN)
|
||||
#define X_DIR_WRITE(STATE) WRITE(X_DIR_PIN,INVERT_DIR(X, STATE))
|
||||
#define X_DIR_READ() INVERT_DIR(X, bool(READ(X_DIR_PIN)))
|
||||
#endif
|
||||
#define X_STEP_INIT() SET_OUTPUT(X_STEP_PIN)
|
||||
#ifndef X_STEP_WRITE
|
||||
#define X_STEP_WRITE(STATE) WRITE(X_STEP_PIN,STATE)
|
||||
#endif
|
||||
#define X_STEP_READ() bool(READ(X_STEP_PIN))
|
||||
|
||||
// Y Stepper
|
||||
#if HAS_Y_AXIS
|
||||
@ -977,8 +979,13 @@ void reset_stepper_drivers(); // Called by settings.load / settings.reset
|
||||
#define AFTER_CHANGE(N,TF) NOOP
|
||||
#endif
|
||||
|
||||
#define ENABLE_AXIS_X() if (SHOULD_ENABLE(x)) { ENABLE_STEPPER_X(); ENABLE_STEPPER_X2(); AFTER_CHANGE(x, true); }
|
||||
#define DISABLE_AXIS_X() if (SHOULD_DISABLE(x)) { DISABLE_STEPPER_X(); DISABLE_STEPPER_X2(); AFTER_CHANGE(x, false); set_axis_untrusted(X_AXIS); }
|
||||
#if HAS_X_AXIS
|
||||
#define ENABLE_AXIS_X() if (SHOULD_ENABLE(x)) { ENABLE_STEPPER_X(); ENABLE_STEPPER_X2(); AFTER_CHANGE(x, true); }
|
||||
#define DISABLE_AXIS_X() if (SHOULD_DISABLE(x)) { DISABLE_STEPPER_X(); DISABLE_STEPPER_X2(); AFTER_CHANGE(x, false); set_axis_untrusted(X_AXIS); }
|
||||
#else
|
||||
#define ENABLE_AXIS_X() NOOP
|
||||
#define DISABLE_AXIS_X() NOOP
|
||||
#endif
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
#define ENABLE_AXIS_Y() if (SHOULD_ENABLE(y)) { ENABLE_STEPPER_Y(); ENABLE_STEPPER_Y2(); AFTER_CHANGE(y, true); }
|
||||
|
@ -493,7 +493,7 @@ enum StealthIndex : uint8_t {
|
||||
#endif
|
||||
|
||||
#define _EN_ITEM(N) , E##N
|
||||
enum TMCAxis : uint8_t { MAIN_AXIS_NAMES, X2, Y2, Z2, Z3, Z4 REPEAT(EXTRUDERS, _EN_ITEM), TOTAL };
|
||||
enum TMCAxis : uint8_t { MAIN_AXIS_NAMES_ X2, Y2, Z2, Z3, Z4 REPEAT(EXTRUDERS, _EN_ITEM), TOTAL };
|
||||
#undef _EN_ITEM
|
||||
|
||||
void tmc_serial_begin() {
|
||||
|
@ -77,7 +77,7 @@
|
||||
#define TMC_CLASS_E(N) TMC_CLASS(E##N, E)
|
||||
#endif
|
||||
|
||||
#ifndef CHOPPER_TIMING_X
|
||||
#if HAS_X_AXIS && !defined(CHOPPER_TIMING_X)
|
||||
#define CHOPPER_TIMING_X CHOPPER_TIMING
|
||||
#endif
|
||||
#if HAS_Y_AXIS && !defined(CHOPPER_TIMING_Y)
|
||||
|
@ -24,44 +24,51 @@
|
||||
//
|
||||
// Prepare a list of protected pins for M42/M43
|
||||
//
|
||||
#if HAS_X_AXIS
|
||||
|
||||
#if PIN_EXISTS(X_MIN)
|
||||
#define _X_MIN X_MIN_PIN,
|
||||
#else
|
||||
#define _X_MIN
|
||||
#endif
|
||||
#if PIN_EXISTS(X_MAX)
|
||||
#define _X_MAX X_MAX_PIN,
|
||||
#else
|
||||
#define _X_MAX
|
||||
#endif
|
||||
#if PIN_EXISTS(X_CS) && AXIS_HAS_SPI(X)
|
||||
#define _X_CS X_CS_PIN,
|
||||
#else
|
||||
#define _X_CS
|
||||
#endif
|
||||
#if PIN_EXISTS(X_MS1)
|
||||
#define _X_MS1 X_MS1_PIN,
|
||||
#else
|
||||
#define _X_MS1
|
||||
#endif
|
||||
#if PIN_EXISTS(X_MS2)
|
||||
#define _X_MS2 X_MS2_PIN,
|
||||
#else
|
||||
#define _X_MS2
|
||||
#endif
|
||||
#if PIN_EXISTS(X_MS3)
|
||||
#define _X_MS3 X_MS3_PIN,
|
||||
#else
|
||||
#define _X_MS3
|
||||
#endif
|
||||
#if PIN_EXISTS(X_ENABLE)
|
||||
#define _X_ENABLE_PIN X_ENABLE_PIN,
|
||||
#else
|
||||
#define _X_ENABLE_PIN
|
||||
#endif
|
||||
#if PIN_EXISTS(X_MIN)
|
||||
#define _X_MIN X_MIN_PIN,
|
||||
#else
|
||||
#define _X_MIN
|
||||
#endif
|
||||
#if PIN_EXISTS(X_MAX)
|
||||
#define _X_MAX X_MAX_PIN,
|
||||
#else
|
||||
#define _X_MAX
|
||||
#endif
|
||||
#if PIN_EXISTS(X_CS) && AXIS_HAS_SPI(X)
|
||||
#define _X_CS X_CS_PIN,
|
||||
#else
|
||||
#define _X_CS
|
||||
#endif
|
||||
#if PIN_EXISTS(X_MS1)
|
||||
#define _X_MS1 X_MS1_PIN,
|
||||
#else
|
||||
#define _X_MS1
|
||||
#endif
|
||||
#if PIN_EXISTS(X_MS2)
|
||||
#define _X_MS2 X_MS2_PIN,
|
||||
#else
|
||||
#define _X_MS2
|
||||
#endif
|
||||
#if PIN_EXISTS(X_MS3)
|
||||
#define _X_MS3 X_MS3_PIN,
|
||||
#else
|
||||
#define _X_MS3
|
||||
#endif
|
||||
#if PIN_EXISTS(X_ENABLE)
|
||||
#define _X_ENABLE_PIN X_ENABLE_PIN,
|
||||
#else
|
||||
#define _X_ENABLE_PIN
|
||||
#endif
|
||||
|
||||
#define _X_PINS X_STEP_PIN, X_DIR_PIN, _X_ENABLE_PIN _X_MIN _X_MAX _X_MS1 _X_MS2 _X_MS3 _X_CS
|
||||
#define _X_PINS X_STEP_PIN, X_DIR_PIN, _X_ENABLE_PIN _X_MIN _X_MAX _X_MS1 _X_MS2 _X_MS3 _X_CS
|
||||
|
||||
#else
|
||||
|
||||
#define _X_PINS
|
||||
|
||||
#endif
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
|
||||
|
@ -71,6 +71,19 @@ opt_enable VIKI2 BOOT_MARLIN_LOGO_ANIMATED SDSUPPORT AUTO_REPORT_SD_STATUS \
|
||||
FILAMENT_RUNOUT_SENSOR NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE Z_SAFE_HOMING FIL_RUNOUT3_PULLUP
|
||||
exec_test $1 $2 "Z Servo Probe | Multiple runout sensors (x5)" "$3"
|
||||
|
||||
#
|
||||
# Extruder Only. No XYZ axes at all.
|
||||
#
|
||||
restore_configs
|
||||
opt_set DEFAULT_AXIS_STEPS_PER_UNIT '{ 4000 }' \
|
||||
DEFAULT_MAX_FEEDRATE '{ 5 }' \
|
||||
DEFAULT_MAX_ACCELERATION '{ 100 }' \
|
||||
MANUAL_FEEDRATE '{ 4*60 }' \
|
||||
AXIS_RELATIVE_MODES '{ false }' \
|
||||
HOMING_BUMP_MM '{}' HOMING_BUMP_DIVISOR '{}' HOMING_FEEDRATE_MM_M '{}'
|
||||
opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
|
||||
opt_disable X_DRIVER_TYPE Y_DRIVER_TYPE Z_DRIVER_TYPE
|
||||
exec_test $1 $2 "E Axis Only | DOGM MarlinUI" "$3"
|
||||
|
||||
#
|
||||
# Mixing Extruder with 5 steppers, Greek
|
||||
|
@ -36,9 +36,10 @@ platform_packages = framework-arduinoststm32@https://github.com/stm32d
|
||||
board = marlin_BTT_EBB42_V1_1
|
||||
board_build.offset = 0x0000
|
||||
board_upload.offset_address = 0x08000000
|
||||
build_flags = ${stm32_variant.build_flags} ${stm32g0_I2C2.build_flags}
|
||||
upload_protocol = stlink
|
||||
build_flags = ${stm32_variant.build_flags} ${stm32g0_I2C2.build_flags} -flto
|
||||
debug_tool = stlink
|
||||
upload_protocol = dfu
|
||||
upload_command = dfu-util -a 0 -s 0x08000000:leave -D "$SOURCE"
|
||||
|
||||
#
|
||||
# BigTreeTech SKR Mini E3 V3.0 (STM32G0B1RET6 ARM Cortex-M0+)
|
||||
|
Loading…
Reference in New Issue
Block a user