♻️ Refactor Linear / Logical / Distinct Axes (#21953)
* More patches supporting EXTRUDERS 0 * Extend types in prep for more axes
This commit is contained in:
parent
f5f999d7bf
commit
4194cdda5b
@ -101,8 +101,11 @@ void print_bin(uint16_t val) {
|
||||
}
|
||||
}
|
||||
|
||||
void print_pos(const_float_t x, const_float_t y, const_float_t z, PGM_P const prefix/*=nullptr*/, PGM_P const suffix/*=nullptr*/) {
|
||||
void print_pos(
|
||||
LINEAR_AXIS_LIST(const_float_t x, const_float_t y, const_float_t z)
|
||||
, PGM_P const prefix/*=nullptr*/, PGM_P const suffix/*=nullptr*/
|
||||
) {
|
||||
if (prefix) serialprintPGM(prefix);
|
||||
SERIAL_ECHOPAIR_P(SP_X_STR, x, SP_Y_STR, y, SP_Z_STR, z);
|
||||
SERIAL_ECHOPAIR_P(LIST_N(DOUBLE(LINEAR_AXES), SP_X_STR, x, SP_Y_STR, y, SP_Z_STR, z));
|
||||
if (suffix) serialprintPGM(suffix); else SERIAL_EOL();
|
||||
}
|
||||
|
@ -310,10 +310,13 @@ void serialprint_truefalse(const bool tf);
|
||||
void serial_spaces(uint8_t count);
|
||||
|
||||
void print_bin(const uint16_t val);
|
||||
void print_pos(const_float_t x, const_float_t y, const_float_t z, PGM_P const prefix=nullptr, PGM_P const suffix=nullptr);
|
||||
void print_pos(
|
||||
LINEAR_AXIS_LIST(const_float_t x, const_float_t y, const_float_t z),
|
||||
PGM_P const prefix=nullptr, PGM_P const suffix=nullptr
|
||||
);
|
||||
|
||||
inline void print_pos(const xyz_pos_t &xyz, PGM_P const prefix=nullptr, PGM_P const suffix=nullptr) {
|
||||
print_pos(xyz.x, xyz.y, xyz.z, prefix, suffix);
|
||||
print_pos(LINEAR_AXIS_LIST(xyz.x, xyz.y, xyz.z), prefix, suffix);
|
||||
}
|
||||
|
||||
#define SERIAL_POS(SUFFIX,VAR) do { print_pos(VAR, PSTR(" " STRINGIFY(VAR) "="), PSTR(" : " SUFFIX "\n")); }while(0)
|
||||
|
@ -39,6 +39,26 @@ struct IF { typedef R type; };
|
||||
template <class L, class R>
|
||||
struct IF<true, L, R> { typedef L type; };
|
||||
|
||||
#define LINEAR_AXIS_GANG(V...) GANG_N(LINEAR_AXES, V)
|
||||
#define LINEAR_AXIS_CODE(V...) CODE_N(LINEAR_AXES, V)
|
||||
#define LINEAR_AXIS_LIST(V...) LIST_N(LINEAR_AXES, V)
|
||||
#define LINEAR_AXIS_ARRAY(V...) { LINEAR_AXIS_LIST(V) }
|
||||
|
||||
#define LOGICAL_AXIS_GANG(E,V...) LINEAR_AXIS_GANG(V) GANG_ITEM_E(E)
|
||||
#define LOGICAL_AXIS_CODE(E,V...) LINEAR_AXIS_CODE(V) CODE_ITEM_E(E)
|
||||
#define LOGICAL_AXIS_LIST(E,V...) LINEAR_AXIS_LIST(V) LIST_ITEM_E(E)
|
||||
#define LOGICAL_AXIS_ARRAY(E,V...) { LOGICAL_AXIS_LIST(E,V) }
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
#define LIST_ITEM_E(N) , N
|
||||
#define CODE_ITEM_E(N) ; N
|
||||
#define GANG_ITEM_E(N) N
|
||||
#else
|
||||
#define LIST_ITEM_E(N)
|
||||
#define CODE_ITEM_E(N)
|
||||
#define GANG_ITEM_E(N)
|
||||
#endif
|
||||
|
||||
//
|
||||
// Enumerated axis indices
|
||||
//
|
||||
@ -47,16 +67,43 @@ struct IF<true, L, R> { typedef L type; };
|
||||
// - X_HEAD, Y_HEAD, and Z_HEAD should be used for Steppers on Core kinematics
|
||||
//
|
||||
enum AxisEnum : uint8_t {
|
||||
X_AXIS = 0, A_AXIS = X_AXIS,
|
||||
Y_AXIS = 1, B_AXIS = Y_AXIS,
|
||||
Z_AXIS = 2, C_AXIS = Z_AXIS,
|
||||
E_AXIS,
|
||||
X_HEAD, Y_HEAD, Z_HEAD,
|
||||
E0_AXIS = E_AXIS,
|
||||
E1_AXIS, E2_AXIS, E3_AXIS, E4_AXIS, E5_AXIS, E6_AXIS, E7_AXIS,
|
||||
|
||||
// Linear axes may be controlled directly or indirectly
|
||||
LINEAR_AXIS_LIST(X_AXIS, Y_AXIS, Z_AXIS),
|
||||
|
||||
// Extruder axes may be considered distinctly
|
||||
#define _EN_ITEM(N) E##N##_AXIS,
|
||||
REPEAT(EXTRUDERS, _EN_ITEM)
|
||||
#undef _EN_ITEM
|
||||
|
||||
// Core also keeps toolhead directions
|
||||
#if IS_CORE
|
||||
X_HEAD, Y_HEAD, Z_HEAD,
|
||||
#endif
|
||||
|
||||
// Distinct axes, including all E and Core
|
||||
NUM_AXIS_ENUMS,
|
||||
|
||||
// Most of the time we refer only to the single E_AXIS
|
||||
#if HAS_EXTRUDERS
|
||||
E_AXIS = E0_AXIS,
|
||||
#endif
|
||||
|
||||
// A, B, and C are for DELTA, SCARA, etc.
|
||||
A_AXIS = X_AXIS,
|
||||
#if LINEAR_AXES >= 2
|
||||
B_AXIS = Y_AXIS,
|
||||
#endif
|
||||
#if LINEAR_AXES >= 3
|
||||
C_AXIS = Z_AXIS,
|
||||
#endif
|
||||
|
||||
// To refer to all or none
|
||||
ALL_AXES_ENUM = 0xFE, NO_AXIS_ENUM = 0xFF
|
||||
};
|
||||
|
||||
typedef IF<(NUM_AXIS_ENUMS > 8), uint16_t, uint8_t>::type axis_bits_t;
|
||||
|
||||
//
|
||||
// Loop over axes
|
||||
//
|
||||
@ -185,7 +232,7 @@ void toNative(xyz_pos_t &raw);
|
||||
void toNative(xyze_pos_t &raw);
|
||||
|
||||
//
|
||||
// XY coordinates, counters, etc.
|
||||
// Paired XY coordinates, counters, flags, etc.
|
||||
//
|
||||
template<typename T>
|
||||
struct XYval {
|
||||
@ -197,10 +244,14 @@ struct XYval {
|
||||
FI void set(const T px) { x = px; }
|
||||
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]; }
|
||||
FI void set(const T (&arr)[XYZ]) { x = arr[0]; y = arr[1]; }
|
||||
FI void set(const T (&arr)[XYZE]) { x = arr[0]; y = arr[1]; }
|
||||
#if DISTINCT_AXES > LOGICAL_AXES
|
||||
FI void set(const T (&arr)[DISTINCT_AXES]) { x = arr[0]; y = arr[1]; }
|
||||
#if LINEAR_AXES > XY
|
||||
FI void set(const T (&arr)[LINEAR_AXES]) { x = arr[0]; y = arr[1]; }
|
||||
#endif
|
||||
#if LOGICAL_AXES > LINEAR_AXES
|
||||
FI void set(const T (&arr)[LOGICAL_AXES]) { x = arr[0]; y = arr[1]; }
|
||||
#if DISTINCT_AXES > LOGICAL_AXES
|
||||
FI void set(const T (&arr)[DISTINCT_AXES]) { x = arr[0]; y = arr[1]; }
|
||||
#endif
|
||||
#endif
|
||||
FI void reset() { x = y = 0; }
|
||||
FI T magnitude() const { return (T)sqrtf(x*x + y*y); }
|
||||
@ -223,8 +274,8 @@ struct XYval {
|
||||
FI operator XYZval<T>() const { return { x, y }; }
|
||||
FI operator XYZEval<T>() { return { x, y }; }
|
||||
FI operator XYZEval<T>() const { return { x, y }; }
|
||||
FI T& operator[](const int i) { return pos[i]; }
|
||||
FI const T& operator[](const int i) const { return pos[i]; }
|
||||
FI T& operator[](const int n) { return pos[n]; }
|
||||
FI const T& operator[](const int n) const { return pos[n]; }
|
||||
FI XYval<T>& operator= (const T v) { set(v, v ); return *this; }
|
||||
FI XYval<T>& operator= (const XYZval<T> &rs) { set(rs.x, rs.y); return *this; }
|
||||
FI XYval<T>& operator= (const XYZEval<T> &rs) { set(rs.x, rs.y); return *this; }
|
||||
@ -294,219 +345,227 @@ struct XYval {
|
||||
};
|
||||
|
||||
//
|
||||
// XYZ coordinates, counters, etc.
|
||||
// Linear Axes coordinates, counters, flags, etc.
|
||||
//
|
||||
template<typename T>
|
||||
struct XYZval {
|
||||
union {
|
||||
struct { T x, y, z; };
|
||||
struct { T a, b, c; };
|
||||
T pos[3];
|
||||
struct { T LINEAR_AXIS_LIST(x, y, z); };
|
||||
struct { T LINEAR_AXIS_LIST(a, b, c); };
|
||||
T pos[LINEAR_AXES];
|
||||
};
|
||||
FI void set(const T px) { x = px; }
|
||||
FI void set(const T px, const T py) { x = px; y = py; }
|
||||
FI void set(const T px, const T py, const T pz) { x = px; y = py; z = pz; }
|
||||
FI void set(const XYval<T> pxy) { x = pxy.x; y = pxy.y; }
|
||||
FI void set(const XYval<T> pxy, const T pz) { x = pxy.x; y = pxy.y; z = pz; }
|
||||
FI void set(const T (&arr)[XY]) { x = arr[0]; y = arr[1]; }
|
||||
FI void set(const T (&arr)[XYZ]) { x = arr[0]; y = arr[1]; z = arr[2]; }
|
||||
FI void set(const T (&arr)[XYZE]) { x = arr[0]; y = arr[1]; z = arr[2]; }
|
||||
#if DISTINCT_AXES > XYZE
|
||||
FI void set(const T (&arr)[DISTINCT_AXES]) { x = arr[0]; y = arr[1]; z = arr[2]; }
|
||||
FI void set(const T (&arr)[LINEAR_AXES]) { LINEAR_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2]); }
|
||||
#if LINEAR_AXES >= XYZ
|
||||
FI void set(LINEAR_AXIS_LIST(const T px, const T py, const T pz))
|
||||
{ LINEAR_AXIS_CODE(x = px, y = py, z = pz); }
|
||||
#endif
|
||||
FI void reset() { x = y = z = 0; }
|
||||
FI T magnitude() const { return (T)sqrtf(x*x + y*y + z*z); }
|
||||
#if LOGICAL_AXES > LINEAR_AXES
|
||||
FI void set(const T (&arr)[LOGICAL_AXES]) { LINEAR_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2]); }
|
||||
FI void set(LOGICAL_AXIS_LIST(const T, const T px, const T py, const T pz))
|
||||
{ LINEAR_AXIS_CODE(x = px, y = py, z = pz); }
|
||||
#if DISTINCT_AXES > LOGICAL_AXES
|
||||
FI void set(const T (&arr)[DISTINCT_AXES]) { LINEAR_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2]); }
|
||||
#endif
|
||||
#endif
|
||||
FI void reset() { LINEAR_AXIS_GANG(x =, y =, z =) 0; }
|
||||
FI T magnitude() const { return (T)sqrtf(LINEAR_AXIS_GANG(x*x, + y*y, + z*z)); }
|
||||
FI operator T* () { return pos; }
|
||||
FI operator bool() { return z || x || y; }
|
||||
FI operator bool() { return LINEAR_AXIS_GANG(z, || x, || y); }
|
||||
FI XYZval<T> copy() const { XYZval<T> o = *this; return o; }
|
||||
FI XYZval<T> ABS() const { return { T(_ABS(x)), T(_ABS(y)), T(_ABS(z)) }; }
|
||||
FI XYZval<int16_t> asInt() { return { int16_t(x), int16_t(y), int16_t(z) }; }
|
||||
FI XYZval<int16_t> asInt() const { return { int16_t(x), int16_t(y), int16_t(z) }; }
|
||||
FI XYZval<int32_t> asLong() { return { int32_t(x), int32_t(y), int32_t(z) }; }
|
||||
FI XYZval<int32_t> asLong() const { return { int32_t(x), int32_t(y), int32_t(z) }; }
|
||||
FI XYZval<int32_t> ROUNDL() { return { int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)) }; }
|
||||
FI XYZval<int32_t> ROUNDL() const { return { int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)) }; }
|
||||
FI XYZval<float> asFloat() { return { static_cast<float>(x), static_cast<float>(y), static_cast<float>(z) }; }
|
||||
FI XYZval<float> asFloat() const { return { static_cast<float>(x), static_cast<float>(y), static_cast<float>(z) }; }
|
||||
FI XYZval<float> reciprocal() const { return { _RECIP(x), _RECIP(y), _RECIP(z) }; }
|
||||
FI XYZval<T> ABS() const { return LINEAR_AXIS_ARRAY(T(_ABS(x)), T(_ABS(y)), T(_ABS(z))); }
|
||||
FI XYZval<int16_t> asInt() { return LINEAR_AXIS_ARRAY(int16_t(x), int16_t(y), int16_t(z)); }
|
||||
FI XYZval<int16_t> asInt() const { return LINEAR_AXIS_ARRAY(int16_t(x), int16_t(y), int16_t(z)); }
|
||||
FI XYZval<int32_t> asLong() { return LINEAR_AXIS_ARRAY(int32_t(x), int32_t(y), int32_t(z)); }
|
||||
FI XYZval<int32_t> asLong() const { return LINEAR_AXIS_ARRAY(int32_t(x), int32_t(y), int32_t(z)); }
|
||||
FI XYZval<int32_t> ROUNDL() { return LINEAR_AXIS_ARRAY(int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z))); }
|
||||
FI XYZval<int32_t> ROUNDL() const { return LINEAR_AXIS_ARRAY(int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z))); }
|
||||
FI XYZval<float> asFloat() { return LINEAR_AXIS_ARRAY(static_cast<float>(x), static_cast<float>(y), static_cast<float>(z)); }
|
||||
FI XYZval<float> asFloat() const { return LINEAR_AXIS_ARRAY(static_cast<float>(x), static_cast<float>(y), static_cast<float>(z)); }
|
||||
FI XYZval<float> reciprocal() const { return LINEAR_AXIS_ARRAY(_RECIP(x), _RECIP(y), _RECIP(z)); }
|
||||
FI XYZval<float> asLogical() const { XYZval<float> o = asFloat(); toLogical(o); return o; }
|
||||
FI XYZval<float> asNative() const { XYZval<float> o = asFloat(); toNative(o); return o; }
|
||||
FI operator XYval<T>&() { return *(XYval<T>*)this; }
|
||||
FI operator const XYval<T>&() const { return *(const XYval<T>*)this; }
|
||||
FI operator XYZEval<T>() const { return { x, y, z }; }
|
||||
FI T& operator[](const int i) { return pos[i]; }
|
||||
FI const T& operator[](const int i) const { return pos[i]; }
|
||||
FI XYZval<T>& operator= (const T v) { set(v, v, v ); return *this; }
|
||||
FI operator XYZEval<T>() const { return LINEAR_AXIS_ARRAY(x, y, z); }
|
||||
FI T& operator[](const int n) { return pos[n]; }
|
||||
FI const T& operator[](const int n) const { return pos[n]; }
|
||||
FI XYZval<T>& operator= (const T v) { set(ARRAY_N_1(LINEAR_AXES, v)); return *this; }
|
||||
FI XYZval<T>& operator= (const XYval<T> &rs) { set(rs.x, rs.y ); return *this; }
|
||||
FI XYZval<T>& operator= (const XYZEval<T> &rs) { set(rs.x, rs.y, rs.z); return *this; }
|
||||
FI XYZval<T> operator+ (const XYval<T> &rs) const { XYZval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
|
||||
FI XYZval<T> operator+ (const XYval<T> &rs) { XYZval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
|
||||
FI XYZval<T> operator- (const XYval<T> &rs) const { XYZval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
|
||||
FI XYZval<T> operator- (const XYval<T> &rs) { XYZval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
|
||||
FI XYZval<T> operator* (const XYval<T> &rs) const { XYZval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
|
||||
FI XYZval<T> operator* (const XYval<T> &rs) { XYZval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
|
||||
FI XYZval<T> operator/ (const XYval<T> &rs) const { XYZval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
|
||||
FI XYZval<T> operator/ (const XYval<T> &rs) { XYZval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
|
||||
FI XYZval<T> operator+ (const XYZval<T> &rs) const { XYZval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; ls.z += rs.z; return ls; }
|
||||
FI XYZval<T> operator+ (const XYZval<T> &rs) { XYZval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; ls.z += rs.z; return ls; }
|
||||
FI XYZval<T> operator- (const XYZval<T> &rs) const { XYZval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; ls.z -= rs.z; return ls; }
|
||||
FI XYZval<T> operator- (const XYZval<T> &rs) { XYZval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; ls.z -= rs.z; return ls; }
|
||||
FI XYZval<T> operator* (const XYZval<T> &rs) const { XYZval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; ls.z *= rs.z; return ls; }
|
||||
FI XYZval<T> operator* (const XYZval<T> &rs) { XYZval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; ls.z *= rs.z; return ls; }
|
||||
FI XYZval<T> operator/ (const XYZval<T> &rs) const { XYZval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; return ls; }
|
||||
FI XYZval<T> operator/ (const XYZval<T> &rs) { XYZval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; return ls; }
|
||||
FI XYZval<T> operator+ (const XYZEval<T> &rs) const { XYZval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; ls.z += rs.z; return ls; }
|
||||
FI XYZval<T> operator+ (const XYZEval<T> &rs) { XYZval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; ls.z += rs.z; return ls; }
|
||||
FI XYZval<T> operator- (const XYZEval<T> &rs) const { XYZval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; ls.z -= rs.z; return ls; }
|
||||
FI XYZval<T> operator- (const XYZEval<T> &rs) { XYZval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; ls.z -= rs.z; return ls; }
|
||||
FI XYZval<T> operator* (const XYZEval<T> &rs) const { XYZval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; ls.z *= rs.z; return ls; }
|
||||
FI XYZval<T> operator* (const XYZEval<T> &rs) { XYZval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; ls.z *= rs.z; return ls; }
|
||||
FI XYZval<T> operator/ (const XYZEval<T> &rs) const { XYZval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; return ls; }
|
||||
FI XYZval<T> operator/ (const XYZEval<T> &rs) { XYZval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; return ls; }
|
||||
FI XYZval<T> operator* (const float &v) const { XYZval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; return ls; }
|
||||
FI XYZval<T> operator* (const float &v) { XYZval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; return ls; }
|
||||
FI XYZval<T> operator* (const int &v) const { XYZval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; return ls; }
|
||||
FI XYZval<T> operator* (const int &v) { XYZval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; return ls; }
|
||||
FI XYZval<T> operator/ (const float &v) const { XYZval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; return ls; }
|
||||
FI XYZval<T> operator/ (const float &v) { XYZval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; return ls; }
|
||||
FI XYZval<T> operator/ (const int &v) const { XYZval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; return ls; }
|
||||
FI XYZval<T> operator/ (const int &v) { XYZval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; return ls; }
|
||||
FI XYZval<T> operator>>(const int &v) const { XYZval<T> ls = *this; _RS(ls.x); _RS(ls.y); _RS(ls.z); return ls; }
|
||||
FI XYZval<T> operator>>(const int &v) { XYZval<T> ls = *this; _RS(ls.x); _RS(ls.y); _RS(ls.z); return ls; }
|
||||
FI XYZval<T> operator<<(const int &v) const { XYZval<T> ls = *this; _LS(ls.x); _LS(ls.y); _LS(ls.z); return ls; }
|
||||
FI XYZval<T> operator<<(const int &v) { XYZval<T> ls = *this; _LS(ls.x); _LS(ls.y); _LS(ls.z); return ls; }
|
||||
FI XYZval<T>& operator+=(const XYval<T> &rs) { x += rs.x; y += rs.y; return *this; }
|
||||
FI XYZval<T>& operator-=(const XYval<T> &rs) { x -= rs.x; y -= rs.y; return *this; }
|
||||
FI XYZval<T>& operator*=(const XYval<T> &rs) { x *= rs.x; y *= rs.y; return *this; }
|
||||
FI XYZval<T>& operator/=(const XYval<T> &rs) { x /= rs.x; y /= rs.y; return *this; }
|
||||
FI XYZval<T>& operator+=(const XYZval<T> &rs) { x += rs.x; y += rs.y; z += rs.z; return *this; }
|
||||
FI XYZval<T>& operator-=(const XYZval<T> &rs) { x -= rs.x; y -= rs.y; z -= rs.z; return *this; }
|
||||
FI XYZval<T>& operator*=(const XYZval<T> &rs) { x *= rs.x; y *= rs.y; z *= rs.z; return *this; }
|
||||
FI XYZval<T>& operator/=(const XYZval<T> &rs) { x /= rs.x; y /= rs.y; z /= rs.z; return *this; }
|
||||
FI XYZval<T>& operator+=(const XYZEval<T> &rs) { x += rs.x; y += rs.y; z += rs.z; return *this; }
|
||||
FI XYZval<T>& operator-=(const XYZEval<T> &rs) { x -= rs.x; y -= rs.y; z -= rs.z; return *this; }
|
||||
FI XYZval<T>& operator*=(const XYZEval<T> &rs) { x *= rs.x; y *= rs.y; z *= rs.z; return *this; }
|
||||
FI XYZval<T>& operator/=(const XYZEval<T> &rs) { x /= rs.x; y /= rs.y; z /= rs.z; return *this; }
|
||||
FI XYZval<T>& operator*=(const float &v) { x *= v; y *= v; z *= v; return *this; }
|
||||
FI XYZval<T>& operator*=(const int &v) { x *= v; y *= v; z *= v; return *this; }
|
||||
FI XYZval<T>& operator>>=(const int &v) { _RS(x); _RS(y); _RS(z); return *this; }
|
||||
FI XYZval<T>& operator<<=(const int &v) { _LS(x); _LS(y); _LS(z); return *this; }
|
||||
FI bool operator==(const XYZEval<T> &rs) { return x == rs.x && y == rs.y && z == rs.z; }
|
||||
FI XYZval<T>& operator= (const XYZEval<T> &rs) { set(LINEAR_AXIS_LIST(rs.x, rs.y, rs.z)); return *this; }
|
||||
FI XYZval<T> operator+ (const XYval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, NOOP ); return ls; }
|
||||
FI XYZval<T> operator+ (const XYval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, NOOP ); return ls; }
|
||||
FI XYZval<T> operator- (const XYval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, NOOP ); return ls; }
|
||||
FI XYZval<T> operator- (const XYval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, NOOP ); return ls; }
|
||||
FI XYZval<T> operator* (const XYval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, NOOP ); return ls; }
|
||||
FI XYZval<T> operator* (const XYval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, NOOP ); return ls; }
|
||||
FI XYZval<T> operator/ (const XYval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, NOOP ); return ls; }
|
||||
FI XYZval<T> operator/ (const XYval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, NOOP ); return ls; }
|
||||
FI XYZval<T> operator+ (const XYZval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, ls.z += rs.z); return ls; }
|
||||
FI XYZval<T> operator+ (const XYZval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, ls.z += rs.z); return ls; }
|
||||
FI XYZval<T> operator- (const XYZval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z); return ls; }
|
||||
FI XYZval<T> operator- (const XYZval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z); return ls; }
|
||||
FI XYZval<T> operator* (const XYZval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z); return ls; }
|
||||
FI XYZval<T> operator* (const XYZval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z); return ls; }
|
||||
FI XYZval<T> operator/ (const XYZval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z); return ls; }
|
||||
FI XYZval<T> operator/ (const XYZval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z); return ls; }
|
||||
FI XYZval<T> operator+ (const XYZEval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, ls.z += rs.z); return ls; }
|
||||
FI XYZval<T> operator+ (const XYZEval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, ls.z += rs.z); return ls; }
|
||||
FI XYZval<T> operator- (const XYZEval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z); return ls; }
|
||||
FI XYZval<T> operator- (const XYZEval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z); return ls; }
|
||||
FI XYZval<T> operator* (const XYZEval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z); return ls; }
|
||||
FI XYZval<T> operator* (const XYZEval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z); return ls; }
|
||||
FI XYZval<T> operator/ (const XYZEval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z); return ls; }
|
||||
FI XYZval<T> operator/ (const XYZEval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z); return ls; }
|
||||
FI XYZval<T> operator* (const float &v) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= v, ls.y *= v, ls.z *= v ); return ls; }
|
||||
FI XYZval<T> operator* (const float &v) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= v, ls.y *= v, ls.z *= v ); return ls; }
|
||||
FI XYZval<T> operator* (const int &v) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= v, ls.y *= v, ls.z *= v ); return ls; }
|
||||
FI XYZval<T> operator* (const int &v) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= v, ls.y *= v, ls.z *= v ); return ls; }
|
||||
FI XYZval<T> operator/ (const float &v) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= v, ls.y /= v, ls.z /= v ); return ls; }
|
||||
FI XYZval<T> operator/ (const float &v) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= v, ls.y /= v, ls.z /= v ); return ls; }
|
||||
FI XYZval<T> operator/ (const int &v) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= v, ls.y /= v, ls.z /= v ); return ls; }
|
||||
FI XYZval<T> operator/ (const int &v) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= v, ls.y /= v, ls.z /= v ); return ls; }
|
||||
FI XYZval<T> operator>>(const int &v) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(_RS(ls.x), _RS(ls.y), _RS(ls.z) ); return ls; }
|
||||
FI XYZval<T> operator>>(const int &v) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(_RS(ls.x), _RS(ls.y), _RS(ls.z) ); return ls; }
|
||||
FI XYZval<T> operator<<(const int &v) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(_LS(ls.x), _LS(ls.y), _LS(ls.z) ); return ls; }
|
||||
FI XYZval<T> operator<<(const int &v) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(_LS(ls.x), _LS(ls.y), _LS(ls.z) ); return ls; }
|
||||
FI XYZval<T>& operator+=(const XYval<T> &rs) { LINEAR_AXIS_CODE(x += rs.x, y += rs.y, NOOP ); return *this; }
|
||||
FI XYZval<T>& operator-=(const XYval<T> &rs) { LINEAR_AXIS_CODE(x -= rs.x, y -= rs.y, NOOP ); return *this; }
|
||||
FI XYZval<T>& operator*=(const XYval<T> &rs) { LINEAR_AXIS_CODE(x *= rs.x, y *= rs.y, NOOP ); return *this; }
|
||||
FI XYZval<T>& operator/=(const XYval<T> &rs) { LINEAR_AXIS_CODE(x /= rs.x, y /= rs.y, NOOP ); return *this; }
|
||||
FI XYZval<T>& operator+=(const XYZval<T> &rs) { LINEAR_AXIS_CODE(x += rs.x, y += rs.y, z += rs.z ); return *this; }
|
||||
FI XYZval<T>& operator-=(const XYZval<T> &rs) { LINEAR_AXIS_CODE(x -= rs.x, y -= rs.y, z -= rs.z ); return *this; }
|
||||
FI XYZval<T>& operator*=(const XYZval<T> &rs) { LINEAR_AXIS_CODE(x *= rs.x, y *= rs.y, z *= rs.z ); return *this; }
|
||||
FI XYZval<T>& operator/=(const XYZval<T> &rs) { LINEAR_AXIS_CODE(x /= rs.x, y /= rs.y, z /= rs.z ); return *this; }
|
||||
FI XYZval<T>& operator+=(const XYZEval<T> &rs) { LINEAR_AXIS_CODE(x += rs.x, y += rs.y, z += rs.z ); return *this; }
|
||||
FI XYZval<T>& operator-=(const XYZEval<T> &rs) { LINEAR_AXIS_CODE(x -= rs.x, y -= rs.y, z -= rs.z ); return *this; }
|
||||
FI XYZval<T>& operator*=(const XYZEval<T> &rs) { LINEAR_AXIS_CODE(x *= rs.x, y *= rs.y, z *= rs.z ); return *this; }
|
||||
FI XYZval<T>& operator/=(const XYZEval<T> &rs) { LINEAR_AXIS_CODE(x /= rs.x, y /= rs.y, z /= rs.z ); return *this; }
|
||||
FI XYZval<T>& operator*=(const float &v) { LINEAR_AXIS_CODE(x *= v, y *= v, z *= v ); return *this; }
|
||||
FI XYZval<T>& operator*=(const int &v) { LINEAR_AXIS_CODE(x *= v, y *= v, z *= v ); return *this; }
|
||||
FI XYZval<T>& operator>>=(const int &v) { LINEAR_AXIS_CODE(_RS(x), _RS(y), _RS(z) ); return *this; }
|
||||
FI XYZval<T>& operator<<=(const int &v) { LINEAR_AXIS_CODE(_LS(x), _LS(y), _LS(z) ); return *this; }
|
||||
FI bool operator==(const XYZEval<T> &rs) { return true LINEAR_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z); }
|
||||
FI bool operator==(const XYZEval<T> &rs) const { return true LINEAR_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z); }
|
||||
FI bool operator!=(const XYZEval<T> &rs) { return !operator==(rs); }
|
||||
FI bool operator==(const XYZEval<T> &rs) const { return x == rs.x && y == rs.y && z == rs.z; }
|
||||
FI bool operator!=(const XYZEval<T> &rs) const { return !operator==(rs); }
|
||||
FI XYZval<T> operator-() { XYZval<T> o = *this; o.x = -x; o.y = -y; o.z = -z; return o; }
|
||||
FI const XYZval<T> operator-() const { XYZval<T> o = *this; o.x = -x; o.y = -y; o.z = -z; return o; }
|
||||
FI XYZval<T> operator-() { XYZval<T> o = *this; LINEAR_AXIS_CODE(o.x = -x, o.y = -y, o.z = -z); return o; }
|
||||
FI const XYZval<T> operator-() const { XYZval<T> o = *this; LINEAR_AXIS_CODE(o.x = -x, o.y = -y, o.z = -z); return o; }
|
||||
};
|
||||
|
||||
//
|
||||
// XYZE coordinates, counters, etc.
|
||||
// Logical Axes coordinates, counters, etc.
|
||||
//
|
||||
template<typename T>
|
||||
struct XYZEval {
|
||||
union {
|
||||
struct{ T x, y, z, e; };
|
||||
struct{ T a, b, c; };
|
||||
T pos[4];
|
||||
struct{ T LOGICAL_AXIS_LIST(e, x, y, z); };
|
||||
struct{ T LINEAR_AXIS_LIST(a, b, c); };
|
||||
T pos[LOGICAL_AXES];
|
||||
};
|
||||
FI void reset() { x = y = z = e = 0; }
|
||||
FI T magnitude() const { return (T)sqrtf(x*x + y*y + z*z + e*e); }
|
||||
FI void reset() { LOGICAL_AXIS_GANG(e =, x =, y =, z =) 0; }
|
||||
FI T magnitude() const { return (T)sqrtf(LOGICAL_AXIS_GANG(+ e*e, + x*x, + y*y, + z*z)); }
|
||||
FI operator T* () { return pos; }
|
||||
FI operator bool() { return e || z || x || y; }
|
||||
FI void set(const T px) { x = px; }
|
||||
FI void set(const T px, const T py) { x = px; y = py; }
|
||||
FI void set(const T px, const T py, const T pz) { x = px; y = py; z = pz; }
|
||||
FI void set(const T px, const T py, const T pz, const T pe) { x = px; y = py; z = pz; e = pe; }
|
||||
FI void set(const XYval<T> pxy) { x = pxy.x; y = pxy.y; }
|
||||
FI void set(const XYval<T> pxy, const T pz) { x = pxy.x; y = pxy.y; z = pz; }
|
||||
FI void set(const XYZval<T> pxyz) { x = pxyz.x; y = pxyz.y; z = pxyz.z; }
|
||||
FI void set(const XYval<T> pxy, const T pz, const T pe) { x = pxy.x; y = pxy.y; z = pz; e = pe; }
|
||||
FI void set(const XYval<T> pxy, const XYval<T> pze) { x = pxy.x; y = pxy.y; z = pze.z; e = pze.e; }
|
||||
FI void set(const XYZval<T> pxyz, const T pe) { x = pxyz.x; y = pxyz.y; z = pxyz.z; e = pe; }
|
||||
FI void set(const T (&arr)[XY]) { x = arr[0]; y = arr[1]; }
|
||||
FI void set(const T (&arr)[XYZ]) { x = arr[0]; y = arr[1]; z = arr[2]; }
|
||||
FI void set(const T (&arr)[XYZE]) { x = arr[0]; y = arr[1]; z = arr[2]; e = arr[3]; }
|
||||
#if DISTINCT_AXES > XYZE
|
||||
FI void set(const T (&arr)[DISTINCT_AXES]) { x = arr[0]; y = arr[1]; z = arr[2]; e = arr[3]; }
|
||||
FI operator bool() { return false LOGICAL_AXIS_GANG(|| e, || x, || y, || z); }
|
||||
FI void set(const T px) { x = px; }
|
||||
FI void set(const T px, const T py) { x = px; y = py; }
|
||||
FI void set(const XYval<T> pxy) { x = pxy.x; y = pxy.y; }
|
||||
FI void set(const XYZval<T> pxyz) { set(LINEAR_AXIS_LIST(pxyz.x, pxyz.y, pxyz.z)); }
|
||||
#if LINEAR_AXES >= XYZ
|
||||
FI void set(LINEAR_AXIS_LIST(const T px, const T py, const T pz)) {
|
||||
LINEAR_AXIS_CODE(x = px, y = py, z = pz);
|
||||
}
|
||||
#endif
|
||||
FI XYZEval<T> copy() const { return *this; }
|
||||
FI XYZEval<T> ABS() const { return { T(_ABS(x)), T(_ABS(y)), T(_ABS(z)), T(_ABS(e)) }; }
|
||||
FI XYZEval<int16_t> asInt() { return { int16_t(x), int16_t(y), int16_t(z), int16_t(e) }; }
|
||||
FI XYZEval<int16_t> asInt() const { return { int16_t(x), int16_t(y), int16_t(z), int16_t(e) }; }
|
||||
FI XYZEval<int32_t> asLong() { return { int32_t(x), int32_t(y), int32_t(z), int32_t(e) }; }
|
||||
FI XYZEval<int32_t> asLong() const { return { int32_t(x), int32_t(y), int32_t(z), int32_t(e) }; }
|
||||
FI XYZEval<int32_t> ROUNDL() { return { int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(e)) }; }
|
||||
FI XYZEval<int32_t> ROUNDL() const { return { int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z)), int32_t(LROUND(e)) }; }
|
||||
FI XYZEval<float> asFloat() { return { static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(e) }; }
|
||||
FI XYZEval<float> asFloat() const { return { static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(e) }; }
|
||||
FI XYZEval<float> reciprocal() const { return { _RECIP(x), _RECIP(y), _RECIP(z), _RECIP(e) }; }
|
||||
#if LOGICAL_AXES > LINEAR_AXES
|
||||
FI void set(LOGICAL_AXIS_LIST(const T pe, const T px, const T py, const T pz)) {
|
||||
LOGICAL_AXIS_CODE(e = pe, x = px, y = py, z = pz);
|
||||
}
|
||||
FI void set(const XYval<T> pxy, const T pe) { set(pxy); e = pe; }
|
||||
FI void set(const XYZval<T> pxyz, const T pe) { set(pxyz); e = pe; }
|
||||
#endif
|
||||
FI XYZEval<T> copy() const { XYZEval<T> o = *this; return o; }
|
||||
FI XYZEval<T> ABS() const { return LOGICAL_AXIS_ARRAY(T(_ABS(e)), T(_ABS(x)), T(_ABS(y)), T(_ABS(z))); }
|
||||
FI XYZEval<int16_t> asInt() { return LOGICAL_AXIS_ARRAY(int16_t(e), int16_t(x), int16_t(y), int16_t(z)); }
|
||||
FI XYZEval<int16_t> asInt() const { return LOGICAL_AXIS_ARRAY(int16_t(e), int16_t(x), int16_t(y), int16_t(z)); }
|
||||
FI XYZEval<int32_t> asLong() { return LOGICAL_AXIS_ARRAY(int32_t(e), int32_t(x), int32_t(y), int32_t(z)); }
|
||||
FI XYZEval<int32_t> asLong() const { return LOGICAL_AXIS_ARRAY(int32_t(e), int32_t(x), int32_t(y), int32_t(z)); }
|
||||
FI XYZEval<int32_t> ROUNDL() { return LOGICAL_AXIS_ARRAY(int32_t(LROUND(e)), int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z))); }
|
||||
FI XYZEval<int32_t> ROUNDL() const { return LOGICAL_AXIS_ARRAY(int32_t(LROUND(e)), int32_t(LROUND(x)), int32_t(LROUND(y)), int32_t(LROUND(z))); }
|
||||
FI XYZEval<float> asFloat() { return LOGICAL_AXIS_ARRAY(static_cast<float>(e), static_cast<float>(x), static_cast<float>(y), static_cast<float>(z)); }
|
||||
FI XYZEval<float> asFloat() const { return LOGICAL_AXIS_ARRAY(static_cast<float>(e), static_cast<float>(x), static_cast<float>(y), static_cast<float>(z)); }
|
||||
FI XYZEval<float> reciprocal() const { return LOGICAL_AXIS_ARRAY(_RECIP(e), _RECIP(x), _RECIP(y), _RECIP(z)); }
|
||||
FI XYZEval<float> asLogical() const { XYZEval<float> o = asFloat(); toLogical(o); return o; }
|
||||
FI XYZEval<float> asNative() const { XYZEval<float> o = asFloat(); toNative(o); return o; }
|
||||
FI operator XYval<T>&() { return *(XYval<T>*)this; }
|
||||
FI operator const XYval<T>&() const { return *(const XYval<T>*)this; }
|
||||
FI operator XYZval<T>&() { return *(XYZval<T>*)this; }
|
||||
FI operator const XYZval<T>&() const { return *(const XYZval<T>*)this; }
|
||||
FI T& operator[](const int i) { return pos[i]; }
|
||||
FI const T& operator[](const int i) const { return pos[i]; }
|
||||
FI XYZEval<T>& operator= (const T v) { set(v, v, v, v); return *this; }
|
||||
FI T& operator[](const int n) { return pos[n]; }
|
||||
FI const T& operator[](const int n) const { return pos[n]; }
|
||||
FI XYZEval<T>& operator= (const T v) { set(LIST_N_1(LINEAR_AXES, v)); return *this; }
|
||||
FI XYZEval<T>& operator= (const XYval<T> &rs) { set(rs.x, rs.y); return *this; }
|
||||
FI XYZEval<T>& operator= (const XYZval<T> &rs) { set(rs.x, rs.y, rs.z); return *this; }
|
||||
FI XYZEval<T> operator+ (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
|
||||
FI XYZEval<T> operator+ (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
|
||||
FI XYZEval<T> operator- (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
|
||||
FI XYZEval<T> operator- (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
|
||||
FI XYZEval<T> operator* (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
|
||||
FI XYZEval<T> operator* (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
|
||||
FI XYZEval<T> operator/ (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
|
||||
FI XYZEval<T> operator/ (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
|
||||
FI XYZEval<T> operator+ (const XYZval<T> &rs) const { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; ls.z += rs.z; return ls; }
|
||||
FI XYZEval<T> operator+ (const XYZval<T> &rs) { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; ls.z += rs.z; return ls; }
|
||||
FI XYZEval<T> operator- (const XYZval<T> &rs) const { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; ls.z -= rs.z; return ls; }
|
||||
FI XYZEval<T> operator- (const XYZval<T> &rs) { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; ls.z -= rs.z; return ls; }
|
||||
FI XYZEval<T> operator* (const XYZval<T> &rs) const { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; ls.z *= rs.z; return ls; }
|
||||
FI XYZEval<T> operator* (const XYZval<T> &rs) { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; ls.z *= rs.z; return ls; }
|
||||
FI XYZEval<T> operator/ (const XYZval<T> &rs) const { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; return ls; }
|
||||
FI XYZEval<T> operator/ (const XYZval<T> &rs) { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; return ls; }
|
||||
FI XYZEval<T> operator+ (const XYZEval<T> &rs) const { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; ls.z += rs.z; ls.e += rs.e; return ls; }
|
||||
FI XYZEval<T> operator+ (const XYZEval<T> &rs) { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; ls.z += rs.z; ls.e += rs.e; return ls; }
|
||||
FI XYZEval<T> operator- (const XYZEval<T> &rs) const { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; ls.z -= rs.z; ls.e -= rs.e; return ls; }
|
||||
FI XYZEval<T> operator- (const XYZEval<T> &rs) { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; ls.z -= rs.z; ls.e -= rs.e; return ls; }
|
||||
FI XYZEval<T> operator* (const XYZEval<T> &rs) const { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; ls.z *= rs.z; ls.e *= rs.e; return ls; }
|
||||
FI XYZEval<T> operator* (const XYZEval<T> &rs) { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; ls.z *= rs.z; ls.e *= rs.e; return ls; }
|
||||
FI XYZEval<T> operator/ (const XYZEval<T> &rs) const { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; ls.e /= rs.e; return ls; }
|
||||
FI XYZEval<T> operator/ (const XYZEval<T> &rs) { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; ls.z /= rs.z; ls.e /= rs.e; return ls; }
|
||||
FI XYZEval<T> operator* (const float &v) const { XYZEval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; ls.e *= v; return ls; }
|
||||
FI XYZEval<T> operator* (const float &v) { XYZEval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; ls.e *= v; return ls; }
|
||||
FI XYZEval<T> operator* (const int &v) const { XYZEval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; ls.e *= v; return ls; }
|
||||
FI XYZEval<T> operator* (const int &v) { XYZEval<T> ls = *this; ls.x *= v; ls.y *= v; ls.z *= v; ls.e *= v; return ls; }
|
||||
FI XYZEval<T> operator/ (const float &v) const { XYZEval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; ls.e /= v; return ls; }
|
||||
FI XYZEval<T> operator/ (const float &v) { XYZEval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; ls.e /= v; return ls; }
|
||||
FI XYZEval<T> operator/ (const int &v) const { XYZEval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; ls.e /= v; return ls; }
|
||||
FI XYZEval<T> operator/ (const int &v) { XYZEval<T> ls = *this; ls.x /= v; ls.y /= v; ls.z /= v; ls.e /= v; return ls; }
|
||||
FI XYZEval<T> operator>>(const int &v) const { XYZEval<T> ls = *this; _RS(ls.x); _RS(ls.y); _RS(ls.z); _RS(ls.e); return ls; }
|
||||
FI XYZEval<T> operator>>(const int &v) { XYZEval<T> ls = *this; _RS(ls.x); _RS(ls.y); _RS(ls.z); _RS(ls.e); return ls; }
|
||||
FI XYZEval<T> operator<<(const int &v) const { XYZEval<T> ls = *this; _LS(ls.x); _LS(ls.y); _LS(ls.z); _LS(ls.e); return ls; }
|
||||
FI XYZEval<T> operator<<(const int &v) { XYZEval<T> ls = *this; _LS(ls.x); _LS(ls.y); _LS(ls.z); _LS(ls.e); return ls; }
|
||||
FI XYZEval<T>& operator+=(const XYval<T> &rs) { x += rs.x; y += rs.y; return *this; }
|
||||
FI XYZEval<T>& operator-=(const XYval<T> &rs) { x -= rs.x; y -= rs.y; return *this; }
|
||||
FI XYZEval<T>& operator*=(const XYval<T> &rs) { x *= rs.x; y *= rs.y; return *this; }
|
||||
FI XYZEval<T>& operator/=(const XYval<T> &rs) { x /= rs.x; y /= rs.y; return *this; }
|
||||
FI XYZEval<T>& operator+=(const XYZval<T> &rs) { x += rs.x; y += rs.y; z += rs.z; return *this; }
|
||||
FI XYZEval<T>& operator-=(const XYZval<T> &rs) { x -= rs.x; y -= rs.y; z -= rs.z; return *this; }
|
||||
FI XYZEval<T>& operator*=(const XYZval<T> &rs) { x *= rs.x; y *= rs.y; z *= rs.z; return *this; }
|
||||
FI XYZEval<T>& operator/=(const XYZval<T> &rs) { x /= rs.x; y /= rs.y; z /= rs.z; return *this; }
|
||||
FI XYZEval<T>& operator+=(const XYZEval<T> &rs) { x += rs.x; y += rs.y; z += rs.z; e += rs.e; return *this; }
|
||||
FI XYZEval<T>& operator-=(const XYZEval<T> &rs) { x -= rs.x; y -= rs.y; z -= rs.z; e -= rs.e; return *this; }
|
||||
FI XYZEval<T>& operator*=(const XYZEval<T> &rs) { x *= rs.x; y *= rs.y; z *= rs.z; e *= rs.e; return *this; }
|
||||
FI XYZEval<T>& operator/=(const XYZEval<T> &rs) { x /= rs.x; y /= rs.y; z /= rs.z; e /= rs.e; return *this; }
|
||||
FI XYZEval<T>& operator*=(const T &v) { x *= v; y *= v; z *= v; e *= v; return *this; }
|
||||
FI XYZEval<T>& operator>>=(const int &v) { _RS(x); _RS(y); _RS(z); _RS(e); return *this; }
|
||||
FI XYZEval<T>& operator<<=(const int &v) { _LS(x); _LS(y); _LS(z); _LS(e); return *this; }
|
||||
FI bool operator==(const XYZval<T> &rs) { return x == rs.x && y == rs.y && z == rs.z; }
|
||||
FI XYZEval<T>& operator= (const XYZval<T> &rs) { set(LINEAR_AXIS_LIST(rs.x, rs.y, rs.z)); return *this; }
|
||||
FI XYZEval<T> operator+ (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
|
||||
FI XYZEval<T> operator+ (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x += rs.x; ls.y += rs.y; return ls; }
|
||||
FI XYZEval<T> operator- (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
|
||||
FI XYZEval<T> operator- (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x -= rs.x; ls.y -= rs.y; return ls; }
|
||||
FI XYZEval<T> operator* (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
|
||||
FI XYZEval<T> operator* (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x *= rs.x; ls.y *= rs.y; return ls; }
|
||||
FI XYZEval<T> operator/ (const XYval<T> &rs) const { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
|
||||
FI XYZEval<T> operator/ (const XYval<T> &rs) { XYZEval<T> ls = *this; ls.x /= rs.x; ls.y /= rs.y; return ls; }
|
||||
FI XYZEval<T> operator+ (const XYZval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, ls.z += rs.z); return ls; }
|
||||
FI XYZEval<T> operator+ (const XYZval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x += rs.x, ls.y += rs.y, ls.z += rs.z); return ls; }
|
||||
FI XYZEval<T> operator- (const XYZval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z); return ls; }
|
||||
FI XYZEval<T> operator- (const XYZval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z); return ls; }
|
||||
FI XYZEval<T> operator* (const XYZval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z); return ls; }
|
||||
FI XYZEval<T> operator* (const XYZval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z); return ls; }
|
||||
FI XYZEval<T> operator/ (const XYZval<T> &rs) const { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z); return ls; }
|
||||
FI XYZEval<T> operator/ (const XYZval<T> &rs) { XYZval<T> ls = *this; LINEAR_AXIS_CODE(ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z); return ls; }
|
||||
FI XYZEval<T> operator+ (const XYZEval<T> &rs) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e += rs.e, ls.x += rs.x, ls.y += rs.y, ls.z += rs.z ); return ls; }
|
||||
FI XYZEval<T> operator+ (const XYZEval<T> &rs) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e += rs.e, ls.x += rs.x, ls.y += rs.y, ls.z += rs.z ); return ls; }
|
||||
FI XYZEval<T> operator- (const XYZEval<T> &rs) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e -= rs.e, ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z ); return ls; }
|
||||
FI XYZEval<T> operator- (const XYZEval<T> &rs) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e -= rs.e, ls.x -= rs.x, ls.y -= rs.y, ls.z -= rs.z ); return ls; }
|
||||
FI XYZEval<T> operator* (const XYZEval<T> &rs) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= rs.e, ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z ); return ls; }
|
||||
FI XYZEval<T> operator* (const XYZEval<T> &rs) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= rs.e, ls.x *= rs.x, ls.y *= rs.y, ls.z *= rs.z ); return ls; }
|
||||
FI XYZEval<T> operator/ (const XYZEval<T> &rs) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= rs.e, ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z ); return ls; }
|
||||
FI XYZEval<T> operator/ (const XYZEval<T> &rs) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= rs.e, ls.x /= rs.x, ls.y /= rs.y, ls.z /= rs.z ); return ls; }
|
||||
FI XYZEval<T> operator* (const float &v) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= v, ls.x *= v, ls.y *= v, ls.z *= v ); return ls; }
|
||||
FI XYZEval<T> operator* (const float &v) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= v, ls.x *= v, ls.y *= v, ls.z *= v ); return ls; }
|
||||
FI XYZEval<T> operator* (const int &v) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= v, ls.x *= v, ls.y *= v, ls.z *= v ); return ls; }
|
||||
FI XYZEval<T> operator* (const int &v) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e *= v, ls.x *= v, ls.y *= v, ls.z *= v ); return ls; }
|
||||
FI XYZEval<T> operator/ (const float &v) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= v, ls.x /= v, ls.y /= v, ls.z /= v ); return ls; }
|
||||
FI XYZEval<T> operator/ (const float &v) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= v, ls.x /= v, ls.y /= v, ls.z /= v ); return ls; }
|
||||
FI XYZEval<T> operator/ (const int &v) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= v, ls.x /= v, ls.y /= v, ls.z /= v ); return ls; }
|
||||
FI XYZEval<T> operator/ (const int &v) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(ls.e /= v, ls.x /= v, ls.y /= v, ls.z /= v ); return ls; }
|
||||
FI XYZEval<T> operator>>(const int &v) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(_RS(ls.e), _RS(ls.x), _RS(ls.y), _RS(ls.z) ); return ls; }
|
||||
FI XYZEval<T> operator>>(const int &v) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(_RS(ls.e), _RS(ls.x), _RS(ls.y), _RS(ls.z) ); return ls; }
|
||||
FI XYZEval<T> operator<<(const int &v) const { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(_LS(ls.e), _LS(ls.x), _LS(ls.y), _LS(ls.z) ); return ls; }
|
||||
FI XYZEval<T> operator<<(const int &v) { XYZEval<T> ls = *this; LOGICAL_AXIS_CODE(_LS(ls.e), _LS(ls.x), _LS(ls.y), _LS(ls.z) ); return ls; }
|
||||
FI XYZEval<T>& operator+=(const XYval<T> &rs) { x += rs.x; y += rs.y; return *this; }
|
||||
FI XYZEval<T>& operator-=(const XYval<T> &rs) { x -= rs.x; y -= rs.y; return *this; }
|
||||
FI XYZEval<T>& operator*=(const XYval<T> &rs) { x *= rs.x; y *= rs.y; return *this; }
|
||||
FI XYZEval<T>& operator/=(const XYval<T> &rs) { x /= rs.x; y /= rs.y; return *this; }
|
||||
FI XYZEval<T>& operator+=(const XYZval<T> &rs) { LINEAR_AXIS_CODE(x += rs.x, y += rs.y, z += rs.z); return *this; }
|
||||
FI XYZEval<T>& operator-=(const XYZval<T> &rs) { LINEAR_AXIS_CODE(x -= rs.x, y -= rs.y, z -= rs.z); return *this; }
|
||||
FI XYZEval<T>& operator*=(const XYZval<T> &rs) { LINEAR_AXIS_CODE(x *= rs.x, y *= rs.y, z *= rs.z); return *this; }
|
||||
FI XYZEval<T>& operator/=(const XYZval<T> &rs) { LINEAR_AXIS_CODE(x /= rs.x, y /= rs.y, z /= rs.z); return *this; }
|
||||
FI XYZEval<T>& operator+=(const XYZEval<T> &rs) { LOGICAL_AXIS_CODE(e += rs.e, x += rs.x, y += rs.y, z += rs.z); return *this; }
|
||||
FI XYZEval<T>& operator-=(const XYZEval<T> &rs) { LOGICAL_AXIS_CODE(e -= rs.e, x -= rs.x, y -= rs.y, z -= rs.z); return *this; }
|
||||
FI XYZEval<T>& operator*=(const XYZEval<T> &rs) { LOGICAL_AXIS_CODE(e *= rs.e, x *= rs.x, y *= rs.y, z *= rs.z); return *this; }
|
||||
FI XYZEval<T>& operator/=(const XYZEval<T> &rs) { LOGICAL_AXIS_CODE(e /= rs.e, x /= rs.x, y /= rs.y, z /= rs.z); return *this; }
|
||||
FI XYZEval<T>& operator*=(const T &v) { LOGICAL_AXIS_CODE(e *= v, x *= v, y *= v, z *= v); return *this; }
|
||||
FI XYZEval<T>& operator>>=(const int &v) { LOGICAL_AXIS_CODE(_RS(e), _RS(x), _RS(y), _RS(z)); return *this; }
|
||||
FI XYZEval<T>& operator<<=(const int &v) { LOGICAL_AXIS_CODE(_LS(e), _LS(x), _LS(y), _LS(z)); return *this; }
|
||||
FI bool operator==(const XYZval<T> &rs) { return true LINEAR_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z); }
|
||||
FI bool operator==(const XYZval<T> &rs) const { return true LINEAR_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z); }
|
||||
FI bool operator!=(const XYZval<T> &rs) { return !operator==(rs); }
|
||||
FI bool operator==(const XYZval<T> &rs) const { return x == rs.x && y == rs.y && z == rs.z; }
|
||||
FI bool operator!=(const XYZval<T> &rs) const { return !operator==(rs); }
|
||||
FI XYZEval<T> operator-() { return { -x, -y, -z, -e }; }
|
||||
FI const XYZEval<T> operator-() const { return { -x, -y, -z, -e }; }
|
||||
FI XYZEval<T> operator-() { return LOGICAL_AXIS_ARRAY(-e, -x, -y, -z); }
|
||||
FI const XYZEval<T> operator-() const { return LOGICAL_AXIS_ARRAY(-e, -x, -y, -z); }
|
||||
};
|
||||
|
||||
#undef _RECIP
|
||||
@ -514,6 +573,3 @@ struct XYZEval {
|
||||
#undef _LS
|
||||
#undef _RS
|
||||
#undef FI
|
||||
|
||||
const xyze_char_t axis_codes { 'X', 'Y', 'Z', 'E' };
|
||||
#define AXIS_CHAR(A) ((char)('X' + A))
|
||||
|
@ -76,3 +76,11 @@ public:
|
||||
// Converts from an uint8_t in the range of 0-255 to an uint8_t
|
||||
// in the range 0-100 while avoiding rounding artifacts
|
||||
constexpr uint8_t ui8_to_percent(const uint8_t i) { return (int(i) * 100 + 127) / 255; }
|
||||
|
||||
const xyze_char_t axis_codes LOGICAL_AXIS_ARRAY('E', 'X', 'Y', 'Z');
|
||||
|
||||
#if LINEAR_AXES <= XYZ
|
||||
#define AXIS_CHAR(A) ((char)('X' + A))
|
||||
#else
|
||||
#define AXIS_CHAR(A) axis_codes[A]
|
||||
#endif
|
||||
|
@ -327,7 +327,7 @@ int32_t I2CPositionEncoder::get_raw_count() {
|
||||
}
|
||||
|
||||
bool I2CPositionEncoder::test_axis() {
|
||||
//only works on XYZ cartesian machines for the time being
|
||||
// Only works on XYZ Cartesian machines for the time being
|
||||
if (!(encoderAxis == X_AXIS || encoderAxis == Y_AXIS || encoderAxis == Z_AXIS)) return false;
|
||||
|
||||
const float startPosition = soft_endstop.min[encoderAxis] + 10,
|
||||
@ -345,9 +345,12 @@ bool I2CPositionEncoder::test_axis() {
|
||||
endCoord[encoderAxis] = endPosition;
|
||||
|
||||
planner.synchronize();
|
||||
startCoord.e = planner.get_axis_position_mm(E_AXIS);
|
||||
planner.buffer_line(startCoord, fr_mm_s, 0);
|
||||
planner.synchronize();
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
startCoord.e = planner.get_axis_position_mm(E_AXIS);
|
||||
planner.buffer_line(startCoord, fr_mm_s, 0);
|
||||
planner.synchronize();
|
||||
#endif
|
||||
|
||||
// if the module isn't currently trusted, wait until it is (or until it should be if things are working)
|
||||
if (!trusted) {
|
||||
@ -357,7 +360,7 @@ bool I2CPositionEncoder::test_axis() {
|
||||
}
|
||||
|
||||
if (trusted) { // if trusted, commence test
|
||||
endCoord.e = planner.get_axis_position_mm(E_AXIS);
|
||||
TERN_(HAS_EXTRUDERS, endCoord.e = planner.get_axis_position_mm(E_AXIS));
|
||||
planner.buffer_line(endCoord, fr_mm_s, 0);
|
||||
planner.synchronize();
|
||||
}
|
||||
@ -402,7 +405,7 @@ void I2CPositionEncoder::calibrate_steps_mm(const uint8_t iter) {
|
||||
planner.synchronize();
|
||||
|
||||
LOOP_L_N(i, iter) {
|
||||
startCoord.e = planner.get_axis_position_mm(E_AXIS);
|
||||
TERN_(HAS_EXTRUDERS, startCoord.e = planner.get_axis_position_mm(E_AXIS));
|
||||
planner.buffer_line(startCoord, fr_mm_s, 0);
|
||||
planner.synchronize();
|
||||
|
||||
@ -411,7 +414,7 @@ void I2CPositionEncoder::calibrate_steps_mm(const uint8_t iter) {
|
||||
|
||||
//do_blocking_move_to(endCoord);
|
||||
|
||||
endCoord.e = planner.get_axis_position_mm(E_AXIS);
|
||||
TERN_(HAS_EXTRUDERS, endCoord.e = planner.get_axis_position_mm(E_AXIS));
|
||||
planner.buffer_line(endCoord, fr_mm_s, 0);
|
||||
planner.synchronize();
|
||||
|
||||
@ -497,9 +500,7 @@ void I2CPositionEncodersMgr::init() {
|
||||
|
||||
encoders[i].set_active(encoders[i].passes_test(true));
|
||||
|
||||
#if I2CPE_ENC_1_AXIS == E_AXIS
|
||||
encoders[i].set_homed();
|
||||
#endif
|
||||
TERN_(HAS_EXTRUDERS, if (I2CPE_ENC_1_AXIS == E_AXIS) encoders[i].set_homed());
|
||||
#endif
|
||||
|
||||
#if I2CPE_ENCODER_CNT > 1
|
||||
@ -528,9 +529,7 @@ void I2CPositionEncodersMgr::init() {
|
||||
|
||||
encoders[i].set_active(encoders[i].passes_test(true));
|
||||
|
||||
#if I2CPE_ENC_2_AXIS == E_AXIS
|
||||
encoders[i].set_homed();
|
||||
#endif
|
||||
TERN_(HAS_EXTRUDERS, if (I2CPE_ENC_2_AXIS == E_AXIS) encoders[i].set_homed());
|
||||
#endif
|
||||
|
||||
#if I2CPE_ENCODER_CNT > 2
|
||||
@ -557,11 +556,9 @@ void I2CPositionEncodersMgr::init() {
|
||||
encoders[i].set_ec_threshold(I2CPE_ENC_3_EC_THRESH);
|
||||
#endif
|
||||
|
||||
encoders[i].set_active(encoders[i].passes_test(true));
|
||||
encoders[i].set_active(encoders[i].passes_test(true));
|
||||
|
||||
#if I2CPE_ENC_3_AXIS == E_AXIS
|
||||
encoders[i].set_homed();
|
||||
#endif
|
||||
TERN_(HAS_EXTRUDERS, if (I2CPE_ENC_3_AXIS == E_AXIS) encoders[i].set_homed());
|
||||
#endif
|
||||
|
||||
#if I2CPE_ENCODER_CNT > 3
|
||||
@ -590,9 +587,7 @@ void I2CPositionEncodersMgr::init() {
|
||||
|
||||
encoders[i].set_active(encoders[i].passes_test(true));
|
||||
|
||||
#if I2CPE_ENC_4_AXIS == E_AXIS
|
||||
encoders[i].set_homed();
|
||||
#endif
|
||||
TERN_(HAS_EXTRUDERS, if (I2CPE_ENC_4_AXIS == E_AXIS) encoders[i].set_homed());
|
||||
#endif
|
||||
|
||||
#if I2CPE_ENCODER_CNT > 4
|
||||
@ -621,9 +616,7 @@ void I2CPositionEncodersMgr::init() {
|
||||
|
||||
encoders[i].set_active(encoders[i].passes_test(true));
|
||||
|
||||
#if I2CPE_ENC_5_AXIS == E_AXIS
|
||||
encoders[i].set_homed();
|
||||
#endif
|
||||
TERN_(HAS_EXTRUDERS, if (I2CPE_ENC_5_AXIS == E_AXIS) encoders[i].set_homed());
|
||||
#endif
|
||||
|
||||
#if I2CPE_ENCODER_CNT > 5
|
||||
@ -652,9 +645,7 @@ void I2CPositionEncodersMgr::init() {
|
||||
|
||||
encoders[i].set_active(encoders[i].passes_test(true));
|
||||
|
||||
#if I2CPE_ENC_6_AXIS == E_AXIS
|
||||
encoders[i].set_homed();
|
||||
#endif
|
||||
TERN_(HAS_EXTRUDERS, if (I2CPE_ENC_6_AXIS == E_AXIS) encoders[i].set_homed());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -757,7 +757,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
static void tmc_debug_loop(const TMC_debug_enum i, const bool print_x, const bool print_y, const bool print_z, const bool print_e) {
|
||||
static void tmc_debug_loop(
|
||||
const TMC_debug_enum i,
|
||||
LOGICAL_AXIS_LIST(const bool print_e, const bool print_x, const bool print_y, const bool print_z)
|
||||
) {
|
||||
if (print_x) {
|
||||
#if AXIS_IS_TMC(X)
|
||||
tmc_status(stepperX, i);
|
||||
@ -821,7 +824,10 @@
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
static void drv_status_loop(const TMC_drv_status_enum i, const bool print_x, const bool print_y, const bool print_z, const bool print_e) {
|
||||
static void drv_status_loop(
|
||||
const TMC_drv_status_enum i,
|
||||
LOGICAL_AXIS_LIST(const bool print_e, const bool print_x, const bool print_y, const bool print_z)
|
||||
) {
|
||||
if (print_x) {
|
||||
#if AXIS_IS_TMC(X)
|
||||
tmc_parse_drv_status(stepperX, i);
|
||||
@ -889,9 +895,12 @@
|
||||
* M122 report functions
|
||||
*/
|
||||
|
||||
void tmc_report_all(const bool print_x/*=true*/, const bool print_y/*=true*/, const bool print_z/*=true*/, const bool print_e/*=true*/) {
|
||||
#define TMC_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_debug_loop(ITEM, print_x, print_y, print_z, print_e); }while(0)
|
||||
#define DRV_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); drv_status_loop(ITEM, print_x, print_y, print_z, print_e); }while(0)
|
||||
void tmc_report_all(
|
||||
LOGICAL_AXIS_LIST(const bool print_e/*=true*/, const bool print_x/*=true*/, const bool print_y/*=true*/, const bool print_z/*=true*/)
|
||||
) {
|
||||
#define TMC_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_debug_loop(ITEM, LOGICAL_AXIS_LIST(print_e, print_x, print_y, print_z)); }while(0)
|
||||
#define DRV_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); drv_status_loop(ITEM, LOGICAL_AXIS_LIST(print_e, print_x, print_y, print_z)); }while(0)
|
||||
|
||||
TMC_REPORT("\t", TMC_CODES);
|
||||
#if HAS_DRIVER(TMC2209)
|
||||
TMC_REPORT("Address\t", TMC_UART_ADDR);
|
||||
@ -1015,7 +1024,10 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
static void tmc_get_registers(TMC_get_registers_enum i, const bool print_x, const bool print_y, const bool print_z, const bool print_e) {
|
||||
static void tmc_get_registers(
|
||||
TMC_get_registers_enum i,
|
||||
LOGICAL_AXIS_LIST(const bool print_e, const bool print_x, const bool print_y, const bool print_z)
|
||||
) {
|
||||
if (print_x) {
|
||||
#if AXIS_IS_TMC(X)
|
||||
tmc_get_registers(stepperX, i);
|
||||
@ -1079,8 +1091,10 @@
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
void tmc_get_registers(bool print_x, bool print_y, bool print_z, bool print_e) {
|
||||
#define _TMC_GET_REG(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_get_registers(ITEM, print_x, print_y, print_z, print_e); }while(0)
|
||||
void tmc_get_registers(
|
||||
LOGICAL_AXIS_LIST(bool print_e, bool print_x, bool print_y, bool print_z)
|
||||
) {
|
||||
#define _TMC_GET_REG(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_get_registers(ITEM, LOGICAL_AXIS_LIST(print_e, print_x, print_y, print_z)); }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");
|
||||
@ -1214,7 +1228,9 @@ static bool test_connection(TMC &st) {
|
||||
return test_result;
|
||||
}
|
||||
|
||||
void test_tmc_connection(const bool test_x/*=true*/, const bool test_y/*=true*/, const bool test_z/*=true*/, const bool test_e/*=true*/) {
|
||||
void test_tmc_connection(
|
||||
LOGICAL_AXIS_LIST(const bool test_e/*=true*/, const bool test_x/*=true*/, const bool test_y/*=true*/, const bool test_z/*=true*/)
|
||||
) {
|
||||
uint8_t axis_connection = 0;
|
||||
|
||||
if (test_x) {
|
||||
|
@ -335,14 +335,20 @@ void tmc_print_current(TMC &st) {
|
||||
#endif
|
||||
|
||||
void monitor_tmc_drivers();
|
||||
void test_tmc_connection(const bool test_x=true, const bool test_y=true, const bool test_z=true, const bool test_e=true);
|
||||
void test_tmc_connection(
|
||||
LOGICAL_AXIS_LIST(const bool test_e=true, const bool test_x=true, const bool test_y=true, const bool test_z=true)
|
||||
);
|
||||
|
||||
#if ENABLED(TMC_DEBUG)
|
||||
#if ENABLED(MONITOR_DRIVER_STATUS)
|
||||
void tmc_set_report_interval(const uint16_t update_interval);
|
||||
#endif
|
||||
void tmc_report_all(const bool print_x=true, const bool print_y=true, const bool print_z=true, const bool print_e=true);
|
||||
void tmc_get_registers(const bool print_x, const bool print_y, const bool print_z, const bool print_e);
|
||||
void tmc_report_all(
|
||||
LOGICAL_AXIS_LIST(const bool print_e=true, const bool print_x=true, const bool print_y=true, const bool print_z=true)
|
||||
);
|
||||
void tmc_get_registers(
|
||||
LOGICAL_AXIS_LIST(const bool print_e, const bool print_x, const bool print_y, const bool print_z)
|
||||
);
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -355,7 +361,7 @@ void test_tmc_connection(const bool test_x=true, const bool test_y=true, const b
|
||||
#if USE_SENSORLESS
|
||||
|
||||
// Track enabled status of stealthChop and only re-enable where applicable
|
||||
struct sensorless_t { bool x, y, z, x2, y2, z2, z3, z4; };
|
||||
struct sensorless_t { bool LINEAR_AXIS_LIST(x, y, z), x2, y2, z2, z3, z4; };
|
||||
|
||||
#if ENABLED(IMPROVE_HOMING_RELIABILITY)
|
||||
extern millis_t sg_guard_period;
|
||||
|
@ -321,12 +321,23 @@ void GcodeSuite::G28() {
|
||||
|
||||
#else
|
||||
|
||||
#define _UNSAFE(A) (homeZ && TERN0(Z_SAFE_HOMING, axes_should_home(_BV(A##_AXIS))))
|
||||
|
||||
const bool homeZ = parser.seen_test('Z'),
|
||||
needX = homeZ && TERN0(Z_SAFE_HOMING, axes_should_home(_BV(X_AXIS))),
|
||||
needY = homeZ && TERN0(Z_SAFE_HOMING, axes_should_home(_BV(Y_AXIS))),
|
||||
homeX = needX || parser.seen_test('X'), homeY = needY || parser.seen_test('Y'),
|
||||
home_all = homeX == homeY && homeX == homeZ, // All or None
|
||||
doX = home_all || homeX, doY = home_all || homeY, doZ = home_all || homeZ;
|
||||
LINEAR_AXIS_LIST( // Other axes should be homed before Z safe-homing
|
||||
needX = _UNSAFE(X), needY = _UNSAFE(Y), needZ = false // UNUSED
|
||||
),
|
||||
LINEAR_AXIS_LIST( // Home each axis if needed or flagged
|
||||
homeX = needX || parser.seen_test('X'),
|
||||
homeY = needY || parser.seen_test('Y'),
|
||||
homeZZ = homeZ // UNUSED
|
||||
),
|
||||
// Home-all if all or none are flagged
|
||||
home_all = true LINEAR_AXIS_GANG(&& homeX == homeX, && homeX == homeY, && homeX == homeZ),
|
||||
LINEAR_AXIS_LIST(doX = home_all || homeX, doY = home_all || homeY, doZ = home_all || homeZ);
|
||||
|
||||
UNUSED(needZ);
|
||||
UNUSED(homeZZ);
|
||||
|
||||
#if ENABLED(HOME_Z_FIRST)
|
||||
|
||||
@ -336,7 +347,7 @@ void GcodeSuite::G28() {
|
||||
|
||||
const float z_homing_height = parser.seenval('R') ? parser.value_linear_units() : Z_HOMING_HEIGHT;
|
||||
|
||||
if (z_homing_height && (doX || doY || TERN0(Z_SAFE_HOMING, doZ))) {
|
||||
if (z_homing_height && (0 LINEAR_AXIS_GANG(|| doX, || doY, || TERN0(Z_SAFE_HOMING, doZ)))) {
|
||||
// Raise Z before homing any other axes and z is not already high enough (never lower z)
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Raise Z (before homing) by ", z_homing_height);
|
||||
do_z_clearance(z_homing_height);
|
||||
@ -469,7 +480,7 @@ void GcodeSuite::G28() {
|
||||
#if HAS_CURRENT_HOME(Y2)
|
||||
stepperY2.rms_current(tmc_save_current_Y2);
|
||||
#endif
|
||||
#endif
|
||||
#endif // HAS_HOMING_CURRENT
|
||||
|
||||
ui.refresh();
|
||||
|
||||
@ -490,7 +501,7 @@ void GcodeSuite::G28() {
|
||||
static constexpr AxisEnum L64XX_axis_xref[MAX_L64XX] = {
|
||||
X_AXIS, Y_AXIS, Z_AXIS,
|
||||
X_AXIS, Y_AXIS, Z_AXIS, Z_AXIS,
|
||||
E_AXIS, E_AXIS, E_AXIS, E_AXIS, E_AXIS, E_AXIS
|
||||
E_AXIS, E_AXIS, E_AXIS, E_AXIS, E_AXIS, E_AXIS, E_AXIS, E_AXIS
|
||||
};
|
||||
for (uint8_t j = 1; j <= L64XX::chain[0]; j++) {
|
||||
const uint8_t cv = L64XX::chain[j];
|
||||
|
@ -307,9 +307,11 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
|
||||
|
||||
// The difference between the known and the measured location
|
||||
// of the calibration object is the positional error
|
||||
m.pos_error.x = TERN0(HAS_X_CENTER, true_center.x - m.obj_center.x);
|
||||
m.pos_error.y = TERN0(HAS_Y_CENTER, true_center.y - m.obj_center.y);
|
||||
m.pos_error.z = true_center.z - m.obj_center.z;
|
||||
LINEAR_AXIS_CODE(
|
||||
m.pos_error.x = TERN0(HAS_X_CENTER, true_center.x - m.obj_center.x),
|
||||
m.pos_error.y = TERN0(HAS_Y_CENTER, true_center.y - m.obj_center.y),
|
||||
m.pos_error.z = true_center.z - m.obj_center.z
|
||||
);
|
||||
}
|
||||
|
||||
#if ENABLED(CALIBRATION_REPORTING)
|
||||
@ -455,7 +457,9 @@ inline void calibrate_backlash(measurements_t &m, const float uncertainty) {
|
||||
// New scope for TEMPORARY_BACKLASH_CORRECTION
|
||||
TEMPORARY_BACKLASH_CORRECTION(all_on);
|
||||
TEMPORARY_BACKLASH_SMOOTHING(0.0f);
|
||||
const xyz_float_t move = { AXIS_CAN_CALIBRATE(X) * 3, AXIS_CAN_CALIBRATE(Y) * 3, AXIS_CAN_CALIBRATE(Z) * 3 };
|
||||
const xyz_float_t move = LINEAR_AXIS_ARRAY(
|
||||
AXIS_CAN_CALIBRATE(X) * 3, AXIS_CAN_CALIBRATE(Y) * 3, AXIS_CAN_CALIBRATE(Z) * 3
|
||||
);
|
||||
current_position += move; calibration_move();
|
||||
current_position -= move; calibration_move();
|
||||
}
|
||||
|
@ -48,10 +48,12 @@ void GcodeSuite::M425() {
|
||||
|
||||
auto axis_can_calibrate = [](const uint8_t a) {
|
||||
switch (a) {
|
||||
default:
|
||||
case X_AXIS: return AXIS_CAN_CALIBRATE(X);
|
||||
case Y_AXIS: return AXIS_CAN_CALIBRATE(Y);
|
||||
case Z_AXIS: return AXIS_CAN_CALIBRATE(Z);
|
||||
default: return false;
|
||||
LINEAR_AXIS_CODE(
|
||||
case X_AXIS: return AXIS_CAN_CALIBRATE(X),
|
||||
case Y_AXIS: return AXIS_CAN_CALIBRATE(Y),
|
||||
case Z_AXIS: return AXIS_CAN_CALIBRATE(Z)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -88,7 +88,7 @@ void GcodeSuite::M201() {
|
||||
|
||||
LOOP_LOGICAL_AXES(i) {
|
||||
if (parser.seenval(axis_codes[i])) {
|
||||
const uint8_t a = (i == E_AXIS ? uint8_t(E_AXIS_N(target_extruder)) : i);
|
||||
const uint8_t a = TERN(HAS_EXTRUDERS, (i == E_AXIS ? uint8_t(E_AXIS_N(target_extruder)) : i), i);
|
||||
planner.set_max_acceleration(a, parser.value_axis_units((AxisEnum)a));
|
||||
}
|
||||
}
|
||||
@ -106,7 +106,7 @@ void GcodeSuite::M203() {
|
||||
|
||||
LOOP_LOGICAL_AXES(i)
|
||||
if (parser.seenval(axis_codes[i])) {
|
||||
const uint8_t a = (i == E_AXIS ? uint8_t(E_AXIS_N(target_extruder)) : i);
|
||||
const uint8_t a = TERN(HAS_EXTRUDERS, (i == E_AXIS ? uint8_t(E_AXIS_N(target_extruder)) : i), i);
|
||||
planner.set_max_feedrate(a, parser.value_axis_units((AxisEnum)a));
|
||||
}
|
||||
}
|
||||
@ -165,17 +165,16 @@ void GcodeSuite::M205() {
|
||||
}
|
||||
#endif
|
||||
#if HAS_CLASSIC_JERK
|
||||
if (parser.seenval('X')) planner.set_max_jerk(X_AXIS, parser.value_linear_units());
|
||||
if (parser.seenval('Y')) planner.set_max_jerk(Y_AXIS, parser.value_linear_units());
|
||||
if (parser.seenval('Z')) {
|
||||
planner.set_max_jerk(Z_AXIS, parser.value_linear_units());
|
||||
#if HAS_MESH && DISABLED(LIMITED_JERK_EDITING)
|
||||
if (planner.max_jerk.z <= 0.1f)
|
||||
SERIAL_ECHOLNPGM("WARNING! Low Z Jerk may lead to unwanted pauses.");
|
||||
#endif
|
||||
}
|
||||
#if HAS_CLASSIC_E_JERK
|
||||
if (parser.seenval('E')) planner.set_max_jerk(E_AXIS, parser.value_linear_units());
|
||||
bool seenZ = false;
|
||||
LOGICAL_AXIS_CODE(
|
||||
if (parser.seenval('E')) planner.set_max_jerk(E_AXIS, parser.value_linear_units()),
|
||||
if (parser.seenval('X')) planner.set_max_jerk(X_AXIS, parser.value_linear_units()),
|
||||
if (parser.seenval('Y')) planner.set_max_jerk(Y_AXIS, parser.value_linear_units()),
|
||||
if ((seenZ = parser.seenval('Z'))) planner.set_max_jerk(Z_AXIS, parser.value_linear_units())
|
||||
);
|
||||
#if HAS_MESH && DISABLED(LIMITED_JERK_EDITING)
|
||||
if (seenZ && planner.max_jerk.z <= 0.1f)
|
||||
SERIAL_ECHOLNPGM("WARNING! Low Z Jerk may lead to unwanted pauses.");
|
||||
#endif
|
||||
#endif
|
||||
#endif // HAS_CLASSIC_JERK
|
||||
}
|
||||
|
@ -25,10 +25,12 @@
|
||||
|
||||
void report_M92(const bool echo=true, const int8_t e=-1) {
|
||||
if (echo) SERIAL_ECHO_START(); else SERIAL_CHAR(' ');
|
||||
SERIAL_ECHOPAIR_P(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]));
|
||||
#if DISABLED(DISTINCT_E_FACTORS)
|
||||
SERIAL_ECHOPAIR_P(LIST_N(DOUBLE(LINEAR_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])
|
||||
));
|
||||
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
|
||||
SERIAL_ECHOPAIR_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS]));
|
||||
#endif
|
||||
SERIAL_EOL();
|
||||
@ -64,25 +66,28 @@ void GcodeSuite::M92() {
|
||||
if (target_extruder < 0) return;
|
||||
|
||||
// No arguments? Show M92 report.
|
||||
if (!parser.seen("XYZE" TERN_(MAGIC_NUMBERS_GCODE, "HL")))
|
||||
return report_M92(true, target_extruder);
|
||||
if (!parser.seen(
|
||||
LOGICAL_AXIS_GANG("E", "X", "Y", "Z")
|
||||
TERN_(MAGIC_NUMBERS_GCODE, "HL")
|
||||
)) return report_M92(true, target_extruder);
|
||||
|
||||
LOOP_LOGICAL_AXES(i) {
|
||||
if (parser.seenval(axis_codes[i])) {
|
||||
if (i == E_AXIS) {
|
||||
const float value = parser.value_per_axis_units((AxisEnum)(E_AXIS_N(target_extruder)));
|
||||
if (value < 20) {
|
||||
float factor = planner.settings.axis_steps_per_mm[E_AXIS_N(target_extruder)] / value; // increase e constants if M92 E14 is given for netfab.
|
||||
#if HAS_CLASSIC_JERK && HAS_CLASSIC_E_JERK
|
||||
planner.max_jerk.e *= factor;
|
||||
#endif
|
||||
planner.settings.max_feedrate_mm_s[E_AXIS_N(target_extruder)] *= factor;
|
||||
planner.max_acceleration_steps_per_s2[E_AXIS_N(target_extruder)] *= factor;
|
||||
}
|
||||
planner.settings.axis_steps_per_mm[E_AXIS_N(target_extruder)] = value;
|
||||
}
|
||||
else {
|
||||
if (TERN1(HAS_EXTRUDERS, i != E_AXIS))
|
||||
planner.settings.axis_steps_per_mm[i] = parser.value_per_axis_units((AxisEnum)i);
|
||||
else {
|
||||
#if HAS_EXTRUDERS
|
||||
const float value = parser.value_per_axis_units((AxisEnum)(E_AXIS_N(target_extruder)));
|
||||
if (value < 20) {
|
||||
float factor = planner.settings.axis_steps_per_mm[E_AXIS_N(target_extruder)] / value; // increase e constants if M92 E14 is given for netfab.
|
||||
#if HAS_CLASSIC_JERK && HAS_CLASSIC_E_JERK
|
||||
planner.max_jerk.e *= factor;
|
||||
#endif
|
||||
planner.settings.max_feedrate_mm_s[E_AXIS_N(target_extruder)] *= factor;
|
||||
planner.max_acceleration_steps_per_s2[E_AXIS_N(target_extruder)] *= factor;
|
||||
}
|
||||
planner.settings.axis_steps_per_mm[E_AXIS_N(target_extruder)] = value;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,11 +33,13 @@
|
||||
* M17: Enable stepper motors
|
||||
*/
|
||||
void GcodeSuite::M17() {
|
||||
if (parser.seen("XYZE")) {
|
||||
if (parser.seen_test('X')) ENABLE_AXIS_X();
|
||||
if (parser.seen_test('Y')) ENABLE_AXIS_Y();
|
||||
if (parser.seen_test('Z')) ENABLE_AXIS_Z();
|
||||
if (TERN0(HAS_E_STEPPER_ENABLE, parser.seen_test('E'))) enable_e_steppers();
|
||||
if (parser.seen(LOGICAL_AXIS_GANG("E", "X", "Y", "Z"))) {
|
||||
LOGICAL_AXIS_CODE(
|
||||
if (TERN0(HAS_E_STEPPER_ENABLE, parser.seen_test('E'))) enable_e_steppers(),
|
||||
if (parser.seen_test('X')) ENABLE_AXIS_X(),
|
||||
if (parser.seen_test('Y')) ENABLE_AXIS_Y(),
|
||||
if (parser.seen_test('Z')) ENABLE_AXIS_Z()
|
||||
);
|
||||
}
|
||||
else {
|
||||
LCD_MESSAGEPGM(MSG_NO_MOVE);
|
||||
@ -54,12 +56,14 @@ void GcodeSuite::M18_M84() {
|
||||
stepper_inactive_time = parser.value_millis_from_seconds();
|
||||
}
|
||||
else {
|
||||
if (parser.seen("XYZE")) {
|
||||
if (parser.seen(LOGICAL_AXIS_GANG("E", "X", "Y", "Z"))) {
|
||||
planner.synchronize();
|
||||
if (parser.seen_test('X')) DISABLE_AXIS_X();
|
||||
if (parser.seen_test('Y')) DISABLE_AXIS_Y();
|
||||
if (parser.seen_test('Z')) DISABLE_AXIS_Z();
|
||||
if (TERN0(HAS_E_STEPPER_ENABLE, parser.seen_test('E'))) disable_e_steppers();
|
||||
LOGICAL_AXIS_CODE(
|
||||
if (TERN0(HAS_E_STEPPER_ENABLE, parser.seen_test('E'))) disable_e_steppers(),
|
||||
if (parser.seen_test('X')) DISABLE_AXIS_X(),
|
||||
if (parser.seen_test('Y')) DISABLE_AXIS_Y(),
|
||||
if (parser.seen_test('Z')) DISABLE_AXIS_Z()
|
||||
);
|
||||
}
|
||||
else
|
||||
planner.finish_and_disable();
|
||||
|
@ -68,7 +68,7 @@ void GcodeSuite::G61(void) {
|
||||
SYNC_E(stored_position[slot].e);
|
||||
}
|
||||
else {
|
||||
if (parser.seen("XYZ")) {
|
||||
if (parser.seen(LINEAR_AXIS_GANG("X", "Y", "Z"))) {
|
||||
DEBUG_ECHOPAIR(STR_RESTORING_POS " S", slot);
|
||||
LOOP_LINEAR_AXES(i) {
|
||||
destination[i] = parser.seen(AXIS_CHAR(i))
|
||||
@ -81,10 +81,12 @@ void GcodeSuite::G61(void) {
|
||||
// Move to the saved position
|
||||
prepare_line_to_destination();
|
||||
}
|
||||
if (parser.seen_test('E')) {
|
||||
DEBUG_ECHOLNPAIR(STR_RESTORING_POS " S", slot, " E", current_position.e, "=>", stored_position[slot].e);
|
||||
SYNC_E(stored_position[slot].e);
|
||||
}
|
||||
#if HAS_EXTRUDERS
|
||||
if (parser.seen_test('E')) {
|
||||
DEBUG_ECHOLNPAIR(STR_RESTORING_POS " S", slot, " E", current_position.e, "=>", stored_position[slot].e);
|
||||
SYNC_E(stored_position[slot].e);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
feedrate_mm_s = saved_feedrate;
|
||||
|
@ -49,13 +49,21 @@ void GcodeSuite::M122() {
|
||||
tmc_set_report_interval(interval);
|
||||
#endif
|
||||
|
||||
if (parser.seen_test('V'))
|
||||
tmc_get_registers(print_axis.x, print_axis.y, print_axis.z, print_axis.e);
|
||||
else
|
||||
tmc_report_all(print_axis.x, print_axis.y, print_axis.z, print_axis.e);
|
||||
if (parser.seen_test('V')) {
|
||||
tmc_get_registers(
|
||||
LOGICAL_AXIS_LIST(print_axis.e, print_axis.x, print_axis.y, print_axis.z)
|
||||
);
|
||||
}
|
||||
else {
|
||||
tmc_report_all(
|
||||
LOGICAL_AXIS_LIST(print_axis.e, print_axis.x, print_axis.y, print_axis.z)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
test_tmc_connection(print_axis.x, print_axis.y, print_axis.z, print_axis.e);
|
||||
test_tmc_connection(
|
||||
LOGICAL_AXIS_LIST(print_axis.e, print_axis.x, print_axis.y, print_axis.z)
|
||||
);
|
||||
}
|
||||
|
||||
#endif // HAS_TRINAMIC_CONFIG
|
||||
|
@ -74,11 +74,11 @@ millis_t GcodeSuite::previous_move_ms = 0,
|
||||
|
||||
// Relative motion mode for each logical axis
|
||||
static constexpr xyze_bool_t ar_init = AXIS_RELATIVE_MODES;
|
||||
uint8_t GcodeSuite::axis_relative = (
|
||||
(ar_init.x ? _BV(REL_X) : 0)
|
||||
| (ar_init.y ? _BV(REL_Y) : 0)
|
||||
| (ar_init.z ? _BV(REL_Z) : 0)
|
||||
| (ar_init.e ? _BV(REL_E) : 0)
|
||||
uint8_t GcodeSuite::axis_relative = 0 LOGICAL_AXIS_GANG(
|
||||
| (ar_init.e << REL_E),
|
||||
| (ar_init.x << REL_X),
|
||||
| (ar_init.y << REL_Y),
|
||||
| (ar_init.z << REL_Z)
|
||||
);
|
||||
|
||||
#if EITHER(HAS_AUTO_REPORTING, HOST_KEEPALIVE_FEATURE)
|
||||
@ -161,13 +161,15 @@ void GcodeSuite::get_destination_from_command() {
|
||||
destination[i] = current_position[i];
|
||||
}
|
||||
|
||||
// Get new E position, whether absolute or relative
|
||||
if ( (seen.e = parser.seenval('E')) ) {
|
||||
const float v = parser.value_axis_units(E_AXIS);
|
||||
destination.e = axis_is_relative(E_AXIS) ? current_position.e + v : v;
|
||||
}
|
||||
else
|
||||
destination.e = current_position.e;
|
||||
#if HAS_EXTRUDERS
|
||||
// Get new E position, whether absolute or relative
|
||||
if ( (seen.e = parser.seenval('E')) ) {
|
||||
const float v = parser.value_axis_units(E_AXIS);
|
||||
destination.e = axis_is_relative(E_AXIS) ? current_position.e + v : v;
|
||||
}
|
||||
else
|
||||
destination.e = current_position.e;
|
||||
#endif
|
||||
|
||||
#if ENABLED(POWER_LOSS_RECOVERY) && !PIN_EXISTS(POWER_LOSS)
|
||||
// Only update power loss recovery on moves with E
|
||||
|
@ -314,7 +314,12 @@
|
||||
#define HAS_FAST_MOVES 1
|
||||
#endif
|
||||
|
||||
enum AxisRelative : uint8_t { REL_X, REL_Y, REL_Z, REL_E, E_MODE_ABS, E_MODE_REL };
|
||||
enum AxisRelative : uint8_t {
|
||||
LOGICAL_AXIS_LIST(REL_E, REL_X, REL_Y, REL_Z)
|
||||
#if HAS_EXTRUDERS
|
||||
, E_MODE_ABS, E_MODE_REL
|
||||
#endif
|
||||
};
|
||||
|
||||
extern const char G28_STR[];
|
||||
|
||||
@ -324,23 +329,27 @@ public:
|
||||
static uint8_t axis_relative;
|
||||
|
||||
static inline bool axis_is_relative(const AxisEnum a) {
|
||||
if (a == E_AXIS) {
|
||||
if (TEST(axis_relative, E_MODE_REL)) return true;
|
||||
if (TEST(axis_relative, E_MODE_ABS)) return false;
|
||||
}
|
||||
#if HAS_EXTRUDERS
|
||||
if (a == E_AXIS) {
|
||||
if (TEST(axis_relative, E_MODE_REL)) return true;
|
||||
if (TEST(axis_relative, E_MODE_ABS)) return false;
|
||||
}
|
||||
#endif
|
||||
return TEST(axis_relative, a);
|
||||
}
|
||||
static inline void set_relative_mode(const bool rel) {
|
||||
axis_relative = rel ? _BV(REL_X) | _BV(REL_Y) | _BV(REL_Z) | _BV(REL_E) : 0;
|
||||
}
|
||||
static inline void set_e_relative() {
|
||||
CBI(axis_relative, E_MODE_ABS);
|
||||
SBI(axis_relative, E_MODE_REL);
|
||||
}
|
||||
static inline void set_e_absolute() {
|
||||
CBI(axis_relative, E_MODE_REL);
|
||||
SBI(axis_relative, E_MODE_ABS);
|
||||
axis_relative = rel ? (0 LOGICAL_AXIS_GANG(| _BV(REL_E), | _BV(REL_X), | _BV(REL_Y), | _BV(REL_Z))) : 0;
|
||||
}
|
||||
#if HAS_EXTRUDERS
|
||||
static inline void set_e_relative() {
|
||||
CBI(axis_relative, E_MODE_ABS);
|
||||
SBI(axis_relative, E_MODE_REL);
|
||||
}
|
||||
static inline void set_e_absolute() {
|
||||
CBI(axis_relative, E_MODE_REL);
|
||||
SBI(axis_relative, E_MODE_ABS);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLED(CNC_WORKSPACE_PLANES)
|
||||
/**
|
||||
|
@ -48,7 +48,10 @@
|
||||
*/
|
||||
void GcodeSuite::G92() {
|
||||
|
||||
bool sync_E = false, sync_XYZE = false;
|
||||
#if HAS_EXTRUDERS
|
||||
bool sync_E = false;
|
||||
#endif
|
||||
bool sync_XYZE = false;
|
||||
|
||||
#if USE_GCODE_SUBCODES
|
||||
const uint8_t subcode_G92 = parser.subcode;
|
||||
@ -72,7 +75,11 @@ void GcodeSuite::G92() {
|
||||
case 9: // G92.9 - Set Current Position directly (like Marlin 1.0)
|
||||
LOOP_LOGICAL_AXES(i) {
|
||||
if (parser.seenval(axis_codes[i])) {
|
||||
if (i == E_AXIS) sync_E = true; else sync_XYZE = true;
|
||||
if (TERN1(HAS_EXTRUDERS, i != E_AXIS))
|
||||
sync_XYZE = true;
|
||||
else {
|
||||
TERN_(HAS_EXTRUDERS, sync_E = true);
|
||||
}
|
||||
current_position[i] = parser.value_axis_units((AxisEnum)i);
|
||||
}
|
||||
}
|
||||
@ -83,20 +90,26 @@ void GcodeSuite::G92() {
|
||||
LOOP_LOGICAL_AXES(i) {
|
||||
if (parser.seenval(axis_codes[i])) {
|
||||
const float l = parser.value_axis_units((AxisEnum)i), // Given axis coordinate value, converted to millimeters
|
||||
v = i == E_AXIS ? l : LOGICAL_TO_NATIVE(l, i), // Axis position in NATIVE space (applying the existing offset)
|
||||
v = TERN0(HAS_EXTRUDERS, i == E_AXIS) ? l : LOGICAL_TO_NATIVE(l, i), // Axis position in NATIVE space (applying the existing offset)
|
||||
d = v - current_position[i]; // How much is the current axis position altered by?
|
||||
if (!NEAR_ZERO(d)) {
|
||||
#if HAS_POSITION_SHIFT && !IS_SCARA // When using workspaces...
|
||||
if (i == E_AXIS) {
|
||||
sync_E = true;
|
||||
current_position.e = v; // ...E is still set directly
|
||||
}
|
||||
else {
|
||||
position_shift[i] += d; // ...but other axes offset the workspace.
|
||||
if (TERN1(HAS_EXTRUDERS, i != E_AXIS)) {
|
||||
position_shift[i] += d; // ...most axes offset the workspace...
|
||||
update_workspace_offset((AxisEnum)i);
|
||||
}
|
||||
else {
|
||||
#if HAS_EXTRUDERS
|
||||
sync_E = true;
|
||||
current_position.e = v; // ...but E is set directly
|
||||
#endif
|
||||
}
|
||||
#else // Without workspaces...
|
||||
if (i == E_AXIS) sync_E = true; else sync_XYZE = true;
|
||||
if (TERN1(HAS_EXTRUDERS, i != E_AXIS))
|
||||
sync_XYZE = true;
|
||||
else {
|
||||
TERN_(HAS_EXTRUDERS, sync_E = true);
|
||||
}
|
||||
current_position[i] = v; // ...set Current Position directly (like Marlin 1.0)
|
||||
#endif
|
||||
}
|
||||
@ -111,8 +124,10 @@ void GcodeSuite::G92() {
|
||||
coordinate_system[active_coordinate_system] = position_shift;
|
||||
#endif
|
||||
|
||||
if (sync_XYZE) sync_plan_position();
|
||||
else if (sync_E) sync_plan_position_e();
|
||||
if (sync_XYZE) sync_plan_position();
|
||||
#if HAS_EXTRUDERS
|
||||
else if (sync_E) sync_plan_position_e();
|
||||
#endif
|
||||
|
||||
IF_DISABLED(DIRECT_STEPPING, report_current_position());
|
||||
}
|
||||
|
@ -170,7 +170,7 @@
|
||||
|
||||
SERIAL_ECHOPGM("FromStp:");
|
||||
get_cartesian_from_steppers(); // writes 'cartes' (with forward kinematics)
|
||||
xyze_pos_t from_steppers = { cartes.x, cartes.y, cartes.z, planner.get_axis_position_mm(E_AXIS) };
|
||||
xyze_pos_t from_steppers = LOGICAL_AXIS_ARRAY(planner.get_axis_position_mm(E_AXIS), cartes.x, cartes.y, cartes.z);
|
||||
report_all_axis_pos(from_steppers);
|
||||
|
||||
const xyze_float_t diff = from_steppers - leveled;
|
||||
|
@ -49,9 +49,11 @@ void GcodeSuite::G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move/*=false*/)) {
|
||||
if (IsRunning()
|
||||
#if ENABLED(NO_MOTION_BEFORE_HOMING)
|
||||
&& !homing_needed_error(
|
||||
(parser.seen_test('X') ? _BV(X_AXIS) : 0)
|
||||
| (parser.seen_test('Y') ? _BV(Y_AXIS) : 0)
|
||||
| (parser.seen_test('Z') ? _BV(Z_AXIS) : 0) )
|
||||
LINEAR_AXIS_GANG(
|
||||
(parser.seen_test('X') ? _BV(X_AXIS) : 0),
|
||||
| (parser.seen_test('Y') ? _BV(Y_AXIS) : 0),
|
||||
| (parser.seen_test('Z') ? _BV(Z_AXIS) : 0))
|
||||
)
|
||||
#endif
|
||||
) {
|
||||
TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_RUNNING));
|
||||
@ -83,7 +85,7 @@ void GcodeSuite::G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move/*=false*/)) {
|
||||
|
||||
if (MIN_AUTORETRACT <= MAX_AUTORETRACT) {
|
||||
// When M209 Autoretract is enabled, convert E-only moves to firmware retract/recover moves
|
||||
if (fwretract.autoretract_enabled && parser.seen('E') && !parser.seen("XYZ")) {
|
||||
if (fwretract.autoretract_enabled && parser.seen_test('E') && !parser.seen(LINEAR_AXIS_GANG("X", "Y", "Z"))) {
|
||||
const float echange = destination.e - current_position.e;
|
||||
// Is this a retract or recover move?
|
||||
if (WITHIN(ABS(echange), MIN_AUTORETRACT, MAX_AUTORETRACT) && fwretract.retracted[active_extruder] == (echange > 0.0)) {
|
||||
|
@ -109,23 +109,32 @@ void plan_arc(
|
||||
#endif
|
||||
}
|
||||
|
||||
float linear_travel = cart[l_axis] - start_L,
|
||||
extruder_travel = cart.e - current_position.e;
|
||||
float linear_travel = cart[l_axis] - start_L;
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
float extruder_travel = cart.e - current_position.e;
|
||||
#endif
|
||||
|
||||
// If circling around...
|
||||
if (ENABLED(ARC_P_CIRCLES) && circles) {
|
||||
const float total_angular = angular_travel + circles * RADIANS(360), // Total rotation with all circles and remainder
|
||||
part_per_circle = RADIANS(360) / total_angular, // Each circle's part of the total
|
||||
l_per_circle = linear_travel * part_per_circle, // L movement per circle
|
||||
e_per_circle = extruder_travel * part_per_circle; // E movement per circle
|
||||
l_per_circle = linear_travel * part_per_circle; // L movement per circle
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
const float e_per_circle = extruder_travel * part_per_circle; // E movement per circle
|
||||
#endif
|
||||
|
||||
xyze_pos_t temp_position = current_position; // for plan_arc to compare to current_position
|
||||
for (uint16_t n = circles; n--;) {
|
||||
temp_position.e += e_per_circle; // Destination E axis
|
||||
TERN_(HAS_EXTRUDERS, temp_position.e += e_per_circle); // Destination E axis
|
||||
temp_position[l_axis] += l_per_circle; // Destination L axis
|
||||
plan_arc(temp_position, offset, clockwise, 0); // Plan a single whole circle
|
||||
}
|
||||
linear_travel = cart[l_axis] - current_position[l_axis];
|
||||
extruder_travel = cart.e - current_position.e;
|
||||
#if HAS_EXTRUDERS
|
||||
extruder_travel = cart.e - current_position.e;
|
||||
#endif
|
||||
}
|
||||
|
||||
const float flat_mm = radius * angular_travel,
|
||||
@ -179,16 +188,19 @@ void plan_arc(
|
||||
xyze_pos_t raw;
|
||||
const float theta_per_segment = angular_travel / segments,
|
||||
linear_per_segment = linear_travel / segments,
|
||||
extruder_per_segment = extruder_travel / segments,
|
||||
sq_theta_per_segment = sq(theta_per_segment),
|
||||
sin_T = theta_per_segment - sq_theta_per_segment * theta_per_segment / 6,
|
||||
cos_T = 1 - 0.5f * sq_theta_per_segment; // Small angle approximation
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
const float extruder_per_segment = extruder_travel / segments;
|
||||
#endif
|
||||
|
||||
// Initialize the linear axis
|
||||
raw[l_axis] = current_position[l_axis];
|
||||
|
||||
// Initialize the extruder axis
|
||||
raw.e = current_position.e;
|
||||
TERN_(HAS_EXTRUDERS, raw.e = current_position.e);
|
||||
|
||||
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||
const float inv_duration = scaled_fr_mm_s / seg_length;
|
||||
@ -240,7 +252,8 @@ void plan_arc(
|
||||
#else
|
||||
raw[l_axis] += linear_per_segment;
|
||||
#endif
|
||||
raw.e += extruder_per_segment;
|
||||
|
||||
TERN_(HAS_EXTRUDERS, raw.e += extruder_per_segment);
|
||||
|
||||
apply_motion_limits(raw);
|
||||
|
||||
|
@ -87,7 +87,7 @@ void GcodeSuite::M290() {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!parser.seen("XYZ") || parser.seen('R')) {
|
||||
if (!parser.seen(LINEAR_AXIS_GANG("X", "Y", "Z")) || parser.seen('R')) {
|
||||
SERIAL_ECHO_START();
|
||||
|
||||
#if ENABLED(BABYSTEP_ZPROBE_OFFSET)
|
||||
|
@ -248,7 +248,8 @@ void GCodeParser::parse(char *p) {
|
||||
case 'R': if (!WITHIN(motion_mode_codenum, 2, 3)) return;
|
||||
#endif
|
||||
|
||||
case 'X' ... 'Z': case 'E' ... 'F':
|
||||
LOGICAL_AXIS_GANG(case 'E':, case 'X':, case 'Y':, case 'Z':)
|
||||
case 'F':
|
||||
if (motion_mode_codenum < 0) return;
|
||||
command_letter = 'G';
|
||||
codenum = motion_mode_codenum;
|
||||
|
@ -226,7 +226,7 @@ public:
|
||||
|
||||
// Seen any axis parameter
|
||||
static inline bool seen_axis() {
|
||||
return seen("XYZE");
|
||||
return seen(LOGICAL_AXIS_GANG("E", "X", "Y", "Z"));
|
||||
}
|
||||
|
||||
#if ENABLED(GCODE_QUOTED_STRINGS)
|
||||
|
@ -537,12 +537,12 @@
|
||||
* E_STEPPERS - Number of actual E stepper motors
|
||||
* E_MANUAL - Number of E steppers for LCD move options
|
||||
*/
|
||||
|
||||
#if EXTRUDERS
|
||||
#define HAS_EXTRUDERS 1
|
||||
#if EXTRUDERS > 1
|
||||
#define HAS_MULTI_EXTRUDER 1
|
||||
#endif
|
||||
#define E_AXIS_N(E) AxisEnum(E_AXIS + E_INDEX_N(E))
|
||||
#else
|
||||
#undef EXTRUDERS
|
||||
#define EXTRUDERS 0
|
||||
@ -551,6 +551,7 @@
|
||||
#undef SWITCHING_NOZZLE
|
||||
#undef MIXING_EXTRUDER
|
||||
#undef HOTEND_IDLE_TIMEOUT
|
||||
#undef DISABLE_E
|
||||
#endif
|
||||
|
||||
#if ENABLED(SWITCHING_EXTRUDER) // One stepper for every two EXTRUDERS
|
||||
@ -604,6 +605,50 @@
|
||||
#define E_MANUAL EXTRUDERS
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Number of Linear Axes (e.g., XYZ)
|
||||
* All the logical axes except for the tool (E) axis
|
||||
*/
|
||||
#ifndef LINEAR_AXES
|
||||
#define LINEAR_AXES XYZ
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Number of Logical Axes (e.g., XYZE)
|
||||
* All the logical axes that can be commanded directly by G-code.
|
||||
* Delta maps stepper-specific values to ABC steppers.
|
||||
*/
|
||||
#if HAS_EXTRUDERS
|
||||
#define LOGICAL_AXES INCREMENT(LINEAR_AXES)
|
||||
#else
|
||||
#define LOGICAL_AXES LINEAR_AXES
|
||||
#endif
|
||||
|
||||
/**
|
||||
* DISTINCT_E_FACTORS is set to give extruders (some) individual settings.
|
||||
*
|
||||
* DISTINCT_AXES is the number of distinct addressable axes (not steppers).
|
||||
* Includes all linear axes plus all distinguished extruders.
|
||||
* The default behavior is to treat all extruders as a single E axis
|
||||
* with shared motion and temperature settings.
|
||||
*
|
||||
* DISTINCT_E is the number of distinguished extruders. By default this
|
||||
* well be 1 which indicates all extruders share the same settings.
|
||||
*
|
||||
* E_INDEX_N(E) should be used to get the E index of any item that might be
|
||||
* distinguished.
|
||||
*/
|
||||
#if ENABLED(DISTINCT_E_FACTORS) && E_STEPPERS > 1
|
||||
#define DISTINCT_AXES (LINEAR_AXES + E_STEPPERS)
|
||||
#define DISTINCT_E E_STEPPERS
|
||||
#define E_INDEX_N(E) (E)
|
||||
#else
|
||||
#undef DISTINCT_E_FACTORS
|
||||
#define DISTINCT_AXES LOGICAL_AXES
|
||||
#define DISTINCT_E 1
|
||||
#define E_INDEX_N(E) 0
|
||||
#endif
|
||||
|
||||
#if HOTENDS
|
||||
#define HAS_HOTEND 1
|
||||
#ifndef HOTEND_OVERSHOOT
|
||||
@ -624,10 +669,6 @@
|
||||
#define ARRAY_BY_HOTENDS(V...) ARRAY_N(HOTENDS, V)
|
||||
#define ARRAY_BY_HOTENDS1(v1) ARRAY_N_1(HOTENDS, v1)
|
||||
|
||||
#if ENABLED(SWITCHING_EXTRUDER) && (DISABLED(SWITCHING_NOZZLE) || SWITCHING_EXTRUDER_SERVO_NR != SWITCHING_NOZZLE_SERVO_NR)
|
||||
#define DO_SWITCH_EXTRUDER 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Default hotend offsets, if not defined
|
||||
*/
|
||||
@ -653,40 +694,11 @@
|
||||
#undef SINGLENOZZLE_STANDBY_FAN
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Number of Linear Axes (e.g., XYZ)
|
||||
* All the logical axes except for the tool (E) axis
|
||||
*/
|
||||
#ifndef LINEAR_AXES
|
||||
#define LINEAR_AXES XYZ
|
||||
// Switching extruder has its own servo?
|
||||
#if ENABLED(SWITCHING_EXTRUDER) && (DISABLED(SWITCHING_NOZZLE) || SWITCHING_EXTRUDER_SERVO_NR != SWITCHING_NOZZLE_SERVO_NR)
|
||||
#define DO_SWITCH_EXTRUDER 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Number of Logical Axes (e.g., XYZE)
|
||||
* All the logical axes that can be commanded directly by G-code.
|
||||
* Delta maps stepper-specific values to ABC steppers.
|
||||
*/
|
||||
#if HAS_EXTRUDERS
|
||||
#define LOGICAL_AXES INCREMENT(LINEAR_AXES)
|
||||
#else
|
||||
#define LOGICAL_AXES LINEAR_AXES
|
||||
#endif
|
||||
|
||||
/**
|
||||
* DISTINCT_E_FACTORS affects whether Extruders use different settings
|
||||
*/
|
||||
#if ENABLED(DISTINCT_E_FACTORS) && E_STEPPERS > 1
|
||||
#define DISTINCT_E E_STEPPERS
|
||||
#define DISTINCT_AXES (LINEAR_AXES + E_STEPPERS)
|
||||
#define E_INDEX_N(E) (E)
|
||||
#else
|
||||
#undef DISTINCT_E_FACTORS
|
||||
#define DISTINCT_E 1
|
||||
#define DISTINCT_AXES LOGICAL_AXES
|
||||
#define E_INDEX_N(E) 0
|
||||
#endif
|
||||
#define E_AXIS_N(E) AxisEnum(E_AXIS + E_INDEX_N(E))
|
||||
|
||||
/**
|
||||
* The BLTouch Probe emulates a servo probe
|
||||
* and uses "special" angles for its state.
|
||||
@ -726,6 +738,9 @@
|
||||
#define HAS_BED_PROBE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Fill in undefined Filament Sensor options
|
||||
*/
|
||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
|
||||
#if NUM_RUNOUT_SENSORS >= 1
|
||||
#ifndef FIL_RUNOUT1_STATE
|
||||
@ -834,6 +849,9 @@
|
||||
#define Z_HOME_TO_MIN 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Conditionals based on the type of Bed Probe
|
||||
*/
|
||||
#if HAS_BED_PROBE
|
||||
#if DISABLED(NOZZLE_AS_PROBE)
|
||||
#define HAS_PROBE_XY_OFFSET 1
|
||||
@ -868,7 +886,7 @@
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set granular options based on the specific type of leveling
|
||||
* Conditionals based on the type of Bed Leveling
|
||||
*/
|
||||
#if ENABLED(AUTO_BED_LEVELING_UBL)
|
||||
#undef LCD_BED_LEVELING
|
||||
|
@ -103,6 +103,9 @@
|
||||
#undef THERMAL_PROTECTION_PERIOD
|
||||
#undef WATCH_TEMP_PERIOD
|
||||
#undef SHOW_TEMP_ADC_VALUES
|
||||
#undef LCD_SHOW_E_TOTAL
|
||||
#undef MANUAL_E_MOVES_RELATIVE
|
||||
#undef STEALTHCHOP_E
|
||||
#endif
|
||||
|
||||
#if TEMP_SENSOR_BED == 0
|
||||
@ -482,6 +485,23 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Remove unused STEALTHCHOP flags
|
||||
#if LINEAR_AXES < 6
|
||||
#undef STEALTHCHOP_K
|
||||
#if LINEAR_AXES < 5
|
||||
#undef STEALTHCHOP_J
|
||||
#if LINEAR_AXES < 4
|
||||
#undef STEALTHCHOP_I
|
||||
#if LINEAR_AXES < 3
|
||||
#undef STEALTHCHOP_Z
|
||||
#if LINEAR_AXES < 2
|
||||
#undef STEALTHCHOP_Y
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// SD Card connection methods
|
||||
// Defined here so pins and sanity checks can use them
|
||||
|
@ -1563,133 +1563,137 @@
|
||||
#endif
|
||||
|
||||
// Extruder steppers and solenoids
|
||||
#if PIN_EXISTS(E0_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E0))
|
||||
#define HAS_E0_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E0_DIR)
|
||||
#define HAS_E0_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E0_STEP)
|
||||
#define HAS_E0_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E0_MS1)
|
||||
#define HAS_E0_MS_PINS 1
|
||||
#endif
|
||||
#if PIN_EXISTS(SOL0)
|
||||
#define HAS_SOLENOID_0 1
|
||||
#endif
|
||||
#if HAS_EXTRUDERS
|
||||
|
||||
#if PIN_EXISTS(E1_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E1))
|
||||
#define HAS_E1_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E1_DIR)
|
||||
#define HAS_E1_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E1_STEP)
|
||||
#define HAS_E1_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E1_MS1)
|
||||
#define HAS_E1_MS_PINS 1
|
||||
#endif
|
||||
#if PIN_EXISTS(SOL1)
|
||||
#define HAS_SOLENOID_1 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E0_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E0))
|
||||
#define HAS_E0_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E0_DIR)
|
||||
#define HAS_E0_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E0_STEP)
|
||||
#define HAS_E0_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E0_MS1)
|
||||
#define HAS_E0_MS_PINS 1
|
||||
#endif
|
||||
#if PIN_EXISTS(SOL0)
|
||||
#define HAS_SOLENOID_0 1
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(E2_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E2))
|
||||
#define HAS_E2_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E2_DIR)
|
||||
#define HAS_E2_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E2_STEP)
|
||||
#define HAS_E2_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E2_MS1)
|
||||
#define HAS_E2_MS_PINS 1
|
||||
#endif
|
||||
#if PIN_EXISTS(SOL2)
|
||||
#define HAS_SOLENOID_2 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E1_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E1))
|
||||
#define HAS_E1_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E1_DIR)
|
||||
#define HAS_E1_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E1_STEP)
|
||||
#define HAS_E1_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E1_MS1)
|
||||
#define HAS_E1_MS_PINS 1
|
||||
#endif
|
||||
#if PIN_EXISTS(SOL1)
|
||||
#define HAS_SOLENOID_1 1
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(E3_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E3))
|
||||
#define HAS_E3_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E3_DIR)
|
||||
#define HAS_E3_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E3_STEP)
|
||||
#define HAS_E3_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E3_MS1)
|
||||
#define HAS_E3_MS_PINS 1
|
||||
#endif
|
||||
#if PIN_EXISTS(SOL3)
|
||||
#define HAS_SOLENOID_3 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E2_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E2))
|
||||
#define HAS_E2_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E2_DIR)
|
||||
#define HAS_E2_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E2_STEP)
|
||||
#define HAS_E2_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E2_MS1)
|
||||
#define HAS_E2_MS_PINS 1
|
||||
#endif
|
||||
#if PIN_EXISTS(SOL2)
|
||||
#define HAS_SOLENOID_2 1
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(E4_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E4))
|
||||
#define HAS_E4_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E4_DIR)
|
||||
#define HAS_E4_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E4_STEP)
|
||||
#define HAS_E4_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E4_MS1)
|
||||
#define HAS_E4_MS_PINS 1
|
||||
#endif
|
||||
#if PIN_EXISTS(SOL4)
|
||||
#define HAS_SOLENOID_4 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E3_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E3))
|
||||
#define HAS_E3_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E3_DIR)
|
||||
#define HAS_E3_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E3_STEP)
|
||||
#define HAS_E3_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E3_MS1)
|
||||
#define HAS_E3_MS_PINS 1
|
||||
#endif
|
||||
#if PIN_EXISTS(SOL3)
|
||||
#define HAS_SOLENOID_3 1
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(E5_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E5))
|
||||
#define HAS_E5_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E5_DIR)
|
||||
#define HAS_E5_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E5_STEP)
|
||||
#define HAS_E5_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E5_MS1)
|
||||
#define HAS_E5_MS_PINS 1
|
||||
#endif
|
||||
#if PIN_EXISTS(SOL5)
|
||||
#define HAS_SOLENOID_5 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E4_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E4))
|
||||
#define HAS_E4_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E4_DIR)
|
||||
#define HAS_E4_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E4_STEP)
|
||||
#define HAS_E4_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E4_MS1)
|
||||
#define HAS_E4_MS_PINS 1
|
||||
#endif
|
||||
#if PIN_EXISTS(SOL4)
|
||||
#define HAS_SOLENOID_4 1
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(E6_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E6))
|
||||
#define HAS_E6_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E6_DIR)
|
||||
#define HAS_E6_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E6_STEP)
|
||||
#define HAS_E6_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E6_MS1)
|
||||
#define HAS_E6_MS_PINS 1
|
||||
#endif
|
||||
#if PIN_EXISTS(SOL6)
|
||||
#define HAS_SOLENOID_6 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E5_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E5))
|
||||
#define HAS_E5_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E5_DIR)
|
||||
#define HAS_E5_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E5_STEP)
|
||||
#define HAS_E5_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E5_MS1)
|
||||
#define HAS_E5_MS_PINS 1
|
||||
#endif
|
||||
#if PIN_EXISTS(SOL5)
|
||||
#define HAS_SOLENOID_5 1
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(E7_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E7))
|
||||
#define HAS_E7_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E7_DIR)
|
||||
#define HAS_E7_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E7_STEP)
|
||||
#define HAS_E7_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E7_MS1)
|
||||
#define HAS_E7_MS_PINS 1
|
||||
#endif
|
||||
#if PIN_EXISTS(SOL7)
|
||||
#define HAS_SOLENOID_7 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E6_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E6))
|
||||
#define HAS_E6_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E6_DIR)
|
||||
#define HAS_E6_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E6_STEP)
|
||||
#define HAS_E6_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E6_MS1)
|
||||
#define HAS_E6_MS_PINS 1
|
||||
#endif
|
||||
#if PIN_EXISTS(SOL6)
|
||||
#define HAS_SOLENOID_6 1
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(E7_ENABLE) || (ENABLED(SOFTWARE_DRIVER_ENABLE) && AXIS_IS_TMC(E7))
|
||||
#define HAS_E7_ENABLE 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E7_DIR)
|
||||
#define HAS_E7_DIR 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E7_STEP)
|
||||
#define HAS_E7_STEP 1
|
||||
#endif
|
||||
#if PIN_EXISTS(E7_MS1)
|
||||
#define HAS_E7_MS_PINS 1
|
||||
#endif
|
||||
#if PIN_EXISTS(SOL7)
|
||||
#define HAS_SOLENOID_7 1
|
||||
#endif
|
||||
|
||||
#endif // HAS_EXTRUDERS
|
||||
|
||||
//
|
||||
// Trinamic Stepper Drivers
|
||||
@ -2348,7 +2352,10 @@
|
||||
#if PIN_EXISTS(DIGIPOTSS)
|
||||
#define HAS_MOTOR_CURRENT_SPI 1
|
||||
#endif
|
||||
#if ANY_PIN(MOTOR_CURRENT_PWM_X, MOTOR_CURRENT_PWM_Y, MOTOR_CURRENT_PWM_XY, MOTOR_CURRENT_PWM_Z, MOTOR_CURRENT_PWM_E)
|
||||
#if HAS_EXTRUDERS && PIN_EXISTS(MOTOR_CURRENT_PWM_E)
|
||||
#define HAS_MOTOR_CURRENT_PWM_E 1
|
||||
#endif
|
||||
#if HAS_MOTOR_CURRENT_PWM_E || ANY_PIN(MOTOR_CURRENT_PWM_X, MOTOR_CURRENT_PWM_Y, MOTOR_CURRENT_PWM_XY, MOTOR_CURRENT_PWM_Z)
|
||||
#define HAS_MOTOR_CURRENT_PWM 1
|
||||
#endif
|
||||
|
||||
|
@ -1600,11 +1600,12 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
|
||||
* Homing
|
||||
*/
|
||||
constexpr float hbm[] = HOMING_BUMP_MM;
|
||||
static_assert(COUNT(hbm) == XYZ, "HOMING_BUMP_MM requires X, Y, and Z elements.");
|
||||
static_assert(hbm[X_AXIS] >= 0, "HOMING_BUMP_MM.X must be greater than or equal to 0.");
|
||||
static_assert(hbm[Y_AXIS] >= 0, "HOMING_BUMP_MM.Y must be greater than or equal to 0.");
|
||||
static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal to 0.");
|
||||
|
||||
static_assert(COUNT(hbm) == LINEAR_AXES, "HOMING_BUMP_MM requires one element per linear axis.");
|
||||
LINEAR_AXIS_CODE(
|
||||
static_assert(hbm[X_AXIS] >= 0, "HOMING_BUMP_MM.X must be greater than or equal to 0."),
|
||||
static_assert(hbm[Y_AXIS] >= 0, "HOMING_BUMP_MM.Y must be greater than or equal to 0."),
|
||||
static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal to 0.")
|
||||
);
|
||||
#if ENABLED(CODEPENDENT_XY_HOMING)
|
||||
#if ENABLED(QUICK_HOME)
|
||||
#error "QUICK_HOME is incompatible with CODEPENDENT_XY_HOMING."
|
||||
@ -1983,12 +1984,16 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
|
||||
#error "HEATER_0_PIN not defined for this board."
|
||||
#elif !ANY_PIN(TEMP_0, MAX6675_SS)
|
||||
#error "TEMP_0_PIN or MAX6675_SS not defined for this board."
|
||||
#elif ((defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && !PINS_EXIST(E0_STEP, E0_DIR))
|
||||
#error "E0_STEP_PIN or E0_DIR_PIN not defined for this board."
|
||||
#elif ( !(defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && (!PINS_EXIST(E0_STEP, E0_DIR) || !HAS_E0_ENABLE))
|
||||
#error "E0_STEP_PIN, E0_DIR_PIN, or E0_ENABLE_PIN not defined for this board."
|
||||
#elif EXTRUDERS && TEMP_SENSOR_0 == 0
|
||||
#error "TEMP_SENSOR_0 is required if there are any extruders."
|
||||
#endif
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
#if ((defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && !PINS_EXIST(E0_STEP, E0_DIR))
|
||||
#error "E0_STEP_PIN or E0_DIR_PIN not defined for this board."
|
||||
#elif ( !(defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)) && (!PINS_EXIST(E0_STEP, E0_DIR) || !HAS_E0_ENABLE))
|
||||
#error "E0_STEP_PIN, E0_DIR_PIN, or E0_ENABLE_PIN not defined for this board."
|
||||
#elif EXTRUDERS && TEMP_SENSOR_0 == 0
|
||||
#error "TEMP_SENSOR_0 is required if there are any extruders."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -856,8 +856,10 @@ void MarlinUI::draw_status_screen() {
|
||||
#else
|
||||
|
||||
if (show_e_total) {
|
||||
_draw_axis_value(E_AXIS, xstring, true);
|
||||
lcd_put_u8str_P(PSTR(" "));
|
||||
#if ENABLED(LCD_SHOW_E_TOTAL)
|
||||
_draw_axis_value(E_AXIS, xstring, true);
|
||||
lcd_put_u8str_P(PSTR(" "));
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
_draw_axis_value(X_AXIS, xstring, blink);
|
||||
|
@ -666,10 +666,10 @@ const struct DGUS_VP_Variable ListOfVP[] PROGMEM = {
|
||||
VPHELPER(VP_Z_MAX_SPEED, &planner.settings.max_feedrate_mm_s[Z_AXIS], ScreenHandler.HandleMaxSpeedChange_MKS, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<0>),
|
||||
|
||||
#if HOTENDS >= 1
|
||||
VPHELPER(VP_E0_MAX_SPEED, &planner.settings.max_feedrate_mm_s[E0_AXIS], ScreenHandler.HandleExtruderMaxSpeedChange_MKS, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<0>),
|
||||
VPHELPER(VP_E0_MAX_SPEED, &planner.settings.max_feedrate_mm_s[E_AXIS_N(0)], ScreenHandler.HandleExtruderMaxSpeedChange_MKS, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<0>),
|
||||
#endif
|
||||
#if HOTENDS >= 2
|
||||
VPHELPER(VP_E1_MAX_SPEED, &planner.settings.max_feedrate_mm_s[E1_AXIS], ScreenHandler.HandleExtruderMaxSpeedChange_MKS, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<0>),
|
||||
VPHELPER(VP_E1_MAX_SPEED, &planner.settings.max_feedrate_mm_s[E_AXIS_N(1)], ScreenHandler.HandleExtruderMaxSpeedChange_MKS, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<0>),
|
||||
#endif
|
||||
|
||||
VPHELPER(VP_X_ACC_MAX_SPEED, (uint16_t *)&planner.settings.max_acceleration_mm_per_s2[X_AXIS], ScreenHandler.HandleMaxAccChange_MKS, ScreenHandler.DGUSLCD_SendWordValueToDisplay),
|
||||
@ -677,10 +677,10 @@ const struct DGUS_VP_Variable ListOfVP[] PROGMEM = {
|
||||
VPHELPER(VP_Z_ACC_MAX_SPEED, (uint16_t *)&planner.settings.max_acceleration_mm_per_s2[Z_AXIS], ScreenHandler.HandleMaxAccChange_MKS, ScreenHandler.DGUSLCD_SendWordValueToDisplay),
|
||||
|
||||
#if HOTENDS >= 1
|
||||
VPHELPER(VP_E0_ACC_MAX_SPEED, (uint16_t *)&planner.settings.max_acceleration_mm_per_s2[E0_AXIS], ScreenHandler.HandleExtruderAccChange_MKS, ScreenHandler.DGUSLCD_SendWordValueToDisplay),
|
||||
VPHELPER(VP_E0_ACC_MAX_SPEED, (uint16_t *)&planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(0)], ScreenHandler.HandleExtruderAccChange_MKS, ScreenHandler.DGUSLCD_SendWordValueToDisplay),
|
||||
#endif
|
||||
#if HOTENDS >= 2
|
||||
VPHELPER(VP_E1_ACC_MAX_SPEED, (uint16_t *)&planner.settings.max_acceleration_mm_per_s2[E1_AXIS], ScreenHandler.HandleExtruderAccChange_MKS, ScreenHandler.DGUSLCD_SendWordValueToDisplay),
|
||||
VPHELPER(VP_E1_ACC_MAX_SPEED, (uint16_t *)&planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(1)], ScreenHandler.HandleExtruderAccChange_MKS, ScreenHandler.DGUSLCD_SendWordValueToDisplay),
|
||||
#endif
|
||||
|
||||
VPHELPER(VP_TRAVEL_SPEED, (uint16_t *)&planner.settings.travel_acceleration, ScreenHandler.HandleTravelAccChange_MKS, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<0>),
|
||||
|
@ -712,13 +712,15 @@ void MarlinUI::quick_feedback(const bool clear_buttons/*=true*/) {
|
||||
// Add a manual move to the queue?
|
||||
if (axis != NO_AXIS_ENUM && ELAPSED(millis(), start_time) && !planner.is_full()) {
|
||||
|
||||
const feedRate_t fr_mm_s = (axis <= E_AXIS) ? manual_feedrate_mm_s[axis] : XY_PROBE_FEEDRATE_MM_S;
|
||||
const feedRate_t fr_mm_s = (axis <= LOGICAL_AXES) ? manual_feedrate_mm_s[axis] : XY_PROBE_FEEDRATE_MM_S;
|
||||
|
||||
#if IS_KINEMATIC
|
||||
|
||||
#if HAS_MULTI_EXTRUDER
|
||||
REMEMBER(ae, active_extruder);
|
||||
if (axis == E_AXIS) active_extruder = e_index;
|
||||
#if MULTI_E_MANUAL
|
||||
if (axis == E_AXIS) active_extruder = e_index;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Apply a linear offset to a single axis
|
||||
@ -744,7 +746,9 @@ void MarlinUI::quick_feedback(const bool clear_buttons/*=true*/) {
|
||||
#else
|
||||
|
||||
// For Cartesian / Core motion simply move to the current_position
|
||||
planner.buffer_line(current_position, fr_mm_s, axis == E_AXIS ? e_index : active_extruder);
|
||||
planner.buffer_line(current_position, fr_mm_s,
|
||||
TERN_(MULTI_E_MANUAL, axis == E_AXIS ? e_index :) active_extruder
|
||||
);
|
||||
|
||||
//SERIAL_ECHOLNPAIR("Add planner.move with Axis ", AS_CHAR(axis_codes[axis]), " at FR ", fr_mm_s);
|
||||
|
||||
|
@ -68,10 +68,7 @@ void menu_backlash();
|
||||
START_MENU();
|
||||
BACK_ITEM(MSG_ADVANCED_SETTINGS);
|
||||
#define EDIT_DAC_PERCENT(A) EDIT_ITEM(uint8, MSG_DAC_PERCENT_##A, &driverPercent[_AXIS(A)], 0, 100, []{ stepper_dac.set_current_percents(driverPercent); })
|
||||
EDIT_DAC_PERCENT(X);
|
||||
EDIT_DAC_PERCENT(Y);
|
||||
EDIT_DAC_PERCENT(Z);
|
||||
EDIT_DAC_PERCENT(E);
|
||||
LOGICAL_AXIS_CODE(EDIT_DAC_PERCENT(E), EDIT_DAC_PERCENT(X), EDIT_DAC_PERCENT(Y), EDIT_DAC_PERCENT(Z), EDIT_DAC_PERCENT(I), EDIT_DAC_PERCENT(J), EDIT_DAC_PERCENT(K));
|
||||
ACTION_ITEM(MSG_DAC_EEPROM_WRITE, stepper_dac.commit_eeprom);
|
||||
END_MENU();
|
||||
}
|
||||
@ -359,7 +356,7 @@ void menu_backlash();
|
||||
#elif ENABLED(LIMITED_MAX_FR_EDITING)
|
||||
DEFAULT_MAX_FEEDRATE
|
||||
#else
|
||||
{ 9999, 9999, 9999, 9999 }
|
||||
LOGICAL_AXIS_ARRAY(9999, 9999, 9999, 9999)
|
||||
#endif
|
||||
;
|
||||
#if ENABLED(LIMITED_MAX_FR_EDITING) && !defined(MAX_FEEDRATE_EDIT_VALUES)
|
||||
@ -372,9 +369,7 @@ void menu_backlash();
|
||||
BACK_ITEM(MSG_ADVANCED_SETTINGS);
|
||||
|
||||
#define EDIT_VMAX(N) EDIT_ITEM_FAST(float5, MSG_VMAX_##N, &planner.settings.max_feedrate_mm_s[_AXIS(N)], 1, max_fr_edit_scaled[_AXIS(N)])
|
||||
EDIT_VMAX(A);
|
||||
EDIT_VMAX(B);
|
||||
EDIT_VMAX(C);
|
||||
LINEAR_AXIS_CODE(EDIT_VMAX(A), EDIT_VMAX(B), EDIT_VMAX(C), EDIT_VMAX(I), EDIT_VMAX(J), EDIT_VMAX(K));
|
||||
|
||||
#if E_STEPPERS
|
||||
EDIT_ITEM_FAST(float5, MSG_VMAX_E, &planner.settings.max_feedrate_mm_s[E_AXIS_N(active_extruder)], 1, max_fr_edit_scaled.e);
|
||||
@ -404,7 +399,7 @@ void menu_backlash();
|
||||
#elif ENABLED(LIMITED_MAX_ACCEL_EDITING)
|
||||
DEFAULT_MAX_ACCELERATION
|
||||
#else
|
||||
{ 99000, 99000, 99000, 99000 }
|
||||
LOGICAL_AXIS_ARRAY(99000, 99000, 99000, 99000)
|
||||
#endif
|
||||
;
|
||||
#if ENABLED(LIMITED_MAX_ACCEL_EDITING) && !defined(MAX_ACCEL_EDIT_VALUES)
|
||||
@ -419,16 +414,19 @@ void menu_backlash();
|
||||
// M204 P Acceleration
|
||||
EDIT_ITEM_FAST(float5_25, MSG_ACC, &planner.settings.acceleration, 25, max_accel);
|
||||
|
||||
// M204 R Retract Acceleration
|
||||
EDIT_ITEM_FAST(float5, MSG_A_RETRACT, &planner.settings.retract_acceleration, 100, planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(active_extruder)]);
|
||||
#if HAS_EXTRUDERS
|
||||
// M204 R Retract Acceleration
|
||||
EDIT_ITEM_FAST(float5, MSG_A_RETRACT, &planner.settings.retract_acceleration, 100, planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(active_extruder)]);
|
||||
#endif
|
||||
|
||||
// M204 T Travel Acceleration
|
||||
EDIT_ITEM_FAST(float5_25, MSG_A_TRAVEL, &planner.settings.travel_acceleration, 25, max_accel);
|
||||
|
||||
#define EDIT_AMAX(Q,L) EDIT_ITEM_FAST(long5_25, MSG_AMAX_##Q, &planner.settings.max_acceleration_mm_per_s2[_AXIS(Q)], L, max_accel_edit_scaled[_AXIS(Q)], []{ planner.reset_acceleration_rates(); })
|
||||
EDIT_AMAX(A, 100);
|
||||
EDIT_AMAX(B, 100);
|
||||
EDIT_AMAX(C, 10);
|
||||
LINEAR_AXIS_CODE(
|
||||
EDIT_AMAX(A, 100), EDIT_AMAX(B, 100), EDIT_AMAX(C, 10),
|
||||
EDIT_AMAX(I, 10), EDIT_AMAX(J, 10), EDIT_AMAX(K, 10)
|
||||
);
|
||||
|
||||
#if ENABLED(DISTINCT_E_FACTORS)
|
||||
EDIT_ITEM_FAST(long5_25, MSG_AMAX_E, &planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(active_extruder)], 100, max_accel_edit_scaled.e, []{ planner.reset_acceleration_rates(); });
|
||||
@ -474,14 +472,14 @@ void menu_backlash();
|
||||
#endif
|
||||
;
|
||||
#define EDIT_JERK(N) EDIT_ITEM_FAST(float3, MSG_V##N##_JERK, &planner.max_jerk[_AXIS(N)], 1, max_jerk_edit[_AXIS(N)])
|
||||
EDIT_JERK(A);
|
||||
EDIT_JERK(B);
|
||||
#if ENABLED(DELTA)
|
||||
EDIT_JERK(C);
|
||||
#define EDIT_JERK_C() EDIT_JERK(C)
|
||||
#else
|
||||
EDIT_ITEM_FAST(float52sign, MSG_VC_JERK, &planner.max_jerk.c, 0.1f, max_jerk_edit.c);
|
||||
#define EDIT_JERK_C() EDIT_ITEM_FAST(float52sign, MSG_VC_JERK, &planner.max_jerk.c, 0.1f, max_jerk_edit.c)
|
||||
#endif
|
||||
#if HAS_CLASSIC_E_JERK
|
||||
LINEAR_AXIS_CODE(EDIT_JERK(A), EDIT_JERK(B), EDIT_JERK_C());
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
EDIT_ITEM_FAST(float52sign, MSG_VE_JERK, &planner.max_jerk.e, 0.1f, max_jerk_edit.e);
|
||||
#endif
|
||||
|
||||
@ -517,9 +515,7 @@ void menu_advanced_steps_per_mm() {
|
||||
BACK_ITEM(MSG_ADVANCED_SETTINGS);
|
||||
|
||||
#define EDIT_QSTEPS(Q) EDIT_ITEM_FAST(float51, MSG_##Q##_STEPS, &planner.settings.axis_steps_per_mm[_AXIS(Q)], 5, 9999, []{ planner.refresh_positioning(); })
|
||||
EDIT_QSTEPS(A);
|
||||
EDIT_QSTEPS(B);
|
||||
EDIT_QSTEPS(C);
|
||||
LINEAR_AXIS_CODE(EDIT_QSTEPS(A), EDIT_QSTEPS(B), EDIT_QSTEPS(C));
|
||||
|
||||
#if ENABLED(DISTINCT_E_FACTORS)
|
||||
LOOP_L_N(n, E_STEPPERS)
|
||||
|
@ -361,7 +361,8 @@ void Endstops::event_handler() {
|
||||
prev_hit_state = hit_state;
|
||||
if (hit_state) {
|
||||
#if HAS_STATUS_MESSAGE
|
||||
char chrX = ' ', chrY = ' ', chrZ = ' ', chrP = ' ';
|
||||
char LINEAR_AXIS_LIST(chrX = ' ', chrY = ' ', chrZ = ' '),
|
||||
chrP = ' ';
|
||||
#define _SET_STOP_CHAR(A,C) (chr## A = C)
|
||||
#else
|
||||
#define _SET_STOP_CHAR(A,C) NOOP
|
||||
@ -390,7 +391,13 @@ void Endstops::event_handler() {
|
||||
#endif
|
||||
SERIAL_EOL();
|
||||
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf_P(0, PSTR(S_FMT " %c %c %c %c"), GET_TEXT(MSG_LCD_ENDSTOPS), chrX, chrY, chrZ, chrP));
|
||||
TERN_(HAS_STATUS_MESSAGE,
|
||||
ui.status_printf_P(0,
|
||||
PSTR(S_FMT GANG_N_1(LINEAR_AXES, " %c") " %c"),
|
||||
GET_TEXT(MSG_LCD_ENDSTOPS),
|
||||
LINEAR_AXIS_LIST(chrX, chrY, chrZ), chrP
|
||||
)
|
||||
);
|
||||
|
||||
#if BOTH(SD_ABORT_ON_ENDSTOP_HIT, SDSUPPORT)
|
||||
if (planner.abort_on_endstop_hit) {
|
||||
|
@ -89,7 +89,7 @@ bool relative_mode; // = false;
|
||||
#define Z_INIT_POS Z_HOME_POS
|
||||
#endif
|
||||
|
||||
xyze_pos_t current_position = { X_HOME_POS, Y_HOME_POS, Z_INIT_POS };
|
||||
xyze_pos_t current_position = LOGICAL_AXIS_ARRAY(0, X_HOME_POS, Y_HOME_POS, Z_INIT_POS);
|
||||
|
||||
/**
|
||||
* Cartesian Destination
|
||||
@ -195,16 +195,25 @@ 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_ECHOPAIR_P(X_LBL, lpos.x, SP_Y_LBL, lpos.y, SP_Z_LBL, lpos.z, SP_E_LBL, lpos.e);
|
||||
SERIAL_ECHOPAIR_P(
|
||||
LIST_N(DOUBLE(LINEAR_AXES), X_LBL, lpos.x, SP_Y_LBL, lpos.y, SP_Z_LBL, lpos.z)
|
||||
#if HAS_EXTRUDERS
|
||||
, SP_E_LBL, lpos.e
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
// Report the real current position according to the steppers.
|
||||
// Forward kinematics and un-leveling are applied.
|
||||
void report_real_position() {
|
||||
get_cartesian_from_steppers();
|
||||
xyze_pos_t npos = cartes;
|
||||
npos.e = planner.get_axis_position_mm(E_AXIS);
|
||||
xyze_pos_t npos = LOGICAL_AXIS_ARRAY(
|
||||
planner.get_axis_position_mm(E_AXIS),
|
||||
cartes.x, cartes.y, cartes.z
|
||||
);
|
||||
|
||||
TERN_(HAS_POSITION_MODIFIERS, planner.unapply_modifiers(npos, true));
|
||||
|
||||
report_logical_position(npos);
|
||||
report_more_positions();
|
||||
}
|
||||
@ -309,7 +318,9 @@ void sync_plan_position() {
|
||||
planner.set_position_mm(current_position);
|
||||
}
|
||||
|
||||
void sync_plan_position_e() { planner.set_e_position_mm(current_position.e); }
|
||||
#if HAS_EXTRUDERS
|
||||
void sync_plan_position_e() { planner.set_e_position_mm(current_position.e); }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get the stepper positions in the cartes[] array.
|
||||
@ -354,7 +365,10 @@ void get_cartesian_from_steppers() {
|
||||
void set_current_from_steppers_for_axis(const AxisEnum axis) {
|
||||
get_cartesian_from_steppers();
|
||||
xyze_pos_t pos = cartes;
|
||||
pos.e = planner.get_axis_position_mm(E_AXIS);
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
pos.e = planner.get_axis_position_mm(E_AXIS);
|
||||
#endif
|
||||
|
||||
#if HAS_POSITION_MODIFIERS
|
||||
planner.unapply_modifiers(pos, true);
|
||||
@ -442,9 +456,12 @@ 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(const float rx, const float ry, const float rz, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
void do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(const float rx, const float ry, const float rz),
|
||||
const_feedRate_t fr_mm_s/*=0.0f*/
|
||||
) {
|
||||
DEBUG_SECTION(log_move, "do_blocking_move_to", DEBUGGING(LEVELING));
|
||||
if (DEBUGGING(LEVELING)) DEBUG_XYZ("> ", rx, ry, rz);
|
||||
if (DEBUGGING(LEVELING)) DEBUG_XYZ("> ", LINEAR_AXIS_LIST(rx, ry, rz));
|
||||
|
||||
const feedRate_t z_feedrate = fr_mm_s ?: homing_feedrate(Z_AXIS),
|
||||
xy_feedrate = fr_mm_s ?: feedRate_t(XY_PROBE_FEEDRATE_MM_S);
|
||||
@ -529,34 +546,46 @@ void do_blocking_move_to(const float rx, const float ry, const float rz, const_f
|
||||
}
|
||||
|
||||
void do_blocking_move_to(const xy_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to(raw.x, raw.y, current_position.z, fr_mm_s);
|
||||
do_blocking_move_to(LINEAR_AXIS_LIST(raw.x, raw.y, current_position.z, current_position.i), 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(raw.x, raw.y, raw.z, fr_mm_s);
|
||||
do_blocking_move_to(LINEAR_AXIS_LIST(raw.x, raw.y, raw.z), 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(raw.x, raw.y, raw.z, fr_mm_s);
|
||||
do_blocking_move_to(LINEAR_AXIS_LIST(raw.x, raw.y, raw.z), fr_mm_s);
|
||||
}
|
||||
|
||||
void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to(rx, current_position.y, current_position.z, fr_mm_s);
|
||||
do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(rx, current_position.y, current_position.z),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
void do_blocking_move_to_y(const_float_t ry, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to(current_position.x, ry, current_position.z, fr_mm_s);
|
||||
do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(current_position.x, ry, current_position.z),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
void do_blocking_move_to_z(const_float_t rz, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to_xy_z(current_position, rz, fr_mm_s);
|
||||
}
|
||||
|
||||
void do_blocking_move_to_xy(const_float_t rx, const_float_t ry, const_feedRate_t fr_mm_s/*=0.0*/) {
|
||||
do_blocking_move_to(rx, ry, current_position.z, fr_mm_s);
|
||||
do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(rx, ry, current_position.z),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
void do_blocking_move_to_xy(const xy_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*/) {
|
||||
do_blocking_move_to_xy(raw.x, raw.y, fr_mm_s);
|
||||
}
|
||||
|
||||
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(raw.x, raw.y, z, fr_mm_s);
|
||||
do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(raw.x, raw.y, z),
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
|
||||
void do_z_clearance(const_float_t zclear, const bool lower_allowed/*=false*/) {
|
||||
@ -589,8 +618,8 @@ void restore_feedrate_and_scaling() {
|
||||
// Software Endstops are based on the configured limits.
|
||||
soft_endstops_t soft_endstop = {
|
||||
true, false,
|
||||
{ X_MIN_POS, Y_MIN_POS, Z_MIN_POS },
|
||||
{ X_MAX_POS, Y_MAX_POS, Z_MAX_POS }
|
||||
LINEAR_AXIS_ARRAY(X_MIN_POS, Y_MIN_POS, Z_MIN_POS),
|
||||
LINEAR_AXIS_ARRAY(X_MAX_BED, Y_MAX_BED, Z_MAX_POS)
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1176,9 +1205,12 @@ void prepare_line_to_destination() {
|
||||
if (TEST(b, a) && TERN(HOME_AFTER_DEACTIVATE, axis_is_trusted, axis_was_homed)(a))
|
||||
CBI(b, a);
|
||||
};
|
||||
set_should(axis_bits, X_AXIS); // Clear test bits that are trusted
|
||||
set_should(axis_bits, Y_AXIS);
|
||||
set_should(axis_bits, Z_AXIS);
|
||||
// Clear test bits that are trusted
|
||||
LINEAR_AXIS_CODE(
|
||||
set_should(axis_bits, X_AXIS),
|
||||
set_should(axis_bits, Y_AXIS),
|
||||
set_should(axis_bits, Z_AXIS)
|
||||
);
|
||||
return axis_bits;
|
||||
}
|
||||
|
||||
@ -1187,9 +1219,11 @@ void prepare_line_to_destination() {
|
||||
PGM_P home_first = GET_TEXT(MSG_HOME_FIRST);
|
||||
char msg[strlen_P(home_first)+1];
|
||||
sprintf_P(msg, home_first,
|
||||
TEST(axis_bits, X_AXIS) ? "X" : "",
|
||||
TEST(axis_bits, Y_AXIS) ? "Y" : "",
|
||||
TEST(axis_bits, Z_AXIS) ? "Z" : ""
|
||||
LINEAR_AXIS_LIST(
|
||||
TEST(axis_bits, X_AXIS) ? "X" : "",
|
||||
TEST(axis_bits, Y_AXIS) ? "Y" : "",
|
||||
TEST(axis_bits, Z_AXIS) ? "Z" : ""
|
||||
)
|
||||
);
|
||||
SERIAL_ECHO_START();
|
||||
SERIAL_ECHOLN(msg);
|
||||
@ -1356,7 +1390,7 @@ void prepare_line_to_destination() {
|
||||
const feedRate_t home_fr_mm_s = fr_mm_s ?: homing_feedrate(axis);
|
||||
|
||||
if (DEBUGGING(LEVELING)) {
|
||||
DEBUG_ECHOPAIR("...(", AS_CHAR(axis_codes[axis]), ", ", distance, ", ");
|
||||
DEBUG_ECHOPAIR("...(", AS_CHAR(AXIS_CHAR(axis)), ", ", distance, ", ");
|
||||
if (fr_mm_s)
|
||||
DEBUG_ECHO(fr_mm_s);
|
||||
else
|
||||
@ -1441,12 +1475,12 @@ void prepare_line_to_destination() {
|
||||
* "trusted" position).
|
||||
*/
|
||||
void set_axis_never_homed(const AxisEnum axis) {
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR(">>> set_axis_never_homed(", AS_CHAR(axis_codes[axis]), ")");
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR(">>> set_axis_never_homed(", AS_CHAR(AXIS_CHAR(axis)), ")");
|
||||
|
||||
set_axis_untrusted(axis);
|
||||
set_axis_unhomed(axis);
|
||||
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("<<< set_axis_never_homed(", AS_CHAR(axis_codes[axis]), ")");
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("<<< set_axis_never_homed(", AS_CHAR(AXIS_CHAR(axis)), ")");
|
||||
|
||||
TERN_(I2C_POSITION_ENCODERS, I2CPEM.unhomed(axis));
|
||||
}
|
||||
@ -1507,7 +1541,7 @@ void prepare_line_to_destination() {
|
||||
if (ABS(phaseDelta) * planner.steps_to_mm[axis] / phasePerUStep < 0.05f)
|
||||
SERIAL_ECHOLNPAIR("Selected home phase ", home_phase[axis],
|
||||
" too close to endstop trigger phase ", phaseCurrent,
|
||||
". Pick a different phase for ", AS_CHAR(axis_codes[axis]));
|
||||
". Pick a different phase for ", AS_CHAR(AXIS_CHAR(axis)));
|
||||
|
||||
// Skip to next if target position is behind current. So it only moves away from endstop.
|
||||
if (phaseDelta < 0) phaseDelta += 1024;
|
||||
@ -1518,7 +1552,7 @@ void prepare_line_to_destination() {
|
||||
// Optional debug messages
|
||||
if (DEBUGGING(LEVELING)) {
|
||||
DEBUG_ECHOLNPAIR(
|
||||
"Endstop ", AS_CHAR(axis_codes[axis]), " hit at Phase:", phaseCurrent,
|
||||
"Endstop ", AS_CHAR(AXIS_CHAR(axis)), " hit at Phase:", phaseCurrent,
|
||||
" Delta:", phaseDelta, " Distance:", mmDelta
|
||||
);
|
||||
}
|
||||
@ -1556,7 +1590,7 @@ void prepare_line_to_destination() {
|
||||
if (!_CAN_HOME(X) && !_CAN_HOME(Y) && !_CAN_HOME(Z)) return;
|
||||
#endif
|
||||
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR(">>> homeaxis(", AS_CHAR(axis_codes[axis]), ")");
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR(">>> homeaxis(", AS_CHAR(AXIS_CHAR(axis)), ")");
|
||||
|
||||
const int axis_home_dir = TERN0(DUAL_X_CARRIAGE, axis == X_AXIS)
|
||||
? TOOL_X_HOME_DIR(active_extruder) : home_dir(axis);
|
||||
@ -1634,7 +1668,7 @@ void prepare_line_to_destination() {
|
||||
case Z_AXIS: es = Z_ENDSTOP; break;
|
||||
}
|
||||
if (TEST(endstops.state(), es)) {
|
||||
SERIAL_ECHO_MSG("Bad ", AS_CHAR(axis_codes[axis]), " Endstop?");
|
||||
SERIAL_ECHO_MSG("Bad ", AS_CHAR(AXIS_CHAR(axis)), " Endstop?");
|
||||
kill(GET_TEXT(MSG_KILL_HOMING_FAILED));
|
||||
}
|
||||
#endif
|
||||
@ -1856,7 +1890,7 @@ void prepare_line_to_destination() {
|
||||
if (axis == Z_AXIS) fwretract.current_hop = 0.0;
|
||||
#endif
|
||||
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("<<< homeaxis(", AS_CHAR(axis_codes[axis]), ")");
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("<<< homeaxis(", AS_CHAR(AXIS_CHAR(axis)), ")");
|
||||
|
||||
} // homeaxis()
|
||||
|
||||
@ -1881,7 +1915,7 @@ void prepare_line_to_destination() {
|
||||
* Callers must sync the planner position after calling this!
|
||||
*/
|
||||
void set_axis_is_at_home(const AxisEnum axis) {
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR(">>> set_axis_is_at_home(", AS_CHAR(axis_codes[axis]), ")");
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR(">>> set_axis_is_at_home(", AS_CHAR(AXIS_CHAR(axis)), ")");
|
||||
|
||||
set_axis_trusted(axis);
|
||||
set_axis_homed(axis);
|
||||
@ -1931,10 +1965,10 @@ void set_axis_is_at_home(const AxisEnum axis) {
|
||||
|
||||
if (DEBUGGING(LEVELING)) {
|
||||
#if HAS_HOME_OFFSET
|
||||
DEBUG_ECHOLNPAIR("> home_offset[", AS_CHAR(axis_codes[axis]), "] = ", home_offset[axis]);
|
||||
DEBUG_ECHOLNPAIR("> home_offset[", AS_CHAR(AXIS_CHAR(axis)), "] = ", home_offset[axis]);
|
||||
#endif
|
||||
DEBUG_POS("", current_position);
|
||||
DEBUG_ECHOLNPAIR("<<< set_axis_is_at_home(", AS_CHAR(axis_codes[axis]), ")");
|
||||
DEBUG_ECHOLNPAIR("<<< set_axis_is_at_home(", AS_CHAR(AXIS_CHAR(axis)), ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,7 @@ inline int8_t pgm_read_any(const int8_t *p) { return TERN(__IMXRT1062__, *p, pgm
|
||||
|
||||
#define XYZ_DEFS(T, NAME, OPT) \
|
||||
inline T NAME(const AxisEnum axis) { \
|
||||
static const XYZval<T> NAME##_P DEFS_PROGMEM = { X_##OPT, Y_##OPT, Z_##OPT }; \
|
||||
static const XYZval<T> NAME##_P DEFS_PROGMEM = LINEAR_AXIS_ARRAY(X_##OPT, Y_##OPT, Z_##OPT); \
|
||||
return pgm_read_any(&NAME##_P[axis]); \
|
||||
}
|
||||
XYZ_DEFS(float, base_min_pos, MIN_POS);
|
||||
@ -264,7 +264,10 @@ void quickstop_stepper();
|
||||
* no kinematic translation. Used for homing axes and cartesian/core syncing.
|
||||
*/
|
||||
void sync_plan_position();
|
||||
void sync_plan_position_e();
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
void sync_plan_position_e();
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Move the planner to the current position from wherever it last moved
|
||||
@ -295,7 +298,10 @@ 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(const float rx, const float ry, const float rz, const_feedRate_t fr_mm_s=0.0f);
|
||||
void do_blocking_move_to(
|
||||
LINEAR_AXIS_LIST(const float rx, const float ry, const float rz),
|
||||
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);
|
||||
@ -322,7 +328,7 @@ void do_z_clearance(const_float_t zclear, const bool lower_allowed=false);
|
||||
/**
|
||||
* Homing and Trusted Axes
|
||||
*/
|
||||
typedef IF<(LINEAR_AXES>8), uint16_t, uint8_t>::type linear_axis_bits_t;
|
||||
typedef IF<(LINEAR_AXES > 8), uint16_t, uint8_t>::type linear_axis_bits_t;
|
||||
constexpr linear_axis_bits_t linear_bits = _BV(LINEAR_AXES) - 1;
|
||||
|
||||
void set_axis_is_at_home(const AxisEnum axis);
|
||||
|
@ -1345,10 +1345,12 @@ void Planner::check_axes_activity() {
|
||||
#if ANY(DISABLE_X, DISABLE_Y, DISABLE_Z, DISABLE_E)
|
||||
for (uint8_t b = block_buffer_tail; b != block_buffer_head; b = next_block_index(b)) {
|
||||
block_t *block = &block_buffer[b];
|
||||
if (ENABLED(DISABLE_X) && block->steps.x) axis_active.x = true;
|
||||
if (ENABLED(DISABLE_Y) && block->steps.y) axis_active.y = true;
|
||||
if (ENABLED(DISABLE_Z) && block->steps.z) axis_active.z = true;
|
||||
if (ENABLED(DISABLE_E) && block->steps.e) axis_active.e = true;
|
||||
LOGICAL_AXIS_CODE(
|
||||
if (TERN0(DISABLE_E, block->steps.e)) axis_active.e = true,
|
||||
if (TERN0(DISABLE_X, block->steps.x)) axis_active.x = true,
|
||||
if (TERN0(DISABLE_Y, block->steps.y)) axis_active.y = true,
|
||||
if (TERN0(DISABLE_Z, block->steps.z)) axis_active.z = true
|
||||
);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1369,10 +1371,12 @@ void Planner::check_axes_activity() {
|
||||
//
|
||||
// Disable inactive axes
|
||||
//
|
||||
if (TERN0(DISABLE_X, !axis_active.x)) DISABLE_AXIS_X();
|
||||
if (TERN0(DISABLE_Y, !axis_active.y)) DISABLE_AXIS_Y();
|
||||
if (TERN0(DISABLE_Z, !axis_active.z)) DISABLE_AXIS_Z();
|
||||
if (TERN0(DISABLE_E, !axis_active.e)) disable_e_steppers();
|
||||
LOGICAL_AXIS_CODE(
|
||||
if (TERN0(DISABLE_E, !axis_active.e)) disable_e_steppers(),
|
||||
if (TERN0(DISABLE_X, !axis_active.x)) DISABLE_AXIS_X(),
|
||||
if (TERN0(DISABLE_Y, !axis_active.y)) DISABLE_AXIS_Y(),
|
||||
if (TERN0(DISABLE_Z, !axis_active.z)) DISABLE_AXIS_Z()
|
||||
);
|
||||
|
||||
//
|
||||
// Update Fan speeds
|
||||
@ -1823,16 +1827,12 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
OPTARG(HAS_DIST_MM_ARG, const xyze_float_t &cart_dist_mm)
|
||||
, feedRate_t fr_mm_s, const uint8_t extruder, const_float_t millimeters/*=0.0*/
|
||||
) {
|
||||
|
||||
const int32_t da = target.a - position.a,
|
||||
db = target.b - position.b,
|
||||
dc = target.c - position.c;
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
int32_t de = target.e - position.e;
|
||||
#else
|
||||
constexpr int32_t de = 0;
|
||||
#endif
|
||||
int32_t LOGICAL_AXIS_LIST(
|
||||
de = target.e - position.e,
|
||||
da = target.a - position.a,
|
||||
db = target.b - position.b,
|
||||
dc = target.c - position.c
|
||||
);
|
||||
|
||||
/* <-- add a slash to enable
|
||||
SERIAL_ECHOLNPAIR(
|
||||
@ -1883,35 +1883,39 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
// Compute direction bit-mask for this block
|
||||
uint8_t dm = 0;
|
||||
#if CORE_IS_XY
|
||||
if (da < 0) SBI(dm, X_HEAD); // Save the real Extruder (head) direction in X Axis
|
||||
if (da < 0) SBI(dm, X_HEAD); // Save the toolhead's true direction in X
|
||||
if (db < 0) SBI(dm, Y_HEAD); // ...and Y
|
||||
if (dc < 0) SBI(dm, Z_AXIS);
|
||||
if (da + db < 0) SBI(dm, A_AXIS); // Motor A direction
|
||||
if (CORESIGN(da - db) < 0) SBI(dm, B_AXIS); // Motor B direction
|
||||
#elif CORE_IS_XZ
|
||||
if (da < 0) SBI(dm, X_HEAD); // Save the real Extruder (head) direction in X Axis
|
||||
if (da < 0) SBI(dm, X_HEAD); // Save the toolhead's true direction in X
|
||||
if (db < 0) SBI(dm, Y_AXIS);
|
||||
if (dc < 0) SBI(dm, Z_HEAD); // ...and Z
|
||||
if (da + dc < 0) SBI(dm, A_AXIS); // Motor A direction
|
||||
if (CORESIGN(da - dc) < 0) SBI(dm, C_AXIS); // Motor C direction
|
||||
#elif CORE_IS_YZ
|
||||
if (da < 0) SBI(dm, X_AXIS);
|
||||
if (db < 0) SBI(dm, Y_HEAD); // Save the real Extruder (head) direction in Y Axis
|
||||
if (db < 0) SBI(dm, Y_HEAD); // Save the toolhead's true direction in Y
|
||||
if (dc < 0) SBI(dm, Z_HEAD); // ...and Z
|
||||
if (db + dc < 0) SBI(dm, B_AXIS); // Motor B direction
|
||||
if (CORESIGN(db - dc) < 0) SBI(dm, C_AXIS); // Motor C direction
|
||||
#elif ENABLED(MARKFORGED_XY)
|
||||
if (da < 0) SBI(dm, X_HEAD); // Save the real Extruder (head) direction in X Axis
|
||||
if (da < 0) SBI(dm, X_HEAD); // Save the toolhead's true direction in X
|
||||
if (db < 0) SBI(dm, Y_HEAD); // ...and Y
|
||||
if (dc < 0) SBI(dm, Z_AXIS);
|
||||
if (da + db < 0) SBI(dm, A_AXIS); // Motor A direction
|
||||
if (db < 0) SBI(dm, B_AXIS); // Motor B direction
|
||||
#else
|
||||
if (da < 0) SBI(dm, X_AXIS);
|
||||
if (db < 0) SBI(dm, Y_AXIS);
|
||||
if (dc < 0) SBI(dm, Z_AXIS);
|
||||
LINEAR_AXIS_CODE(
|
||||
if (da < 0) SBI(dm, X_AXIS),
|
||||
if (db < 0) SBI(dm, Y_AXIS),
|
||||
if (dc < 0) SBI(dm, Z_AXIS)
|
||||
);
|
||||
#endif
|
||||
#if HAS_EXTRUDERS
|
||||
if (de < 0) SBI(dm, E_AXIS);
|
||||
#endif
|
||||
if (de < 0) SBI(dm, E_AXIS);
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
const float esteps_float = de * e_factor[extruder];
|
||||
@ -1947,7 +1951,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
block->steps.set(ABS(da), ABS(db), ABS(dc));
|
||||
#else
|
||||
// default non-h-bot planning
|
||||
block->steps.set(ABS(da), ABS(db), ABS(dc));
|
||||
block->steps.set(LINEAR_AXIS_LIST(ABS(da), ABS(db), ABS(dc)));
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -1990,41 +1994,51 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
steps_dist_mm.a = (da - db) * steps_to_mm[A_AXIS];
|
||||
steps_dist_mm.b = db * steps_to_mm[B_AXIS];
|
||||
#else
|
||||
steps_dist_mm.a = da * steps_to_mm[A_AXIS];
|
||||
steps_dist_mm.b = db * steps_to_mm[B_AXIS];
|
||||
steps_dist_mm.c = dc * steps_to_mm[C_AXIS];
|
||||
LINEAR_AXIS_CODE(
|
||||
steps_dist_mm.a = da * steps_to_mm[A_AXIS],
|
||||
steps_dist_mm.b = db * steps_to_mm[B_AXIS],
|
||||
steps_dist_mm.c = dc * steps_to_mm[C_AXIS]
|
||||
);
|
||||
#endif
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
steps_dist_mm.e = esteps_float * steps_to_mm[E_AXIS_N(extruder)];
|
||||
#else
|
||||
steps_dist_mm.e = 0.0f;
|
||||
#endif
|
||||
|
||||
TERN_(LCD_SHOW_E_TOTAL, e_move_accumulator += steps_dist_mm.e);
|
||||
|
||||
if (block->steps.a < MIN_STEPS_PER_SEGMENT && block->steps.b < MIN_STEPS_PER_SEGMENT && block->steps.c < MIN_STEPS_PER_SEGMENT) {
|
||||
block->millimeters = (0
|
||||
#if HAS_EXTRUDERS
|
||||
+ ABS(steps_dist_mm.e)
|
||||
#endif
|
||||
);
|
||||
if (true LINEAR_AXIS_GANG(
|
||||
&& block->steps.a < MIN_STEPS_PER_SEGMENT,
|
||||
&& block->steps.b < MIN_STEPS_PER_SEGMENT,
|
||||
&& block->steps.c < MIN_STEPS_PER_SEGMENT
|
||||
)
|
||||
) {
|
||||
block->millimeters = TERN0(HAS_EXTRUDERS, ABS(steps_dist_mm.e));
|
||||
}
|
||||
else {
|
||||
if (millimeters)
|
||||
block->millimeters = millimeters;
|
||||
else
|
||||
else {
|
||||
block->millimeters = SQRT(
|
||||
#if EITHER(CORE_IS_XY, MARKFORGED_XY)
|
||||
sq(steps_dist_mm.head.x) + sq(steps_dist_mm.head.y) + sq(steps_dist_mm.z)
|
||||
LINEAR_AXIS_GANG(
|
||||
sq(steps_dist_mm.head.x), + sq(steps_dist_mm.head.y), + sq(steps_dist_mm.z)
|
||||
)
|
||||
#elif CORE_IS_XZ
|
||||
sq(steps_dist_mm.head.x) + sq(steps_dist_mm.y) + sq(steps_dist_mm.head.z)
|
||||
LINEAR_AXIS_GANG(
|
||||
sq(steps_dist_mm.head.x), + sq(steps_dist_mm.y), + sq(steps_dist_mm.head.z)
|
||||
)
|
||||
#elif CORE_IS_YZ
|
||||
sq(steps_dist_mm.x) + sq(steps_dist_mm.head.y) + sq(steps_dist_mm.head.z)
|
||||
LINEAR_AXIS_GANG(
|
||||
sq(steps_dist_mm.x), + sq(steps_dist_mm.head.y), + sq(steps_dist_mm.head.z)
|
||||
)
|
||||
#else
|
||||
sq(steps_dist_mm.x) + sq(steps_dist_mm.y) + sq(steps_dist_mm.z)
|
||||
LINEAR_AXIS_GANG(
|
||||
sq(steps_dist_mm.x), + sq(steps_dist_mm.y), + sq(steps_dist_mm.z)
|
||||
)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* At this point at least one of the axes has more steps than
|
||||
@ -2038,11 +2052,11 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
TERN_(BACKLASH_COMPENSATION, backlash.add_correction_steps(da, db, dc, dm, block));
|
||||
}
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
block->steps.e = esteps;
|
||||
#endif
|
||||
TERN_(HAS_EXTRUDERS, block->steps.e = esteps);
|
||||
|
||||
block->step_event_count = _MAX(block->steps.a, block->steps.b, block->steps.c, esteps);
|
||||
block->step_event_count = _MAX(LOGICAL_AXIS_LIST(
|
||||
esteps, block->steps.a, block->steps.b, block->steps.c
|
||||
));
|
||||
|
||||
// Bail if this is a zero-length block
|
||||
if (block->step_event_count < MIN_STEPS_PER_SEGMENT) return false;
|
||||
@ -2065,8 +2079,11 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
#endif
|
||||
|
||||
#if ENABLED(AUTO_POWER_CONTROL)
|
||||
if (block->steps.x || block->steps.y || block->steps.z)
|
||||
powerManager.power_on();
|
||||
if (LINEAR_AXIS_GANG(
|
||||
block->steps.x,
|
||||
|| block->steps.y,
|
||||
|| block->steps.z
|
||||
)) powerManager.power_on();
|
||||
#endif
|
||||
|
||||
// Enable active axes
|
||||
@ -2091,11 +2108,11 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
}
|
||||
if (block->steps.x) ENABLE_AXIS_X();
|
||||
#else
|
||||
if (block->steps.x) ENABLE_AXIS_X();
|
||||
if (block->steps.y) ENABLE_AXIS_Y();
|
||||
#if DISABLED(Z_LATE_ENABLE)
|
||||
if (block->steps.z) ENABLE_AXIS_Z();
|
||||
#endif
|
||||
LINEAR_AXIS_CODE(
|
||||
if (block->steps.x) ENABLE_AXIS_X(),
|
||||
if (block->steps.y) ENABLE_AXIS_Y(),
|
||||
if (TERN(Z_LATE_ENABLE, 0, block->steps.z)) ENABLE_AXIS_Z()
|
||||
);
|
||||
#endif
|
||||
|
||||
// Enable extruder(s)
|
||||
@ -2283,7 +2300,9 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
// Compute and limit the acceleration rate for the trapezoid generator.
|
||||
const float steps_per_mm = block->step_event_count * inverse_millimeters;
|
||||
uint32_t accel;
|
||||
if (!block->steps.a && !block->steps.b && !block->steps.c) { // Is this a retract / recover move?
|
||||
if (LINEAR_AXIS_GANG(
|
||||
!block->steps.a, && !block->steps.b, && !block->steps.c
|
||||
)) { // Is this a retract / recover move?
|
||||
accel = CEIL(settings.retract_acceleration * steps_per_mm); // Convert to: acceleration steps/sec^2
|
||||
TERN_(LIN_ADVANCE, block->use_advance_lead = false); // No linear advance for simple retract/recover
|
||||
}
|
||||
@ -2348,16 +2367,20 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
|
||||
// Limit acceleration per axis
|
||||
if (block->step_event_count <= acceleration_long_cutoff) {
|
||||
LIMIT_ACCEL_LONG(A_AXIS, 0);
|
||||
LIMIT_ACCEL_LONG(B_AXIS, 0);
|
||||
LIMIT_ACCEL_LONG(C_AXIS, 0);
|
||||
LIMIT_ACCEL_LONG(E_AXIS, E_INDEX_N(extruder));
|
||||
LOGICAL_AXIS_CODE(
|
||||
LIMIT_ACCEL_LONG(E_AXIS, E_INDEX_N(extruder)),
|
||||
LIMIT_ACCEL_LONG(A_AXIS, 0),
|
||||
LIMIT_ACCEL_LONG(B_AXIS, 0),
|
||||
LIMIT_ACCEL_LONG(C_AXIS, 0)
|
||||
);
|
||||
}
|
||||
else {
|
||||
LIMIT_ACCEL_FLOAT(A_AXIS, 0);
|
||||
LIMIT_ACCEL_FLOAT(B_AXIS, 0);
|
||||
LIMIT_ACCEL_FLOAT(C_AXIS, 0);
|
||||
LIMIT_ACCEL_FLOAT(E_AXIS, E_INDEX_N(extruder));
|
||||
LOGICAL_AXIS_CODE(
|
||||
LIMIT_ACCEL_FLOAT(E_AXIS, E_INDEX_N(extruder)),
|
||||
LIMIT_ACCEL_FLOAT(A_AXIS, 0),
|
||||
LIMIT_ACCEL_FLOAT(B_AXIS, 0),
|
||||
LIMIT_ACCEL_FLOAT(C_AXIS, 0)
|
||||
);
|
||||
}
|
||||
}
|
||||
block->acceleration_steps_per_s2 = accel;
|
||||
@ -2421,7 +2444,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
#if HAS_DIST_MM_ARG
|
||||
cart_dist_mm
|
||||
#else
|
||||
{ steps_dist_mm.x, steps_dist_mm.y, steps_dist_mm.z, steps_dist_mm.e }
|
||||
LOGICAL_AXIS_ARRAY(steps_dist_mm.e, steps_dist_mm.x, steps_dist_mm.y, steps_dist_mm.z)
|
||||
#endif
|
||||
;
|
||||
|
||||
@ -2440,8 +2463,12 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||
if (moves_queued && !UNEAR_ZERO(previous_nominal_speed_sqr)) {
|
||||
// Compute cosine of angle between previous and current path. (prev_unit_vec is negative)
|
||||
// NOTE: Max junction velocity is computed without sin() or acos() by trig half angle identity.
|
||||
float junction_cos_theta = (-prev_unit_vec.x * unit_vec.x) + (-prev_unit_vec.y * unit_vec.y)
|
||||
+ (-prev_unit_vec.z * unit_vec.z) + (-prev_unit_vec.e * unit_vec.e);
|
||||
float junction_cos_theta = LOGICAL_AXIS_GANG(
|
||||
+ (-prev_unit_vec.e * unit_vec.e),
|
||||
(-prev_unit_vec.x * unit_vec.x),
|
||||
+ (-prev_unit_vec.y * unit_vec.y),
|
||||
+ (-prev_unit_vec.z * unit_vec.z)
|
||||
);
|
||||
|
||||
// NOTE: Computed without any expensive trig, sin() or acos(), by trig half angle identity of cos(theta).
|
||||
if (junction_cos_theta > 0.999999f) {
|
||||
@ -2756,7 +2783,8 @@ void Planner::buffer_sync_block(TERN_(LASER_SYNCHRONOUS_M106_M107, uint8_t sync_
|
||||
*
|
||||
* Return 'false' if no segment was queued due to cleaning, cold extrusion, full queue, etc.
|
||||
*/
|
||||
bool Planner::buffer_segment(const_float_t a, const_float_t b, const_float_t c, const_float_t e
|
||||
bool Planner::buffer_segment(
|
||||
LOGICAL_AXIS_LIST(const_float_t e, const_float_t a, const_float_t b, const_float_t c)
|
||||
OPTARG(HAS_DIST_MM_ARG, const xyze_float_t &cart_dist_mm)
|
||||
, const_feedRate_t fr_mm_s, const uint8_t extruder, const_float_t millimeters/*=0.0*/
|
||||
) {
|
||||
@ -2775,21 +2803,25 @@ bool Planner::buffer_segment(const_float_t a, const_float_t b, const_float_t c,
|
||||
// The target position of the tool in absolute steps
|
||||
// Calculate target position in absolute steps
|
||||
const abce_long_t target = {
|
||||
int32_t(LROUND(a * settings.axis_steps_per_mm[A_AXIS])),
|
||||
int32_t(LROUND(b * settings.axis_steps_per_mm[B_AXIS])),
|
||||
int32_t(LROUND(c * settings.axis_steps_per_mm[C_AXIS])),
|
||||
int32_t(LROUND(e * settings.axis_steps_per_mm[E_AXIS_N(extruder)]))
|
||||
LOGICAL_AXIS_LIST(
|
||||
int32_t(LROUND(e * settings.axis_steps_per_mm[E_AXIS_N(extruder)])),
|
||||
int32_t(LROUND(a * settings.axis_steps_per_mm[A_AXIS])),
|
||||
int32_t(LROUND(b * settings.axis_steps_per_mm[B_AXIS])),
|
||||
int32_t(LROUND(c * settings.axis_steps_per_mm[C_AXIS]))
|
||||
)
|
||||
};
|
||||
|
||||
#if HAS_POSITION_FLOAT
|
||||
const xyze_pos_t target_float = { a, b, c, e };
|
||||
const xyze_pos_t target_float = LOGICAL_AXIS_ARRAY(e, a, b, c);
|
||||
#endif
|
||||
|
||||
// DRYRUN prevents E moves from taking place
|
||||
if (DEBUGGING(DRYRUN) || TERN0(CANCEL_OBJECTS, cancelable.skipping)) {
|
||||
position.e = target.e;
|
||||
TERN_(HAS_POSITION_FLOAT, position_float.e = e);
|
||||
}
|
||||
#if HAS_EXTRUDERS
|
||||
// DRYRUN prevents E moves from taking place
|
||||
if (DEBUGGING(DRYRUN) || TERN0(CANCEL_OBJECTS, cancelable.skipping)) {
|
||||
position.e = target.e;
|
||||
TERN_(HAS_POSITION_FLOAT, position_float.e = e);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* <-- add a slash to enable
|
||||
SERIAL_ECHOPAIR(" buffer_segment FR:", fr_mm_s);
|
||||
@ -2848,10 +2880,12 @@ bool Planner::buffer_segment(const_float_t a, const_float_t b, const_float_t c,
|
||||
* millimeters - the length of the movement, if known
|
||||
* inv_duration - the reciprocal if the duration of the movement, if known (kinematic only if feeedrate scaling is enabled)
|
||||
*/
|
||||
bool Planner::buffer_line(const_float_t rx, const_float_t ry, const_float_t rz, const_float_t e, const_feedRate_t fr_mm_s, const uint8_t extruder, const float millimeters
|
||||
bool Planner::buffer_line(
|
||||
LOGICAL_AXIS_LIST(const_float_t e, const_float_t rx, const_float_t ry, const_float_t rz)
|
||||
, const feedRate_t &fr_mm_s, const uint8_t extruder, const float millimeters
|
||||
OPTARG(SCARA_FEEDRATE_SCALING, const_float_t inv_duration)
|
||||
) {
|
||||
xyze_pos_t machine = { rx, ry, rz, e };
|
||||
xyze_pos_t machine = LOGICAL_AXIS_ARRAY(e, rx, ry, rz);
|
||||
TERN_(HAS_POSITION_MODIFIERS, apply_modifiers(machine));
|
||||
|
||||
#if IS_KINEMATIC
|
||||
@ -2914,16 +2948,12 @@ bool Planner::buffer_line(const_float_t rx, const_float_t ry, const_float_t rz,
|
||||
FANS_LOOP(i) block->fan_speed[i] = thermalManager.fan_speed[i];
|
||||
#endif
|
||||
|
||||
#if HAS_MULTI_EXTRUDER
|
||||
block->extruder = extruder;
|
||||
#endif
|
||||
TERN_(HAS_MULTI_EXTRUDER, block->extruder = extruder);
|
||||
|
||||
block->page_idx = page_idx;
|
||||
|
||||
block->step_event_count = num_steps;
|
||||
block->initial_rate =
|
||||
block->final_rate =
|
||||
block->nominal_rate = last_page_step_rate; // steps/s
|
||||
block->initial_rate = block->final_rate = block->nominal_rate = last_page_step_rate; // steps/s
|
||||
|
||||
block->accelerate_until = 0;
|
||||
block->decelerate_after = block->step_event_count;
|
||||
@ -2967,13 +2997,19 @@ bool Planner::buffer_line(const_float_t rx, const_float_t ry, const_float_t rz,
|
||||
* The provided ABC position is in machine units.
|
||||
*/
|
||||
|
||||
void Planner::set_machine_position_mm(const_float_t a, const_float_t b, const_float_t c, const_float_t e) {
|
||||
void Planner::set_machine_position_mm(
|
||||
LOGICAL_AXIS_LIST(const_float_t e, const_float_t a, const_float_t b, const_float_t c)
|
||||
) {
|
||||
TERN_(DISTINCT_E_FACTORS, last_extruder = active_extruder);
|
||||
TERN_(HAS_POSITION_FLOAT, position_float.set(a, b, c, e));
|
||||
position.set(LROUND(a * settings.axis_steps_per_mm[A_AXIS]),
|
||||
LROUND(b * settings.axis_steps_per_mm[B_AXIS]),
|
||||
LROUND(c * settings.axis_steps_per_mm[C_AXIS]),
|
||||
LROUND(e * settings.axis_steps_per_mm[E_AXIS_N(active_extruder)]));
|
||||
TERN_(HAS_POSITION_FLOAT, position_float.set(LOGICAL_AXIS_LIST(e, a, b, c)));
|
||||
position.set(
|
||||
LOGICAL_AXIS_LIST(
|
||||
LROUND(e * settings.axis_steps_per_mm[E_AXIS_N(active_extruder)]),
|
||||
LROUND(a * settings.axis_steps_per_mm[A_AXIS]),
|
||||
LROUND(b * settings.axis_steps_per_mm[B_AXIS]),
|
||||
LROUND(c * settings.axis_steps_per_mm[C_AXIS])
|
||||
)
|
||||
);
|
||||
if (has_blocks_queued()) {
|
||||
//previous_nominal_speed_sqr = 0.0; // Reset planner junction speeds. Assume start from rest.
|
||||
//previous_speed.reset();
|
||||
@ -2983,11 +3019,11 @@ void Planner::set_machine_position_mm(const_float_t a, const_float_t b, const_fl
|
||||
stepper.set_position(position);
|
||||
}
|
||||
|
||||
void Planner::set_position_mm(const_float_t rx, const_float_t ry, const_float_t rz, const_float_t e) {
|
||||
xyze_pos_t machine = { rx, ry, rz, e };
|
||||
#if HAS_POSITION_MODIFIERS
|
||||
apply_modifiers(machine, true);
|
||||
#endif
|
||||
void Planner::set_position_mm(
|
||||
LOGICAL_AXIS_LIST(const_float_t e, const_float_t rx, const_float_t ry, const_float_t rz)
|
||||
) {
|
||||
xyze_pos_t machine = LOGICAL_AXIS_ARRAY(e, rx, ry, rz);
|
||||
TERN_(HAS_POSITION_MODIFIERS, apply_modifiers(machine, true));
|
||||
#if IS_KINEMATIC
|
||||
position_cart.set(rx, ry, rz, e);
|
||||
inverse_kinematics(machine);
|
||||
@ -2997,23 +3033,27 @@ void Planner::set_position_mm(const_float_t rx, const_float_t ry, const_float_t
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Setters for planner position (also setting stepper position).
|
||||
*/
|
||||
void Planner::set_e_position_mm(const_float_t e) {
|
||||
const uint8_t axis_index = E_AXIS_N(active_extruder);
|
||||
TERN_(DISTINCT_E_FACTORS, last_extruder = active_extruder);
|
||||
#if HAS_EXTRUDERS
|
||||
|
||||
const float e_new = DIFF_TERN(FWRETRACT, e, fwretract.current_retract[active_extruder]);
|
||||
position.e = LROUND(settings.axis_steps_per_mm[axis_index] * e_new);
|
||||
TERN_(HAS_POSITION_FLOAT, position_float.e = e_new);
|
||||
TERN_(IS_KINEMATIC, position_cart.e = e);
|
||||
/**
|
||||
* Setters for planner position (also setting stepper position).
|
||||
*/
|
||||
void Planner::set_e_position_mm(const_float_t e) {
|
||||
const uint8_t axis_index = E_AXIS_N(active_extruder);
|
||||
TERN_(DISTINCT_E_FACTORS, last_extruder = active_extruder);
|
||||
|
||||
if (has_blocks_queued())
|
||||
buffer_sync_block();
|
||||
else
|
||||
stepper.set_axis_position(E_AXIS, position.e);
|
||||
}
|
||||
const float e_new = DIFF_TERN(FWRETRACT, e, fwretract.current_retract[active_extruder]);
|
||||
position.e = LROUND(settings.axis_steps_per_mm[axis_index] * e_new);
|
||||
TERN_(HAS_POSITION_FLOAT, position_float.e = e_new);
|
||||
TERN_(IS_KINEMATIC, position_cart.e = e);
|
||||
|
||||
if (has_blocks_queued())
|
||||
buffer_sync_block();
|
||||
else
|
||||
stepper.set_axis_position(E_AXIS, position.e);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Recalculate the steps/s^2 acceleration rates, based on the mm/s^2
|
||||
void Planner::reset_acceleration_rates() {
|
||||
@ -3043,11 +3083,11 @@ void Planner::refresh_positioning() {
|
||||
|
||||
// Apply limits to a variable and give a warning if the value was out of range
|
||||
inline void limit_and_warn(float &val, const uint8_t axis, PGM_P const setting_name, const xyze_float_t &max_limit) {
|
||||
const uint8_t lim_axis = axis > E_AXIS ? E_AXIS : axis;
|
||||
const uint8_t lim_axis = TERN_(HAS_EXTRUDERS, axis > E_AXIS ? E_AXIS :) axis;
|
||||
const float before = val;
|
||||
LIMIT(val, 0.1, max_limit[lim_axis]);
|
||||
if (before != val) {
|
||||
SERIAL_CHAR(axis_codes[lim_axis]);
|
||||
SERIAL_CHAR(AXIS_CHAR(lim_axis));
|
||||
SERIAL_ECHOPGM(" Max ");
|
||||
SERIAL_ECHOPGM_P(setting_name);
|
||||
SERIAL_ECHOLNPAIR(" limited to ", val);
|
||||
|
@ -76,7 +76,7 @@
|
||||
// Feedrate for manual moves
|
||||
#ifdef MANUAL_FEEDRATE
|
||||
constexpr xyze_feedrate_t _mf = MANUAL_FEEDRATE,
|
||||
manual_feedrate_mm_s { _mf.x / 60.0f, _mf.y / 60.0f, _mf.z / 60.0f, _mf.e / 60.0f };
|
||||
manual_feedrate_mm_s = LOGICAL_AXIS_ARRAY(_mf.e / 60.0f, _mf.x / 60.0f, _mf.y / 60.0f, _mf.z / 60.0f);
|
||||
#endif
|
||||
|
||||
#if IS_KINEMATIC && HAS_JUNCTION_DEVIATION
|
||||
@ -758,7 +758,8 @@ class Planner {
|
||||
* extruder - target extruder
|
||||
* millimeters - the length of the movement, if known
|
||||
*/
|
||||
static bool buffer_segment(const_float_t a, const_float_t b, const_float_t c, const_float_t e
|
||||
static bool buffer_segment(
|
||||
LOGICAL_AXIS_LIST(const_float_t e, const_float_t a, const_float_t b, const_float_t c)
|
||||
OPTARG(HAS_DIST_MM_ARG, const xyze_float_t &cart_dist_mm)
|
||||
, const_feedRate_t fr_mm_s, const uint8_t extruder, const_float_t millimeters=0.0
|
||||
);
|
||||
@ -767,9 +768,11 @@ class Planner {
|
||||
OPTARG(HAS_DIST_MM_ARG, const xyze_float_t &cart_dist_mm)
|
||||
, const_feedRate_t fr_mm_s, const uint8_t extruder, const_float_t millimeters=0.0
|
||||
) {
|
||||
return buffer_segment(abce.a, abce.b, abce.c, abce.e
|
||||
return buffer_segment(
|
||||
LOGICAL_AXIS_LIST(abce.e, abce.a, abce.b, abce.c)
|
||||
OPTARG(HAS_DIST_MM_ARG, cart_dist_mm)
|
||||
, fr_mm_s, extruder, millimeters);
|
||||
, fr_mm_s, extruder, millimeters
|
||||
);
|
||||
}
|
||||
|
||||
public:
|
||||
@ -785,14 +788,18 @@ class Planner {
|
||||
* millimeters - the length of the movement, if known
|
||||
* inv_duration - the reciprocal if the duration of the movement, if known (kinematic only if feeedrate scaling is enabled)
|
||||
*/
|
||||
static bool buffer_line(const_float_t rx, const_float_t ry, const_float_t rz, const_float_t e, const_feedRate_t fr_mm_s, const uint8_t extruder, const float millimeters=0.0
|
||||
static bool buffer_line(
|
||||
LOGICAL_AXIS_LIST(const_float_t e, const_float_t rx, const_float_t ry, const_float_t rz)
|
||||
, const feedRate_t &fr_mm_s, const uint8_t extruder, const float millimeters=0.0
|
||||
OPTARG(SCARA_FEEDRATE_SCALING, const_float_t inv_duration=0.0)
|
||||
);
|
||||
|
||||
FORCE_INLINE static bool buffer_line(const xyze_pos_t &cart, const_feedRate_t fr_mm_s, const uint8_t extruder, const float millimeters=0.0
|
||||
OPTARG(SCARA_FEEDRATE_SCALING, const_float_t inv_duration=0.0)
|
||||
) {
|
||||
return buffer_line(cart.x, cart.y, cart.z, cart.e, fr_mm_s, extruder, millimeters
|
||||
return buffer_line(
|
||||
LOGICAL_AXIS_LIST(cart.e, cart.x, cart.y, cart.z)
|
||||
, fr_mm_s, extruder, millimeters
|
||||
OPTARG(SCARA_FEEDRATE_SCALING, inv_duration)
|
||||
);
|
||||
}
|
||||
@ -814,9 +821,16 @@ class Planner {
|
||||
*
|
||||
* Clears previous speed values.
|
||||
*/
|
||||
static void set_position_mm(const_float_t rx, const_float_t ry, const_float_t rz, const_float_t e);
|
||||
FORCE_INLINE static void set_position_mm(const xyze_pos_t &cart) { set_position_mm(cart.x, cart.y, cart.z, cart.e); }
|
||||
static void set_e_position_mm(const_float_t e);
|
||||
static void set_position_mm(
|
||||
LOGICAL_AXIS_LIST(const_float_t e, const_float_t rx, const_float_t ry, const_float_t rz)
|
||||
);
|
||||
FORCE_INLINE static void set_position_mm(const xyze_pos_t &cart) {
|
||||
set_position_mm(LOGICAL_AXIS_LIST(cart.e, cart.x, cart.y, cart.z, cart.i, cart.j, cart.k));
|
||||
}
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
static void set_e_position_mm(const_float_t e);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set the planner.position and individual stepper positions.
|
||||
@ -824,8 +838,12 @@ class Planner {
|
||||
* The supplied position is in machine space, and no additional
|
||||
* conversions are applied.
|
||||
*/
|
||||
static void set_machine_position_mm(const_float_t a, const_float_t b, const_float_t c, const_float_t e);
|
||||
FORCE_INLINE static void set_machine_position_mm(const abce_pos_t &abce) { set_machine_position_mm(abce.a, abce.b, abce.c, abce.e); }
|
||||
static void set_machine_position_mm(
|
||||
LOGICAL_AXIS_LIST(const_float_t e, const_float_t a, const_float_t b, const_float_t c)
|
||||
);
|
||||
FORCE_INLINE static void set_machine_position_mm(const abce_pos_t &abce) {
|
||||
set_machine_position_mm(LOGICAL_AXIS_LIST(abce.e, abce.a, abce.b, abce.c));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an axis position according to stepper position(s)
|
||||
@ -834,12 +852,10 @@ class Planner {
|
||||
static float get_axis_position_mm(const AxisEnum axis);
|
||||
|
||||
static inline abce_pos_t get_axis_positions_mm() {
|
||||
const abce_pos_t out = {
|
||||
get_axis_position_mm(A_AXIS),
|
||||
get_axis_position_mm(B_AXIS),
|
||||
get_axis_position_mm(C_AXIS),
|
||||
get_axis_position_mm(E_AXIS)
|
||||
};
|
||||
const abce_pos_t out = LOGICAL_AXIS_ARRAY(
|
||||
get_axis_position_mm(E_AXIS),
|
||||
get_axis_position_mm(A_AXIS), get_axis_position_mm(B_AXIS), get_axis_position_mm(C_AXIS)
|
||||
);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -168,10 +168,10 @@
|
||||
void M554_report();
|
||||
#endif
|
||||
|
||||
typedef struct { uint16_t X, Y, Z, X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5, E6, E7; } tmc_stepper_current_t;
|
||||
typedef struct { uint32_t X, Y, Z, X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5, E6, E7; } tmc_hybrid_threshold_t;
|
||||
typedef struct { int16_t X, Y, Z, X2, Y2, Z2, Z3, Z4; } tmc_sgt_t;
|
||||
typedef struct { bool X, Y, Z, X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5, E6, E7; } tmc_stealth_enabled_t;
|
||||
typedef struct { uint16_t LINEAR_AXIS_LIST(X, Y, Z), X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5, E6, E7; } tmc_stepper_current_t;
|
||||
typedef struct { uint32_t LINEAR_AXIS_LIST(X, Y, Z), X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5, E6, E7; } tmc_hybrid_threshold_t;
|
||||
typedef struct { int16_t LINEAR_AXIS_LIST(X, Y, Z), X2, Y2, Z2, Z3, Z4; } tmc_sgt_t;
|
||||
typedef struct { bool LINEAR_AXIS_LIST(X, Y, Z), X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5, E6, E7; } tmc_stealth_enabled_t;
|
||||
|
||||
// Limit an index to an array size
|
||||
#define ALIM(I,ARR) _MIN(I, (signed)COUNT(ARR) - 1)
|
||||
@ -654,7 +654,7 @@ void MarlinSettings::postprocess() {
|
||||
EEPROM_WRITE(dummyf);
|
||||
#endif
|
||||
#else
|
||||
const xyze_pos_t planner_max_jerk = { 10, 10, 0.4, float(DEFAULT_EJERK) };
|
||||
const xyze_pos_t planner_max_jerk = LOGICAL_AXIS_ARRAY(float(DEFAULT_EJERK), 10, 10, 0.4);
|
||||
EEPROM_WRITE(planner_max_jerk);
|
||||
#endif
|
||||
|
||||
@ -1188,10 +1188,10 @@ void MarlinSettings::postprocess() {
|
||||
#endif
|
||||
#else
|
||||
const tmc_hybrid_threshold_t tmc_hybrid_threshold = {
|
||||
.X = 100, .Y = 100, .Z = 3,
|
||||
LINEAR_AXIS_LIST(.X = 100, .Y = 100, .Z = 3),
|
||||
.X2 = 100, .Y2 = 100, .Z2 = 3, .Z3 = 3, .Z4 = 3,
|
||||
.E0 = 30, .E1 = 30, .E2 = 30,
|
||||
.E3 = 30, .E4 = 30, .E5 = 30
|
||||
.E0 = 30, .E1 = 30, .E2 = 30, .E3 = 30,
|
||||
.E4 = 30, .E5 = 30, .E6 = 30, .E7 = 30
|
||||
};
|
||||
#endif
|
||||
EEPROM_WRITE(tmc_hybrid_threshold);
|
||||
@ -2604,7 +2604,7 @@ void MarlinSettings::reset() {
|
||||
#ifndef DEFAULT_ZJERK
|
||||
#define DEFAULT_ZJERK 0
|
||||
#endif
|
||||
planner.max_jerk.set(DEFAULT_XJERK, DEFAULT_YJERK, DEFAULT_ZJERK);
|
||||
planner.max_jerk.set(LINEAR_AXIS_LIST(DEFAULT_XJERK, DEFAULT_YJERK, DEFAULT_ZJERK));
|
||||
TERN_(HAS_CLASSIC_E_JERK, planner.max_jerk.e = DEFAULT_EJERK;);
|
||||
#endif
|
||||
|
||||
@ -3142,10 +3142,12 @@ void MarlinSettings::reset() {
|
||||
CONFIG_ECHO_HEADING("Maximum feedrates (units/s):");
|
||||
CONFIG_ECHO_START();
|
||||
SERIAL_ECHOLNPAIR_P(
|
||||
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])
|
||||
#if DISABLED(DISTINCT_E_FACTORS)
|
||||
LIST_N(DOUBLE(LINEAR_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])
|
||||
)
|
||||
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
|
||||
, SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_feedrate_mm_s[E_AXIS])
|
||||
#endif
|
||||
);
|
||||
@ -3162,10 +3164,12 @@ void MarlinSettings::reset() {
|
||||
CONFIG_ECHO_HEADING("Maximum Acceleration (units/s2):");
|
||||
CONFIG_ECHO_START();
|
||||
SERIAL_ECHOLNPAIR_P(
|
||||
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])
|
||||
#if DISABLED(DISTINCT_E_FACTORS)
|
||||
LIST_N(DOUBLE(LINEAR_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])
|
||||
)
|
||||
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
|
||||
, SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_acceleration_mm_per_s2[E_AXIS])
|
||||
#endif
|
||||
);
|
||||
@ -3894,9 +3898,11 @@ void MarlinSettings::reset() {
|
||||
CONFIG_ECHO_START();
|
||||
SERIAL_ECHOLNPAIR_P(
|
||||
PSTR(" M425 F"), backlash.get_correction()
|
||||
, SP_X_STR, LINEAR_UNIT(backlash.distance_mm.x)
|
||||
, SP_Y_STR, LINEAR_UNIT(backlash.distance_mm.y)
|
||||
, SP_Z_STR, LINEAR_UNIT(backlash.distance_mm.z)
|
||||
, LIST_N(DOUBLE(LINEAR_AXES),
|
||||
SP_X_STR, LINEAR_UNIT(backlash.distance_mm.x),
|
||||
SP_Y_STR, LINEAR_UNIT(backlash.distance_mm.y),
|
||||
SP_Z_STR, LINEAR_UNIT(backlash.distance_mm.z)
|
||||
)
|
||||
#ifdef BACKLASH_SMOOTHING_MM
|
||||
, PSTR(" S"), LINEAR_UNIT(backlash.smoothing_mm)
|
||||
#endif
|
||||
|
@ -498,7 +498,7 @@ void Stepper::set_directions() {
|
||||
MIXER_STEPPER_LOOP(j) NORM_E_DIR(j);
|
||||
count_direction.e = 1;
|
||||
}
|
||||
#else
|
||||
#elif HAS_EXTRUDERS
|
||||
if (motor_direction(E_AXIS)) {
|
||||
REV_E_DIR(stepper_extruder);
|
||||
count_direction.e = -1;
|
||||
@ -1627,7 +1627,7 @@ void Stepper::pulse_phase_isr() {
|
||||
PAGE_PULSE_PREP(X);
|
||||
PAGE_PULSE_PREP(Y);
|
||||
PAGE_PULSE_PREP(Z);
|
||||
PAGE_PULSE_PREP(E);
|
||||
TERN_(HAS_EXTRUDERS, PAGE_PULSE_PREP(E));
|
||||
|
||||
page_step_state.segment_steps++;
|
||||
|
||||
@ -1660,7 +1660,7 @@ void Stepper::pulse_phase_isr() {
|
||||
PAGE_PULSE_PREP(X);
|
||||
PAGE_PULSE_PREP(Y);
|
||||
PAGE_PULSE_PREP(Z);
|
||||
PAGE_PULSE_PREP(E);
|
||||
TERN_(HAS_EXTRUDERS, PAGE_PULSE_PREP(E));
|
||||
|
||||
page_step_state.segment_steps++;
|
||||
|
||||
@ -2103,13 +2103,15 @@ uint32_t Stepper::block_phase_isr() {
|
||||
#endif
|
||||
|
||||
uint8_t axis_bits = 0;
|
||||
if (X_MOVE_TEST) SBI(axis_bits, A_AXIS);
|
||||
if (Y_MOVE_TEST) SBI(axis_bits, B_AXIS);
|
||||
if (Z_MOVE_TEST) SBI(axis_bits, C_AXIS);
|
||||
//if (!!current_block->steps.e) SBI(axis_bits, E_AXIS);
|
||||
//if (!!current_block->steps.a) SBI(axis_bits, X_HEAD);
|
||||
//if (!!current_block->steps.b) SBI(axis_bits, Y_HEAD);
|
||||
//if (!!current_block->steps.c) SBI(axis_bits, Z_HEAD);
|
||||
LINEAR_AXIS_CODE(
|
||||
if (X_MOVE_TEST) SBI(axis_bits, A_AXIS),
|
||||
if (Y_MOVE_TEST) SBI(axis_bits, B_AXIS),
|
||||
if (Z_MOVE_TEST) SBI(axis_bits, C_AXIS)
|
||||
);
|
||||
//if (current_block->steps.e) SBI(axis_bits, E_AXIS);
|
||||
//if (current_block->steps.a) SBI(axis_bits, X_HEAD);
|
||||
//if (current_block->steps.b) SBI(axis_bits, Y_HEAD);
|
||||
//if (current_block->steps.c) SBI(axis_bits, Z_HEAD);
|
||||
axis_did_move = axis_bits;
|
||||
|
||||
// No acceleration / deceleration time elapsed so far
|
||||
@ -2606,9 +2608,13 @@ void Stepper::init() {
|
||||
#endif
|
||||
|
||||
// Init direction bits for first moves
|
||||
set_directions((INVERT_X_DIR ? _BV(X_AXIS) : 0)
|
||||
| (INVERT_Y_DIR ? _BV(Y_AXIS) : 0)
|
||||
| (INVERT_Z_DIR ? _BV(Z_AXIS) : 0));
|
||||
set_directions(0
|
||||
LINEAR_AXIS_GANG(
|
||||
| TERN0(INVERT_X_DIR, _BV(X_AXIS)),
|
||||
| TERN0(INVERT_Y_DIR, _BV(Y_AXIS)),
|
||||
| TERN0(INVERT_Z_DIR, _BV(Z_AXIS))
|
||||
)
|
||||
);
|
||||
|
||||
#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
|
||||
initialized = true;
|
||||
@ -2625,7 +2631,9 @@ void Stepper::init() {
|
||||
* This allows get_axis_position_mm to correctly
|
||||
* derive the current XYZ position later on.
|
||||
*/
|
||||
void Stepper::_set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e) {
|
||||
void Stepper::_set_position(
|
||||
LOGICAL_AXIS_LIST(const int32_t &e, const int32_t &a, const int32_t &b, const int32_t &c)
|
||||
) {
|
||||
#if CORE_IS_XY
|
||||
// corexy positioning
|
||||
// these equations follow the form of the dA and dB equations on https://www.corexy.com/theory.html
|
||||
@ -2640,9 +2648,9 @@ void Stepper::_set_position(const int32_t &a, const int32_t &b, const int32_t &c
|
||||
count_position.set(a - b, b, c);
|
||||
#else
|
||||
// default non-h-bot planning
|
||||
count_position.set(a, b, c);
|
||||
count_position.set(LINEAR_AXIS_LIST(a, b, c));
|
||||
#endif
|
||||
count_position.e = e;
|
||||
TERN_(HAS_EXTRUDERS, count_position.e = e);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2665,10 +2673,13 @@ int32_t Stepper::position(const AxisEnum axis) {
|
||||
}
|
||||
|
||||
// Set the current position in steps
|
||||
void Stepper::set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e) {
|
||||
//TODO: Test for LINEAR_AXES >= 4
|
||||
void Stepper::set_position(
|
||||
LOGICAL_AXIS_LIST(const int32_t &e, const int32_t &a, const int32_t &b, const int32_t &c)
|
||||
) {
|
||||
planner.synchronize();
|
||||
const bool was_enabled = suspend();
|
||||
_set_position(a, b, c, e);
|
||||
_set_position(LOGICAL_AXIS_LIST(e, a, b, c));
|
||||
if (was_enabled) wake_up();
|
||||
}
|
||||
|
||||
@ -2743,10 +2754,11 @@ void Stepper::report_a_position(const xyz_long_t &pos) {
|
||||
SERIAL_ECHOPAIR_P(PSTR(STR_COUNT_X), pos.x, SP_Y_LBL, pos.y);
|
||||
#endif
|
||||
#if ANY(CORE_IS_XZ, CORE_IS_YZ, DELTA)
|
||||
SERIAL_ECHOLNPAIR(" C:", pos.z);
|
||||
#else
|
||||
SERIAL_ECHOLNPAIR_P(SP_Z_LBL, pos.z);
|
||||
SERIAL_ECHOPAIR(" C:", pos.z);
|
||||
#elif LINEAR_AXES >= 3
|
||||
SERIAL_ECHOPAIR_P(SP_Z_LBL, pos.z);
|
||||
#endif
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
void Stepper::report_positions() {
|
||||
@ -2903,7 +2915,7 @@ void Stepper::report_positions() {
|
||||
|
||||
DIR_WAIT_BEFORE();
|
||||
|
||||
const xyz_byte_t old_dir = { X_DIR_READ(), Y_DIR_READ(), Z_DIR_READ() };
|
||||
const xyz_byte_t old_dir = LINEAR_AXIS_ARRAY(X_DIR_READ(), Y_DIR_READ(), Z_DIR_READ());
|
||||
|
||||
X_DIR_WRITE(INVERT_X_DIR ^ z_direction);
|
||||
Y_DIR_WRITE(INVERT_Y_DIR ^ z_direction);
|
||||
|
@ -433,8 +433,12 @@ class Stepper {
|
||||
static int32_t position(const AxisEnum axis);
|
||||
|
||||
// Set the current position in steps
|
||||
static void set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e);
|
||||
static inline void set_position(const xyze_long_t &abce) { set_position(abce.a, abce.b, abce.c, abce.e); }
|
||||
static void set_position(
|
||||
LOGICAL_AXIS_LIST(const int32_t &e, const int32_t &a, const int32_t &b, const int32_t &c)
|
||||
);
|
||||
static inline void set_position(const xyze_long_t &abce) {
|
||||
set_position(LOGICAL_AXIS_LIST(abce.e, abce.a, abce.b, abce.c));
|
||||
}
|
||||
static void set_axis_position(const AxisEnum a, const int32_t &v);
|
||||
|
||||
// Report the positions of the steppers, in steps
|
||||
@ -530,8 +534,12 @@ class Stepper {
|
||||
private:
|
||||
|
||||
// Set the current position in steps
|
||||
static void _set_position(const int32_t &a, const int32_t &b, const int32_t &c, const int32_t &e);
|
||||
FORCE_INLINE static void _set_position(const abce_long_t &spos) { _set_position(spos.a, spos.b, spos.c, spos.e); }
|
||||
static void _set_position(
|
||||
LOGICAL_AXIS_LIST(const int32_t &e, const int32_t &a, const int32_t &b, const int32_t &c)
|
||||
);
|
||||
FORCE_INLINE static void _set_position(const abce_long_t &spos) {
|
||||
_set_position(LOGICAL_AXIS_LIST(spos.e, spos.a, spos.b, spos.c));
|
||||
}
|
||||
|
||||
FORCE_INLINE static uint32_t calc_timer_interval(uint32_t step_rate, uint8_t *loops) {
|
||||
uint32_t timer;
|
||||
|
@ -35,7 +35,9 @@
|
||||
#include <HardwareSerial.h>
|
||||
#include <SPI.h>
|
||||
|
||||
enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E };
|
||||
enum StealthIndex : uint8_t {
|
||||
LOGICAL_AXIS_LIST(STEALTH_AXIS_E, STEALTH_AXIS_X, STEALTH_AXIS_Y, STEALTH_AXIS_Z)
|
||||
};
|
||||
#define TMC_INIT(ST, STEALTH_INDEX) tmc_init(stepper##ST, ST##_CURRENT, ST##_MICROSTEPS, ST##_HYBRID_THRESHOLD, stealthchop_by_axis[STEALTH_INDEX], chopper_timing_##ST, ST##_INTERPOLATE)
|
||||
|
||||
// IC = TMC model number
|
||||
@ -400,7 +402,7 @@ enum StealthIndex : uint8_t { STEALTH_AXIS_XY, STEALTH_AXIS_Z, STEALTH_AXIS_E };
|
||||
#endif
|
||||
#endif
|
||||
|
||||
enum TMCAxis : uint8_t { X, Y, Z, X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5, E6, E7, TOTAL };
|
||||
enum TMCAxis : uint8_t { LINEAR_AXIS_LIST(X, Y, Z), X2, Y2, Z2, Z3, Z4, E0, E1, E2, E3, E4, E5, E6, E7, TOTAL };
|
||||
|
||||
void tmc_serial_begin() {
|
||||
#if HAS_TMC_HW_SERIAL
|
||||
@ -765,19 +767,24 @@ void restore_trinamic_drivers() {
|
||||
}
|
||||
|
||||
void reset_trinamic_drivers() {
|
||||
static constexpr bool stealthchop_by_axis[] = { ENABLED(STEALTHCHOP_XY), ENABLED(STEALTHCHOP_Z), ENABLED(STEALTHCHOP_E) };
|
||||
static constexpr bool stealthchop_by_axis[] = LOGICAL_AXIS_ARRAY(
|
||||
ENABLED(STEALTHCHOP_E),
|
||||
ENABLED(STEALTHCHOP_XY),
|
||||
ENABLED(STEALTHCHOP_XY),
|
||||
ENABLED(STEALTHCHOP_Z)
|
||||
);
|
||||
|
||||
#if AXIS_IS_TMC(X)
|
||||
TMC_INIT(X, STEALTH_AXIS_XY);
|
||||
TMC_INIT(X, STEALTH_AXIS_X);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(X2)
|
||||
TMC_INIT(X2, STEALTH_AXIS_XY);
|
||||
TMC_INIT(X2, STEALTH_AXIS_X);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Y)
|
||||
TMC_INIT(Y, STEALTH_AXIS_XY);
|
||||
TMC_INIT(Y, STEALTH_AXIS_Y);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Y2)
|
||||
TMC_INIT(Y2, STEALTH_AXIS_XY);
|
||||
TMC_INIT(Y2, STEALTH_AXIS_Y);
|
||||
#endif
|
||||
#if AXIS_IS_TMC(Z)
|
||||
TMC_INIT(Z, STEALTH_AXIS_Z);
|
||||
@ -841,7 +848,7 @@ void reset_trinamic_drivers() {
|
||||
stepperZ4.homing_threshold(CAT(TERN(Z4_SENSORLESS, Z4, Z), _STALL_SENSITIVITY));
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif // USE SENSORLESS
|
||||
|
||||
#ifdef TMC_ADV
|
||||
TMC_ADV()
|
||||
|
@ -171,10 +171,12 @@ exec_test $1 $2 "Azteeg X3 | Mixing Extruder (x5) | Gradient Mix | Greek" "$3"
|
||||
# Test Laser features with 12864 LCD
|
||||
#
|
||||
restore_configs
|
||||
opt_set MOTHERBOARD BOARD_RAMPS_14_EFB LCD_LANGUAGE en TEMP_SENSOR_COOLER 1 EXTRUDERS 0 TEMP_SENSOR_1 0 SERIAL_PORT_2 2 \
|
||||
opt_set MOTHERBOARD BOARD_RAMPS_14_EFB EXTRUDERS 0 LCD_LANGUAGE en TEMP_SENSOR_COOLER 1 TEMP_SENSOR_1 0 SERIAL_PORT_2 2 \
|
||||
DEFAULT_AXIS_STEPS_PER_UNIT '{ 80, 80, 400 }' \
|
||||
DEFAULT_MAX_FEEDRATE '{ 300, 300, 5 }' \
|
||||
DEFAULT_MAX_ACCELERATION '{ 3000, 3000, 100 }'
|
||||
DEFAULT_MAX_ACCELERATION '{ 3000, 3000, 100 }' \
|
||||
MANUAL_FEEDRATE '{ 50*60, 50*60, 4*60 }' \
|
||||
AXIS_RELATIVE_MODES '{ false, false, false }'
|
||||
opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER SDSUPPORT EEPROM_SETTINGS EEPROM_BOOT_SILENT EEPROM_AUTO_INIT \
|
||||
LASER_FEATURE AIR_EVACUATION AIR_EVACUATION_PIN AIR_ASSIST AIR_ASSIST_PIN LASER_COOLANT_FLOW_METER MEATPACK_ON_SERIAL_PORT_1
|
||||
|
||||
@ -184,10 +186,12 @@ exec_test $1 $2 "REPRAP MEGA2560 RAMPS | Laser Feature | Air Evacuation | Air As
|
||||
# Test Laser features with 44780 LCD
|
||||
#
|
||||
restore_configs
|
||||
opt_set MOTHERBOARD BOARD_RAMPS_14_EFB LCD_LANGUAGE en TEMP_SENSOR_COOLER 1 EXTRUDERS 0 TEMP_SENSOR_1 0 \
|
||||
opt_set MOTHERBOARD BOARD_RAMPS_14_EFB EXTRUDERS 0 LCD_LANGUAGE en TEMP_SENSOR_COOLER 1 TEMP_SENSOR_1 0 \
|
||||
DEFAULT_AXIS_STEPS_PER_UNIT '{ 80, 80, 400 }' \
|
||||
DEFAULT_MAX_FEEDRATE '{ 300, 300, 5 }' \
|
||||
DEFAULT_MAX_ACCELERATION '{ 3000, 3000, 100 }'
|
||||
DEFAULT_MAX_ACCELERATION '{ 3000, 3000, 100 }' \
|
||||
MANUAL_FEEDRATE '{ 50*60, 50*60, 4*60 }' \
|
||||
AXIS_RELATIVE_MODES '{ false, false, false }'
|
||||
opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT EEPROM_SETTINGS EEPROM_BOOT_SILENT EEPROM_AUTO_INIT \
|
||||
LASER_FEATURE AIR_EVACUATION AIR_EVACUATION_PIN AIR_ASSIST AIR_ASSIST_PIN LASER_COOLANT_FLOW_METER
|
||||
|
||||
|
@ -48,6 +48,7 @@ opt_set MOTHERBOARD BOARD_RAMBO \
|
||||
DEFAULT_AXIS_STEPS_PER_UNIT '{ 80, 80, 4000 }' \
|
||||
DEFAULT_MAX_FEEDRATE '{ 300, 300, 5 }' \
|
||||
DEFAULT_MAX_ACCELERATION '{ 3000, 3000, 100 }' \
|
||||
MANUAL_FEEDRATE '{ 50*60, 50*60, 4*60 }' \
|
||||
AXIS_RELATIVE_MODES '{ false, false, false }' \
|
||||
LEVEL_CORNERS_LEVELING_ORDER '{ LF, RF }'
|
||||
opt_enable USE_XMAX_PLUG USE_YMAX_PLUG USE_ZMAX_PLUG \
|
||||
@ -66,6 +67,7 @@ opt_set MOTHERBOARD BOARD_RAMBO EXTRUDERS 0 TEMP_SENSOR_BED 1 \
|
||||
DEFAULT_AXIS_STEPS_PER_UNIT '{ 80, 80, 4000 }' \
|
||||
DEFAULT_MAX_FEEDRATE '{ 300, 300, 5 }' \
|
||||
DEFAULT_MAX_ACCELERATION '{ 3000, 3000, 100 }' \
|
||||
MANUAL_FEEDRATE '{ 50*60, 50*60, 4*60 }' \
|
||||
AXIS_RELATIVE_MODES '{ false, false, false }'
|
||||
opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
|
||||
exec_test $1 $2 "Rambo heated bed only" "$3"
|
||||
|
Loading…
Reference in New Issue
Block a user