🧑‍💻 Other code patches

This commit is contained in:
Scott Lahteine 2024-01-30 18:36:32 -06:00
parent 108f0b0cf5
commit af6dac3d1d
123 changed files with 2872 additions and 2091 deletions

View File

@ -120,6 +120,10 @@
#define HAS_TMC220x 1 #define HAS_TMC220x 1
#endif #endif
#if HAS_DRIVER(TMC26X)
#define HAS_TMC26X 1
#endif
#define AXIS_IS_TMC(A) ( AXIS_DRIVER_TYPE(A,TMC2130) || AXIS_DRIVER_TYPE(A,TMC2160) \ #define AXIS_IS_TMC(A) ( AXIS_DRIVER_TYPE(A,TMC2130) || AXIS_DRIVER_TYPE(A,TMC2160) \
|| AXIS_DRIVER_TYPE(A,TMC2208) || AXIS_DRIVER_TYPE(A,TMC2209) \ || AXIS_DRIVER_TYPE(A,TMC2208) || AXIS_DRIVER_TYPE(A,TMC2209) \
|| AXIS_DRIVER_TYPE(A,TMC2660) \ || AXIS_DRIVER_TYPE(A,TMC2660) \
@ -184,10 +188,3 @@
#if ANY_AXIS_HAS(SPI) #if ANY_AXIS_HAS(SPI)
#define HAS_TMC_SPI 1 #define HAS_TMC_SPI 1
#endif #endif
//
// TMC26XX Stepper Drivers
//
#if HAS_DRIVER(TMC26X)
#define HAS_TMC26X 1
#endif

View File

@ -323,10 +323,12 @@
// //
// Endstop Names used by Endstops::report_states // Endstop Names used by Endstops::report_states
// //
#define STR_X_MIN "x_min" #if HAS_X_AXIS
#define STR_X_MAX "x_max" #define STR_X_MIN "x_min"
#define STR_X2_MIN "x2_min" #define STR_X_MAX "x_max"
#define STR_X2_MAX "x2_max" #define STR_X2_MIN "x2_min"
#define STR_X2_MAX "x2_max"
#endif
#if HAS_Y_AXIS #if HAS_Y_AXIS
#define STR_Y_MIN "y_min" #define STR_Y_MIN "y_min"

View File

@ -263,8 +263,12 @@
// Compiler flags -fno-signed-zeros -ffinite-math-only also cover 'f * 1.0', 'f - f', etc. // Compiler flags -fno-signed-zeros -ffinite-math-only also cover 'f * 1.0', 'f - f', etc.
#define PLUS_TERN0(O,A) _TERN(_ENA_1(O),,+ (A)) // OPTION ? '+ (A)' : '<nul>' #define PLUS_TERN0(O,A) _TERN(_ENA_1(O),,+ (A)) // OPTION ? '+ (A)' : '<nul>'
#define MINUS_TERN0(O,A) _TERN(_ENA_1(O),,- (A)) // OPTION ? '- (A)' : '<nul>' #define MINUS_TERN0(O,A) _TERN(_ENA_1(O),,- (A)) // OPTION ? '- (A)' : '<nul>'
#define MUL_TERN1(O,A) _TERN(_ENA_1(O),,* (A)) // OPTION ? '* (A)' : '<nul>'
#define DIV_TERN1(O,A) _TERN(_ENA_1(O),,/ (A)) // OPTION ? '/ (A)' : '<nul>'
#define SUM_TERN(O,B,A) ((B) PLUS_TERN0(O,A)) // ((B) (OPTION ? '+ (A)' : '<nul>')) #define SUM_TERN(O,B,A) ((B) PLUS_TERN0(O,A)) // ((B) (OPTION ? '+ (A)' : '<nul>'))
#define DIFF_TERN(O,B,A) ((B) MINUS_TERN0(O,A)) // ((B) (OPTION ? '- (A)' : '<nul>')) #define DIFF_TERN(O,B,A) ((B) MINUS_TERN0(O,A)) // ((B) (OPTION ? '- (A)' : '<nul>'))
#define MUL_TERN(O,B,A) ((B) MUL_TERN1(O,A)) // ((B) (OPTION ? '* (A)' : '<nul>'))
#define DIV_TERN(O,B,A) ((B) DIV_TERN1(O,A)) // ((B) (OPTION ? '/ (A)' : '<nul>'))
#define IF_ENABLED TERN_ #define IF_ENABLED TERN_
#define IF_DISABLED(O,A) TERN(O,,A) #define IF_DISABLED(O,A) TERN(O,,A)
@ -434,6 +438,8 @@
extern "C++" { extern "C++" {
// C++11 solution that is standards compliant. Return type is deduced automatically // C++11 solution that is standards compliant. Return type is deduced automatically
template <class N> static constexpr N _MIN(const N val) { return val; }
template <class N> static constexpr N _MAX(const N val) { return val; }
template <class L, class R> static constexpr auto _MIN(const L lhs, const R rhs) -> decltype(lhs + rhs) { template <class L, class R> static constexpr auto _MIN(const L lhs, const R rhs) -> decltype(lhs + rhs) {
return lhs < rhs ? lhs : rhs; return lhs < rhs ? lhs : rhs;
} }
@ -453,9 +459,9 @@
FORCE_INLINE constexpr T operator|(T x, T y) { return static_cast<T>(static_cast<int>(x) | static_cast<int>(y)); } \ FORCE_INLINE constexpr T operator|(T x, T y) { return static_cast<T>(static_cast<int>(x) | static_cast<int>(y)); } \
FORCE_INLINE constexpr T operator^(T x, T y) { return static_cast<T>(static_cast<int>(x) ^ static_cast<int>(y)); } \ FORCE_INLINE constexpr T operator^(T x, T y) { return static_cast<T>(static_cast<int>(x) ^ static_cast<int>(y)); } \
FORCE_INLINE constexpr T operator~(T x) { return static_cast<T>(~static_cast<int>(x)); } \ FORCE_INLINE constexpr T operator~(T x) { return static_cast<T>(~static_cast<int>(x)); } \
FORCE_INLINE T & operator&=(T &x, T y) { return x &= y; } \ FORCE_INLINE T & operator&=(T &x, T y) { x = x & y; return x; } \
FORCE_INLINE T & operator|=(T &x, T y) { return x |= y; } \ FORCE_INLINE T & operator|=(T &x, T y) { x = x | y; return x; } \
FORCE_INLINE T & operator^=(T &x, T y) { return x ^= y; } FORCE_INLINE T & operator^=(T &x, T y) { x = x ^ y; return x; }
// C++11 solution that is standard compliant. <type_traits> is not available on all platform // C++11 solution that is standard compliant. <type_traits> is not available on all platform
namespace Private { namespace Private {
@ -467,6 +473,39 @@
template <typename T, typename ... Args> struct first_type_of { typedef T type; }; template <typename T, typename ... Args> struct first_type_of { typedef T type; };
template <typename T> struct first_type_of<T> { typedef T type; }; template <typename T> struct first_type_of<T> { typedef T type; };
// remove const/volatile type qualifiers
template<typename T> struct remove_const { typedef T type; };
template<typename T> struct remove_const<T const> { typedef T type; };
template<typename T> struct remove_volatile { typedef T type; };
template<typename T> struct remove_volatile<T volatile> { typedef T type; };
template<typename T> struct remove_cv { typedef typename remove_const<typename remove_volatile<T>::type>::type type; };
// test if type is integral
template<typename> struct _is_integral { enum { value = false }; };
template<> struct _is_integral<unsigned char> { enum { value = true }; };
template<> struct _is_integral<unsigned short> { enum { value = true }; };
template<> struct _is_integral<unsigned int> { enum { value = true }; };
template<> struct _is_integral<unsigned long> { enum { value = true }; };
template<> struct _is_integral<unsigned long long> { enum { value = true }; };
template<> struct _is_integral<char> { enum { value = true }; };
template<> struct _is_integral<short> { enum { value = true }; };
template<> struct _is_integral<int> { enum { value = true }; };
template<> struct _is_integral<long> { enum { value = true }; };
template<> struct _is_integral<long long> { enum { value = true }; };
template<typename T> struct is_integral : public _is_integral<typename remove_cv<T>::type> {};
}
// enum type check and regression to its underlying integral.
namespace Private {
template<typename T> struct is_enum { enum { value = __is_enum(T) }; };
template<typename T, bool = is_enum<T>::value> struct _underlying_type { using type = __underlying_type(T); };
template<typename T> struct _underlying_type<T, false> { };
template<typename T> struct underlying_type : public _underlying_type<T> { };
} }
// C++11 solution using SFINAE to detect the existence of a member in a class at compile time. // C++11 solution using SFINAE to detect the existence of a member in a class at compile time.
@ -726,6 +765,19 @@
#define RREPEAT2_S(S,N,OP,V...) EVAL1024(_RREPEAT2(S,SUB##S(N),OP,V)) #define RREPEAT2_S(S,N,OP,V...) EVAL1024(_RREPEAT2(S,SUB##S(N),OP,V))
#define RREPEAT2(N,OP,V...) RREPEAT2_S(0,N,OP,V) #define RREPEAT2(N,OP,V...) RREPEAT2_S(0,N,OP,V)
// Emit a list of N OP(I) items with ascending counter.
#define _REPLIST(_RPT_I,_RPT_N,_RPT_OP) \
_RPT_OP(_RPT_I) \
IF_ELSE(SUB1(_RPT_N)) \
( , DEFER2(__REPLIST)()(ADD1(_RPT_I),SUB1(_RPT_N),_RPT_OP) ) \
( /* Do nothing */ )
#define __REPLIST() _REPLIST
// Repeat a macro, comma-separated, passing S...N-1.
#define REPLIST_S(S,N,OP) EVAL(_REPLIST(S,SUB##S(N),OP))
#define REPLIST(N,OP) REPLIST_S(0,N,OP)
#define REPLIST_1(N,OP) REPLIST_S(1,INCREMENT(N),OP)
// Call OP(A) with each item as an argument // Call OP(A) with each item as an argument
#define _MAP(_MAP_OP,A,V...) \ #define _MAP(_MAP_OP,A,V...) \
_MAP_OP(A) \ _MAP_OP(A) \

View File

@ -64,6 +64,9 @@ typedef const char Language_Str[];
#if NUM_LANGUAGES > 1 #if NUM_LANGUAGES > 1
#define HAS_MULTI_LANGUAGE 1 #define HAS_MULTI_LANGUAGE 1
#if HAS_MARLINUI_MENU
#define HAS_MENU_MULTI_LANGUAGE 1
#endif
#define GET_TEXT(MSG) ( \ #define GET_TEXT(MSG) ( \
ui.language == 4 ? GET_LANG(LCD_LANGUAGE_5)::MSG : \ ui.language == 4 ? GET_LANG(LCD_LANGUAGE_5)::MSG : \
ui.language == 3 ? GET_LANG(LCD_LANGUAGE_4)::MSG : \ ui.language == 3 ? GET_LANG(LCD_LANGUAGE_4)::MSG : \

View File

@ -27,7 +27,8 @@
#include "../feature/ethernet.h" #include "../feature/ethernet.h"
#endif #endif
uint8_t marlin_debug_flags = MARLIN_DEBUG_NONE; // Echo commands to the terminal by default in dev mode
uint8_t marlin_debug_flags = TERN(MARLIN_DEV_MODE, MARLIN_DEBUG_ECHO, MARLIN_DEBUG_NONE);
// Commonly-used strings in serial output // Commonly-used strings in serial output
PGMSTR(SP_A_STR, " A"); PGMSTR(SP_B_STR, " B"); PGMSTR(SP_C_STR, " C"); PGMSTR(SP_A_STR, " A"); PGMSTR(SP_B_STR, " B"); PGMSTR(SP_C_STR, " C");

View File

@ -125,8 +125,6 @@ extern uint8_t marlin_debug_flags;
#define SERIAL_IMPL SERIAL_LEAF_1 #define SERIAL_IMPL SERIAL_LEAF_1
#endif #endif
#define SERIAL_OUT(WHAT, V...) (void)SERIAL_IMPL.WHAT(V)
#define PORT_REDIRECT(p) _PORT_REDIRECT(1,p) #define PORT_REDIRECT(p) _PORT_REDIRECT(1,p)
#define PORT_RESTORE() _PORT_RESTORE(1) #define PORT_RESTORE() _PORT_RESTORE(1)
#define SERIAL_PORTMASK(P) SerialMask::from(P) #define SERIAL_PORTMASK(P) SerialMask::from(P)
@ -149,10 +147,8 @@ template <typename T>
void SERIAL_ECHO(T x) { SERIAL_IMPL.print(x); } void SERIAL_ECHO(T x) { SERIAL_IMPL.print(x); }
// Wrapper for ECHO commands to interpret a char // Wrapper for ECHO commands to interpret a char
typedef struct SerialChar { char c; SerialChar(char n) : c(n) { } } serial_char_t;
inline void SERIAL_ECHO(serial_char_t x) { SERIAL_IMPL.write(x.c); } inline void SERIAL_ECHO(serial_char_t x) { SERIAL_IMPL.write(x.c); }
#define AS_CHAR(C) serial_char_t(C) #define AS_DIGIT(n) C('0' + (n))
#define AS_DIGIT(C) AS_CHAR('0' + (C))
template <typename T> template <typename T>
void SERIAL_ECHOLN(T x) { SERIAL_IMPL.println(x); } void SERIAL_ECHOLN(T x) { SERIAL_IMPL.println(x); }

View File

@ -23,6 +23,8 @@
#include "../inc/MarlinConfigPre.h" #include "../inc/MarlinConfigPre.h"
#include <stddef.h> // for size_t
#if ENABLED(EMERGENCY_PARSER) #if ENABLED(EMERGENCY_PARSER)
#include "../feature/e_parser.h" #include "../feature/e_parser.h"
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -33,17 +33,17 @@ void safe_delay(millis_t ms); // Delay ensuring that temperatures are
inline void serial_delay(const millis_t) {} inline void serial_delay(const millis_t) {}
#endif #endif
#if (GRID_MAX_POINTS_X) && (GRID_MAX_POINTS_Y) #if GRID_MAX_POINTS
// 16x16 bit arrays // 16x16 bit arrays
template <int W, int H> template <int W, int H>
struct FlagBits { struct FlagBits {
typename IF<(W>8), uint16_t, uint8_t>::type bits[H]; bits_t(W) flags[H];
void fill() { memset(bits, 0xFF, sizeof(bits)); } void fill() { memset(flags, 0xFF, sizeof(flags)); }
void reset() { memset(bits, 0x00, sizeof(bits)); } void reset() { memset(flags, 0x00, sizeof(flags)); }
void unmark(const uint8_t x, const uint8_t y) { CBI(bits[y], x); } void unmark(const uint8_t x, const uint8_t y) { CBI(flags[y], x); }
void mark(const uint8_t x, const uint8_t y) { SBI(bits[y], x); } void mark(const uint8_t x, const uint8_t y) { SBI(flags[y], x); }
bool marked(const uint8_t x, const uint8_t y) { return TEST(bits[y], x); } bool marked(const uint8_t x, const uint8_t y) { return TEST(flags[y], x); }
inline void unmark(const xy_int8_t &xy) { unmark(xy.x, xy.y); } inline void unmark(const xy_int8_t &xy) { unmark(xy.x, xy.y); }
inline void mark(const xy_int8_t &xy) { mark(xy.x, xy.y); } inline void mark(const xy_int8_t &xy) { mark(xy.x, xy.y); }
inline bool marked(const xy_int8_t &xy) { return marked(xy.x, xy.y); } inline bool marked(const xy_int8_t &xy) { return marked(xy.x, xy.y); }

View File

@ -175,13 +175,13 @@ void LevelingBilinear::print_leveling_grid(const bed_mesh_t* _z_values/*=nullptr
xy_float_t LevelingBilinear::grid_factor_virt; xy_float_t LevelingBilinear::grid_factor_virt;
#define LINEAR_EXTRAPOLATION(E, I) ((E) * 2 - (I)) #define LINEAR_EXTRAPOLATION(E, I) ((E) * 2 - (I))
float LevelingBilinear::bed_level_virt_coord(const uint8_t x, const uint8_t y) { float LevelingBilinear::virt_coord(const uint8_t x, const uint8_t y) {
uint8_t ep = 0, ip = 1; uint8_t ep = 0, ip = 1;
if (x > (GRID_MAX_POINTS_X) + 1 || y > (GRID_MAX_POINTS_Y) + 1) { if (x > (GRID_MAX_POINTS_X) + 1 || y > (GRID_MAX_POINTS_Y) + 1) {
// The requested point requires extrapolating two points beyond the mesh. // The requested point requires extrapolating two points beyond the mesh.
// These values are only requested for the edges of the mesh, which are always an actual mesh point, // These values are only requested for the edges of the mesh, which are always an actual mesh point,
// and do not require interpolation. When interpolation is not needed, this "Mesh + 2" point is // and do not require interpolation. When interpolation is not needed, this "Mesh + 2" point is
// cancelled out in bed_level_virt_cmr and does not impact the result. Return 0.0 rather than // cancelled out in virt_cmr and does not impact the result. Return 0.0 rather than
// making this function more complex by extrapolating two points. // making this function more complex by extrapolating two points.
return 0.0; return 0.0;
} }
@ -197,8 +197,8 @@ void LevelingBilinear::print_leveling_grid(const bed_mesh_t* _z_values/*=nullptr
); );
else else
return LINEAR_EXTRAPOLATION( return LINEAR_EXTRAPOLATION(
bed_level_virt_coord(ep + 1, y), virt_coord(ep + 1, y),
bed_level_virt_coord(ip + 1, y) virt_coord(ip + 1, y)
); );
} }
if (!y || y == ABL_TEMP_POINTS_Y - 1) { if (!y || y == ABL_TEMP_POINTS_Y - 1) {
@ -213,14 +213,14 @@ void LevelingBilinear::print_leveling_grid(const bed_mesh_t* _z_values/*=nullptr
); );
else else
return LINEAR_EXTRAPOLATION( return LINEAR_EXTRAPOLATION(
bed_level_virt_coord(x, ep + 1), virt_coord(x, ep + 1),
bed_level_virt_coord(x, ip + 1) virt_coord(x, ip + 1)
); );
} }
return z_values[x - 1][y - 1]; return z_values[x - 1][y - 1];
} }
float LevelingBilinear::bed_level_virt_cmr(const float p[4], const uint8_t i, const float t) { float LevelingBilinear::virt_cmr(const float p[4], const uint8_t i, const float t) {
return ( return (
p[i-1] * -t * sq(1 - t) p[i-1] * -t * sq(1 - t)
+ p[i] * (2 - 5 * sq(t) + 3 * t * sq(t)) + p[i] * (2 - 5 * sq(t) + 3 * t * sq(t))
@ -229,18 +229,18 @@ void LevelingBilinear::print_leveling_grid(const bed_mesh_t* _z_values/*=nullptr
) * 0.5f; ) * 0.5f;
} }
float LevelingBilinear::bed_level_virt_2cmr(const uint8_t x, const uint8_t y, const_float_t tx, const_float_t ty) { float LevelingBilinear::virt_2cmr(const uint8_t x, const uint8_t y, const_float_t tx, const_float_t ty) {
float row[4], column[4]; float row[4], column[4];
for (uint8_t i = 0; i < 4; ++i) { for (uint8_t i = 0; i < 4; ++i) {
for (uint8_t j = 0; j < 4; ++j) { for (uint8_t j = 0; j < 4; ++j) {
column[j] = bed_level_virt_coord(i + x - 1, j + y - 1); column[j] = virt_coord(i + x - 1, j + y - 1);
} }
row[i] = bed_level_virt_cmr(column, 1, ty); row[i] = virt_cmr(column, 1, ty);
} }
return bed_level_virt_cmr(row, 1, tx); return virt_cmr(row, 1, tx);
} }
void LevelingBilinear::bed_level_virt_interpolate() { void LevelingBilinear::subdivide_mesh() {
grid_spacing_virt = grid_spacing / (BILINEAR_SUBDIVISIONS); grid_spacing_virt = grid_spacing / (BILINEAR_SUBDIVISIONS);
grid_factor_virt = grid_spacing_virt.reciprocal(); grid_factor_virt = grid_spacing_virt.reciprocal();
for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; ++y) for (uint8_t y = 0; y < GRID_MAX_POINTS_Y; ++y)
@ -250,7 +250,7 @@ void LevelingBilinear::print_leveling_grid(const bed_mesh_t* _z_values/*=nullptr
if ((ty && y == (GRID_MAX_POINTS_Y) - 1) || (tx && x == (GRID_MAX_POINTS_X) - 1)) if ((ty && y == (GRID_MAX_POINTS_Y) - 1) || (tx && x == (GRID_MAX_POINTS_X) - 1))
continue; continue;
z_values_virt[x * (BILINEAR_SUBDIVISIONS) + tx][y * (BILINEAR_SUBDIVISIONS) + ty] = z_values_virt[x * (BILINEAR_SUBDIVISIONS) + tx][y * (BILINEAR_SUBDIVISIONS) + ty] =
bed_level_virt_2cmr( virt_2cmr(
x + 1, x + 1,
y + 1, y + 1,
(float)tx / (BILINEAR_SUBDIVISIONS), (float)tx / (BILINEAR_SUBDIVISIONS),
@ -263,7 +263,7 @@ void LevelingBilinear::print_leveling_grid(const bed_mesh_t* _z_values/*=nullptr
// Refresh after other values have been updated // Refresh after other values have been updated
void LevelingBilinear::refresh_bed_level() { void LevelingBilinear::refresh_bed_level() {
TERN_(ABL_BILINEAR_SUBDIVISION, bed_level_virt_interpolate()); TERN_(ABL_BILINEAR_SUBDIVISION, subdivide_mesh());
cached_rel.x = cached_rel.y = -999.999; cached_rel.x = cached_rel.y = -999.999;
cached_g.x = cached_g.y = -99; cached_g.x = cached_g.y = -99;
} }

View File

@ -43,10 +43,10 @@ private:
static xy_pos_t grid_spacing_virt; static xy_pos_t grid_spacing_virt;
static xy_float_t grid_factor_virt; static xy_float_t grid_factor_virt;
static float bed_level_virt_coord(const uint8_t x, const uint8_t y); static float virt_coord(const uint8_t x, const uint8_t y);
static float bed_level_virt_cmr(const float p[4], const uint8_t i, const float t); static float virt_cmr(const float p[4], const uint8_t i, const float t);
static float bed_level_virt_2cmr(const uint8_t x, const uint8_t y, const_float_t tx, const_float_t ty); static float virt_2cmr(const uint8_t x, const uint8_t y, const_float_t tx, const_float_t ty);
static void bed_level_virt_interpolate(); static void subdivide_mesh();
#endif #endif
public: public:

View File

@ -110,7 +110,7 @@ void BDS_Leveling::process() {
} }
else { else {
babystep.set_mm(Z_AXIS, 0); //if (old_cur_z <= cur_z) Z_DIR_WRITE(!INVERT_Z_DIR); babystep.set_mm(Z_AXIS, 0); //if (old_cur_z <= cur_z) Z_DIR_WRITE(!INVERT_Z_DIR);
stepper.set_directions(); stepper.apply_directions();
} }
#endif #endif
old_cur_z = cur_z; old_cur_z = cur_z;
@ -119,7 +119,7 @@ void BDS_Leveling::process() {
//endstops.update(); //endstops.update();
} }
else else
stepper.set_directions(); stepper.apply_directions();
#if ENABLED(DEBUG_OUT_BD) #if ENABLED(DEBUG_OUT_BD)
SERIAL_ECHOLNPGM("BD:", tmp & 0x3FF, ", Z:", cur_z, "|", current_position.z); SERIAL_ECHOLNPGM("BD:", tmp & 0x3FF, ", Z:", cur_z, "|", current_position.z);
@ -150,7 +150,7 @@ void BDS_Leveling::process() {
if (config_state == -6) { if (config_state == -6) {
//BD_I2C_SENSOR.BD_i2c_write(1019); // begin calibrate //BD_I2C_SENSOR.BD_i2c_write(1019); // begin calibrate
//delay(1000); //delay(1000);
gcode.stepper_inactive_time = SEC_TO_MS(60 * 5); TERN_(HAS_DISABLE_IDLE_AXES, gcode.stepper_inactive_time = SEC_TO_MS(60 * 5));
gcode.process_subcommands_now(F("M17 Z")); gcode.process_subcommands_now(F("M17 Z"));
gcode.process_subcommands_now(F("G1 Z0.0")); gcode.process_subcommands_now(F("G1 Z0.0"));
z_pose = 0; z_pose = 0;

View File

@ -28,8 +28,8 @@
constexpr int8_t to_fix(int8_t v) { return v * 2; } constexpr int8_t to_fix(int8_t v) { return v * 2; }
constexpr int8_t to_int(int8_t v) { return v / 2; } constexpr int8_t to_int(int8_t v) { return v / 2; }
constexpr uint8_t log2(uint8_t n) { return (n > 1) ? 1 + log2(n >> 1) : 0; } constexpr uint8_t log2(uint8_t n) { return (n > 1) ? 1 + log2(uint8_t(n >> 1)) : 0; }
constexpr uint8_t order(uint8_t n) { return uint8_t(log2(n - 1)) + 1; } constexpr uint8_t order(uint8_t n) { return uint8_t(log2(uint8_t(n - 1))) + 1; }
constexpr uint8_t ord = order(_MAX(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y)); constexpr uint8_t ord = order(_MAX(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y));
constexpr uint8_t dim = _BV(ord); constexpr uint8_t dim = _BV(ord);

View File

@ -72,18 +72,18 @@ public:
static float get_mesh_x(const uint8_t i) { return index_to_xpos[i]; } static float get_mesh_x(const uint8_t i) { return index_to_xpos[i]; }
static float get_mesh_y(const uint8_t i) { return index_to_ypos[i]; } static float get_mesh_y(const uint8_t i) { return index_to_ypos[i]; }
static int8_t cell_index_x(const_float_t x) { static uint8_t cell_index_x(const_float_t x) {
int8_t cx = (x - (MESH_MIN_X)) * RECIPROCAL(MESH_X_DIST); int8_t cx = (x - (MESH_MIN_X)) * RECIPROCAL(MESH_X_DIST);
return constrain(cx, 0, GRID_MAX_CELLS_X - 1); return constrain(cx, 0, GRID_MAX_CELLS_X - 1);
} }
static int8_t cell_index_y(const_float_t y) { static uint8_t cell_index_y(const_float_t y) {
int8_t cy = (y - (MESH_MIN_Y)) * RECIPROCAL(MESH_Y_DIST); int8_t cy = (y - (MESH_MIN_Y)) * RECIPROCAL(MESH_Y_DIST);
return constrain(cy, 0, GRID_MAX_CELLS_Y - 1); return constrain(cy, 0, GRID_MAX_CELLS_Y - 1);
} }
static xy_int8_t cell_indexes(const_float_t x, const_float_t y) { static xy_uint8_t cell_indexes(const_float_t x, const_float_t y) {
return { cell_index_x(x), cell_index_y(y) }; return { cell_index_x(x), cell_index_y(y) };
} }
static xy_int8_t cell_indexes(const xy_pos_t &xy) { return cell_indexes(xy.x, xy.y); } static xy_uint8_t cell_indexes(const xy_pos_t &xy) { return cell_indexes(xy.x, xy.y); }
static int8_t probe_index_x(const_float_t x) { static int8_t probe_index_x(const_float_t x) {
int8_t px = (x - (MESH_MIN_X) + 0.5f * (MESH_X_DIST)) * RECIPROCAL(MESH_X_DIST); int8_t px = (x - (MESH_MIN_X) + 0.5f * (MESH_X_DIST)) * RECIPROCAL(MESH_X_DIST);
@ -107,7 +107,7 @@ public:
static float get_z_offset() { return z_offset; } static float get_z_offset() { return z_offset; }
static float get_z_correction(const xy_pos_t &pos) { static float get_z_correction(const xy_pos_t &pos) {
const xy_int8_t ind = cell_indexes(pos); const xy_uint8_t ind = cell_indexes(pos);
const float x1 = index_to_xpos[ind.x], x2 = index_to_xpos[ind.x+1], const float x1 = index_to_xpos[ind.x], x2 = index_to_xpos[ind.x+1],
y1 = index_to_ypos[ind.y], y2 = index_to_ypos[ind.y+1], y1 = index_to_ypos[ind.y], y2 = index_to_ypos[ind.y+1],
z1 = calc_z0(pos.x, x1, z_values[ind.x][ind.y ], x2, z_values[ind.x+1][ind.y ]), z1 = calc_z0(pos.x, x1, z_values[ind.x][ind.y ], x2, z_values[ind.x+1][ind.y ]),

View File

@ -48,8 +48,8 @@ struct mesh_index_pair;
typedef struct { typedef struct {
bool C_seen; bool C_seen;
int8_t KLS_storage_slot; int8_t KLS_storage_slot;
uint8_t R_repetition, grid_count_t R_repetition;
V_verbosity, uint8_t V_verbosity,
P_phase, P_phase,
T_map_type; T_map_type;
float B_shim_thickness, float B_shim_thickness,
@ -77,7 +77,6 @@ private:
static bool G29_parse_parameters() __O0; static bool G29_parse_parameters() __O0;
static void shift_mesh_height(); static void shift_mesh_height();
static void probe_entire_mesh(const xy_pos_t &near, const bool do_ubl_mesh_map, const bool stow_probe, const bool do_furthest) __O0; static void probe_entire_mesh(const xy_pos_t &near, const bool do_ubl_mesh_map, const bool stow_probe, const bool do_furthest) __O0;
static void tilt_mesh_based_on_3pts(const_float_t z1, const_float_t z2, const_float_t z3);
static void tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map); static void tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map);
static bool smart_fill_one(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir); static bool smart_fill_one(const uint8_t x, const uint8_t y, const int8_t xdir, const int8_t ydir);
static bool smart_fill_one(const xy_uint8_t &pos, const xy_uint8_t &dir) { static bool smart_fill_one(const xy_uint8_t &pos, const xy_uint8_t &dir) {
@ -141,26 +140,26 @@ public:
return FLOOR((y - (MESH_MIN_Y)) * RECIPROCAL(MESH_Y_DIST)); return FLOOR((y - (MESH_MIN_Y)) * RECIPROCAL(MESH_Y_DIST));
} }
static int8_t cell_index_x_valid(const_float_t x) { static bool cell_index_x_valid(const_float_t x) {
return WITHIN(cell_index_x_raw(x), 0, GRID_MAX_CELLS_X - 1); return WITHIN(cell_index_x_raw(x), 0, GRID_MAX_CELLS_X - 1);
} }
static int8_t cell_index_y_valid(const_float_t y) { static bool cell_index_y_valid(const_float_t y) {
return WITHIN(cell_index_y_raw(y), 0, GRID_MAX_CELLS_Y - 1); return WITHIN(cell_index_y_raw(y), 0, GRID_MAX_CELLS_Y - 1);
} }
static int8_t cell_index_x(const_float_t x) { static uint8_t cell_index_x(const_float_t x) {
return constrain(cell_index_x_raw(x), 0, GRID_MAX_CELLS_X - 1); return constrain(cell_index_x_raw(x), 0, GRID_MAX_CELLS_X - 1);
} }
static int8_t cell_index_y(const_float_t y) { static uint8_t cell_index_y(const_float_t y) {
return constrain(cell_index_y_raw(y), 0, GRID_MAX_CELLS_Y - 1); return constrain(cell_index_y_raw(y), 0, GRID_MAX_CELLS_Y - 1);
} }
static xy_int8_t cell_indexes(const_float_t x, const_float_t y) { static xy_uint8_t cell_indexes(const_float_t x, const_float_t y) {
return { cell_index_x(x), cell_index_y(y) }; return { cell_index_x(x), cell_index_y(y) };
} }
static xy_int8_t cell_indexes(const xy_pos_t &xy) { return cell_indexes(xy.x, xy.y); } static xy_uint8_t cell_indexes(const xy_pos_t &xy) { return cell_indexes(xy.x, xy.y); }
static int8_t closest_x_index(const_float_t x) { static int8_t closest_x_index(const_float_t x) {
const int8_t px = (x - (MESH_MIN_X) + (MESH_X_DIST) * 0.5) * RECIPROCAL(MESH_X_DIST); const int8_t px = (x - (MESH_MIN_X) + (MESH_X_DIST) * 0.5) * RECIPROCAL(MESH_X_DIST);

View File

@ -354,7 +354,7 @@ void unified_bed_leveling::G29() {
// Invalidate one or more nearby mesh points, possibly all. // Invalidate one or more nearby mesh points, possibly all.
if (parser.seen('I')) { if (parser.seen('I')) {
uint8_t count = parser.has_value() ? parser.value_byte() : 1; grid_count_t count = parser.has_value() ? parser.value_ushort() : 1;
bool invalidate_all = count >= GRID_MAX_POINTS; bool invalidate_all = count >= GRID_MAX_POINTS;
if (!invalidate_all) { if (!invalidate_all) {
while (count--) { while (count--) {
@ -762,14 +762,14 @@ void unified_bed_leveling::shift_mesh_height() {
TERN_(DWIN_LCD_PROUI, DWIN_LevelingStart()); TERN_(DWIN_LCD_PROUI, DWIN_LevelingStart());
save_ubl_active_state_and_disable(); // No bed level correction so only raw data is obtained save_ubl_active_state_and_disable(); // No bed level correction so only raw data is obtained
uint8_t count = GRID_MAX_POINTS; grid_count_t count = GRID_MAX_POINTS;
mesh_index_pair best; mesh_index_pair best;
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(best.pos, ExtUI::G29_START)); TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(best.pos, ExtUI::G29_START));
do { do {
if (do_ubl_mesh_map) display_map(param.T_map_type); if (do_ubl_mesh_map) display_map(param.T_map_type);
const uint8_t point_num = (GRID_MAX_POINTS - count) + 1; const grid_count_t point_num = (GRID_MAX_POINTS - count) + 1;
SERIAL_ECHOLNPGM("Probing mesh point ", point_num, "/", GRID_MAX_POINTS, "."); SERIAL_ECHOLNPGM("Probing mesh point ", point_num, "/", GRID_MAX_POINTS, ".");
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), point_num, int(GRID_MAX_POINTS))); TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), point_num, int(GRID_MAX_POINTS)));
@ -1141,7 +1141,7 @@ bool unified_bed_leveling::G29_parse_parameters() {
param.R_repetition = 0; param.R_repetition = 0;
if (parser.seen('R')) { if (parser.seen('R')) {
param.R_repetition = parser.has_value() ? parser.value_byte() : GRID_MAX_POINTS; param.R_repetition = parser.has_value() ? parser.value_ushort() : GRID_MAX_POINTS;
NOMORE(param.R_repetition, GRID_MAX_POINTS); NOMORE(param.R_repetition, GRID_MAX_POINTS);
if (param.R_repetition < 1) { if (param.R_repetition < 1) {
SERIAL_ECHOLNPGM("?(R)epetition count invalid (1+).\n"); SERIAL_ECHOLNPGM("?(R)epetition count invalid (1+).\n");
@ -1613,7 +1613,7 @@ void unified_bed_leveling::smart_fill_mesh() {
probe.move_z_after_probing(); probe.move_z_after_probing();
if (abort_flag || finish_incremental_LSF(&lsf_results)) { if (abort_flag || finish_incremental_LSF(&lsf_results)) {
SERIAL_ECHOPGM("Could not complete LSF!"); SERIAL_ECHOLNPGM("Could not complete LSF!");
return; return;
} }
@ -1747,7 +1747,7 @@ void unified_bed_leveling::smart_fill_mesh() {
} }
} }
if (finish_incremental_LSF(&lsf_results)) { if (finish_incremental_LSF(&lsf_results)) {
SERIAL_ECHOLNPGM("Insufficient data"); SERIAL_ECHOLNPGM(" Insufficient data");
return; return;
} }
const float ez = -lsf_results.D - lsf_results.A * ppos.x - lsf_results.B * ppos.y; const float ez = -lsf_results.D - lsf_results.A * ppos.x - lsf_results.B * ppos.y;
@ -1758,7 +1758,7 @@ void unified_bed_leveling::smart_fill_mesh() {
} }
} }
SERIAL_ECHOLNPGM("done"); SERIAL_ECHOLNPGM(" done.");
} }
#endif // UBL_G29_P31 #endif // UBL_G29_P31
@ -1771,10 +1771,9 @@ void unified_bed_leveling::smart_fill_mesh() {
report_state(); report_state();
if (storage_slot == -1) if (storage_slot == -1)
SERIAL_ECHOPGM("No Mesh Loaded."); SERIAL_ECHOLNPGM("No Mesh Loaded.");
else else
SERIAL_ECHOPGM("Mesh ", storage_slot, " Loaded."); SERIAL_ECHOLNPGM("Mesh ", storage_slot, " Loaded.");
SERIAL_EOL();
serial_delay(50); serial_delay(50);
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
@ -1819,15 +1818,14 @@ void unified_bed_leveling::smart_fill_mesh() {
SERIAL_EOL(); SERIAL_EOL();
serial_delay(50); serial_delay(50);
#if ENABLED(UBL_DEVEL_DEBUGGING)
SERIAL_ECHOLNPGM("ubl_state_at_invocation :", ubl_state_at_invocation, "\nubl_state_recursion_chk :", ubl_state_recursion_chk); SERIAL_ECHOLNPGM("ubl_state_at_invocation :", ubl_state_at_invocation, "\nubl_state_recursion_chk :", ubl_state_recursion_chk);
serial_delay(50); serial_delay(50);
SERIAL_ECHOLNPGM("Meshes go from ", hex_address((void*)settings.meshes_start_index()), " to ", hex_address((void*)settings.meshes_end_index())); SERIAL_ECHOLNPGM("Meshes go from ", hex_address((void*)settings.meshes_start_index()), " to ", hex_address((void*)settings.meshes_end_index()));
serial_delay(50); serial_delay(50);
SERIAL_ECHOLNPGM("sizeof(ubl) : ", sizeof(ubl)); SERIAL_EOL(); SERIAL_ECHOLNPGM("sizeof(unified_bed_leveling) : ", sizeof(unified_bed_leveling));
SERIAL_ECHOLNPGM("z_value[][] size: ", sizeof(z_values)); SERIAL_EOL(); SERIAL_ECHOLNPGM("z_value[][] size: ", sizeof(z_values));
serial_delay(25); serial_delay(25);
SERIAL_ECHOLNPGM("EEPROM free for UBL: ", hex_address((void*)(settings.meshes_end_index() - settings.meshes_start_index()))); SERIAL_ECHOLNPGM("EEPROM free for UBL: ", hex_address((void*)(settings.meshes_end_index() - settings.meshes_start_index())));
@ -1835,7 +1833,6 @@ void unified_bed_leveling::smart_fill_mesh() {
SERIAL_ECHOLNPGM("EEPROM can hold ", settings.calc_num_meshes(), " meshes.\n"); SERIAL_ECHOLNPGM("EEPROM can hold ", settings.calc_num_meshes(), " meshes.\n");
serial_delay(25); serial_delay(25);
#endif // UBL_DEVEL_DEBUGGING
if (!sanity_check()) { if (!sanity_check()) {
echo_name(); echo_name();
@ -1857,7 +1854,8 @@ void unified_bed_leveling::smart_fill_mesh() {
print_hex_word(i); print_hex_word(i);
SERIAL_ECHOPGM(": "); SERIAL_ECHOPGM(": ");
for (uint16_t j = 0; j < 16; j++) { for (uint16_t j = 0; j < 16; j++) {
persistentStore.read_data(i + j, &cccc, sizeof(uint8_t)); int pos = i + j;
persistentStore.read_data(pos, &cccc, sizeof(uint8_t));
print_hex_byte(cccc); print_hex_byte(cccc);
SERIAL_CHAR(' '); SERIAL_CHAR(' ');
} }

View File

@ -61,7 +61,7 @@
const xyze_pos_t &start = current_position, &end = destination; const xyze_pos_t &start = current_position, &end = destination;
#endif #endif
const xy_int8_t istart = cell_indexes(start), iend = cell_indexes(end); const xy_uint8_t istart = cell_indexes(start), iend = cell_indexes(end);
// A move within the same cell needs no splitting // A move within the same cell needs no splitting
if (istart == iend) { if (istart == iend) {
@ -108,7 +108,7 @@
const xy_float_t dist = end - start; const xy_float_t dist = end - start;
const xy_bool_t neg { dist.x < 0, dist.y < 0 }; const xy_bool_t neg { dist.x < 0, dist.y < 0 };
const xy_int8_t ineg { int8_t(neg.x), int8_t(neg.y) }; const xy_uint8_t ineg { uint8_t(neg.x), uint8_t(neg.y) };
const xy_float_t sign { neg.x ? -1.0f : 1.0f, neg.y ? -1.0f : 1.0f }; const xy_float_t sign { neg.x ? -1.0f : 1.0f, neg.y ? -1.0f : 1.0f };
const xy_int8_t iadd { int8_t(iend.x == istart.x ? 0 : sign.x), int8_t(iend.y == istart.y ? 0 : sign.y) }; const xy_int8_t iadd { int8_t(iend.x == istart.x ? 0 : sign.x), int8_t(iend.y == istart.y ? 0 : sign.y) };
@ -131,7 +131,7 @@
const bool inf_normalized_flag = isinf(e_normalized_dist); const bool inf_normalized_flag = isinf(e_normalized_dist);
#endif #endif
xy_int8_t icell = istart; xy_uint8_t icell = istart;
const float ratio = dist.y / dist.x, // Allow divide by zero const float ratio = dist.y / dist.x, // Allow divide by zero
c = start.y - ratio * start.x; c = start.y - ratio * start.x;
@ -252,7 +252,7 @@
* Generic case of a line crossing both X and Y Mesh lines. * Generic case of a line crossing both X and Y Mesh lines.
*/ */
xy_int8_t cnt = (istart - iend).ABS(); xy_uint8_t cnt = istart.diff(iend);
icell += ineg; icell += ineg;
@ -334,16 +334,14 @@
#else // UBL_SEGMENTED #else // UBL_SEGMENTED
#if IS_SCARA #if IS_SCARA
#define DELTA_SEGMENT_MIN_LENGTH 0.25 // SCARA minimum segment size is 0.25mm #define SEGMENT_MIN_LENGTH 0.25 // SCARA minimum segment size is 0.25mm
#elif ENABLED(DELTA) #elif IS_KINEMATIC
#define DELTA_SEGMENT_MIN_LENGTH 0.10 // mm (still subject to DEFAULT_SEGMENTS_PER_SECOND) #define SEGMENT_MIN_LENGTH 0.10 // (mm) Still subject to DEFAULT_SEGMENTS_PER_SECOND
#elif ENABLED(POLARGRAPH)
#define DELTA_SEGMENT_MIN_LENGTH 0.10 // mm (still subject to DEFAULT_SEGMENTS_PER_SECOND)
#else // CARTESIAN #else // CARTESIAN
#ifdef LEVELED_SEGMENT_LENGTH #ifdef LEVELED_SEGMENT_LENGTH
#define DELTA_SEGMENT_MIN_LENGTH LEVELED_SEGMENT_LENGTH #define SEGMENT_MIN_LENGTH LEVELED_SEGMENT_LENGTH
#else #else
#define DELTA_SEGMENT_MIN_LENGTH 1.00 // mm (similar to G2/G3 arc segmentation) #define SEGMENT_MIN_LENGTH 1.00 // (mm) Similar to G2/G3 arc segmentation
#endif #endif
#endif #endif
@ -366,10 +364,10 @@
#if IS_KINEMATIC #if IS_KINEMATIC
const float seconds = cart_xy_mm / scaled_fr_mm_s; // Duration of XY move at requested rate const float seconds = cart_xy_mm / scaled_fr_mm_s; // Duration of XY move at requested rate
uint16_t segments = LROUND(segments_per_second * seconds), // Preferred number of segments for distance @ feedrate uint16_t segments = LROUND(segments_per_second * seconds), // Preferred number of segments for distance @ feedrate
seglimit = LROUND(cart_xy_mm * RECIPROCAL(DELTA_SEGMENT_MIN_LENGTH)); // Number of segments at minimum segment length seglimit = LROUND(cart_xy_mm * RECIPROCAL(SEGMENT_MIN_LENGTH)); // Number of segments at minimum segment length
NOMORE(segments, seglimit); // Limit to minimum segment length (fewer segments) NOMORE(segments, seglimit); // Limit to minimum segment length (fewer segments)
#else #else
uint16_t segments = LROUND(cart_xy_mm * RECIPROCAL(DELTA_SEGMENT_MIN_LENGTH)); // Cartesian fixed segment length uint16_t segments = LROUND(cart_xy_mm * RECIPROCAL(SEGMENT_MIN_LENGTH)); // Cartesian fixed segment length
#endif #endif
NOLESS(segments, 1U); // Must have at least one segment NOLESS(segments, 1U); // Must have at least one segment

View File

@ -30,7 +30,7 @@
class CaseLight { class CaseLight {
public: public:
static bool on; static bool on;
#if ENABLED(CASELIGHT_USES_BRIGHTNESS) #if CASELIGHT_USES_BRIGHTNESS
static uint8_t brightness; static uint8_t brightness;
#endif #endif

View File

@ -38,6 +38,10 @@ uint8_t ControllerFan::speed;
const controllerFan_settings_t &ControllerFan::settings = controllerFan_defaults; const controllerFan_settings_t &ControllerFan::settings = controllerFan_defaults;
#endif #endif
#if ENABLED(FAN_SOFT_PWM)
uint8_t ControllerFan::soft_pwm_speed;
#endif
void ControllerFan::setup() { void ControllerFan::setup() {
SET_OUTPUT(CONTROLLER_FAN_PIN); SET_OUTPUT(CONTROLLER_FAN_PIN);
#ifdef CONTROLLER_FAN2_PIN #ifdef CONTROLLER_FAN2_PIN
@ -92,7 +96,7 @@ void ControllerFan::update() {
#endif #endif
#if ENABLED(FAN_SOFT_PWM) #if ENABLED(FAN_SOFT_PWM)
thermalManager.soft_pwm_controller_speed = speed; soft_pwm_speed = speed;
#else #else
if (PWM_PIN(CONTROLLER_FAN_PIN)) if (PWM_PIN(CONTROLLER_FAN_PIN))
hal.set_pwm_duty(pin_t(CONTROLLER_FAN_PIN), speed); hal.set_pwm_duty(pin_t(CONTROLLER_FAN_PIN), speed);

View File

@ -60,6 +60,9 @@ class ControllerFan {
#else #else
static const controllerFan_settings_t &settings; static const controllerFan_settings_t &settings;
#endif #endif
#if ENABLED(FAN_SOFT_PWM)
static uint8_t soft_pwm_speed;
#endif
static bool state() { return speed > 0; } static bool state() { return speed > 0; }
static void init() { reset(); } static void init() { reset(); }
static void reset() { TERN_(CONTROLLER_FAN_EDITABLE, settings = controllerFan_defaults); } static void reset() { TERN_(CONTROLLER_FAN_EDITABLE, settings = controllerFan_defaults); }

View File

@ -80,9 +80,6 @@ namespace DirectStepping {
static void set_page_state(const page_idx_t page_idx, const PageState page_state); static void set_page_state(const page_idx_t page_idx, const PageState page_state);
}; };
template<bool b, typename T, typename F> struct TypeSelector { typedef T type;} ;
template<typename T, typename F> struct TypeSelector<false, T, F> { typedef F type; };
template <int num_pages, int num_axes, int bits_segment, bool dir, int segments> template <int num_pages, int num_axes, int bits_segment, bool dir, int segments>
struct config_t { struct config_t {
static constexpr char CONTROL_CHAR = '!'; static constexpr char CONTROL_CHAR = '!';
@ -98,8 +95,8 @@ namespace DirectStepping {
static constexpr int TOTAL_STEPS = SEGMENT_STEPS * SEGMENTS; static constexpr int TOTAL_STEPS = SEGMENT_STEPS * SEGMENTS;
static constexpr int PAGE_SIZE = (AXIS_COUNT * BITS_SEGMENT * SEGMENTS) / 8; static constexpr int PAGE_SIZE = (AXIS_COUNT * BITS_SEGMENT * SEGMENTS) / 8;
typedef typename TypeSelector<(PAGE_SIZE>256), uint16_t, uint8_t>::type write_byte_idx_t; typedef uvalue_t(PAGE_SIZE - 1) write_byte_idx_t;
typedef typename TypeSelector<(PAGE_COUNT>256), uint16_t, uint8_t>::type page_idx_t; typedef uvalue_t(PAGE_COUNT - 1) page_idx_t;
}; };
template <uint8_t num_pages> template <uint8_t num_pages>

View File

@ -48,7 +48,7 @@ void I2CPositionEncoder::init(const uint8_t address, const AxisEnum axis) {
initialized = true; initialized = true;
SERIAL_ECHOLNPGM("Setting up encoder on ", AS_CHAR(AXIS_CHAR(encoderAxis)), " axis, addr = ", address); SERIAL_ECHOLNPGM("Setting up encoder on ", C(AXIS_CHAR(encoderAxis)), " axis, addr = ", address);
position = get_position(); position = get_position();
} }
@ -66,7 +66,7 @@ void I2CPositionEncoder::update() {
/* /*
if (trusted) { //commented out as part of the note below if (trusted) { //commented out as part of the note below
trusted = false; trusted = false;
SERIAL_ECHOLNPGM("Fault detected on ", AS_CHAR(AXIS_CHAR(encoderAxis)), " axis encoder. Disengaging error correction until module is trusted again."); SERIAL_ECHOLNPGM("Fault detected on ", C(AXIS_CHAR(encoderAxis)), " axis encoder. Disengaging error correction until module is trusted again.");
} }
*/ */
return; return;
@ -91,7 +91,7 @@ void I2CPositionEncoder::update() {
if (millis() - lastErrorTime > I2CPE_TIME_TRUSTED) { if (millis() - lastErrorTime > I2CPE_TIME_TRUSTED) {
trusted = true; trusted = true;
SERIAL_ECHOLNPGM("Untrusted encoder module on ", AS_CHAR(AXIS_CHAR(encoderAxis)), " axis has been fault-free for set duration, reinstating error correction."); SERIAL_ECHOLNPGM("Untrusted encoder module on ", C(AXIS_CHAR(encoderAxis)), " axis has been fault-free for set duration, reinstating error correction.");
//the encoder likely lost its place when the error occurred, so we'll reset and use the printer's //the encoder likely lost its place when the error occurred, so we'll reset and use the printer's
//idea of where it the axis is to re-initialize //idea of where it the axis is to re-initialize

View File

@ -261,32 +261,32 @@ class I2CPositionEncodersMgr {
static void report_error_count(const int8_t idx, const AxisEnum axis) { static void report_error_count(const int8_t idx, const AxisEnum axis) {
CHECK_IDX(); CHECK_IDX();
SERIAL_ECHOLNPGM("Error count on ", AS_CHAR(AXIS_CHAR(axis)), " axis is ", encoders[idx].get_error_count()); SERIAL_ECHOLNPGM("Error count on ", C(AXIS_CHAR(axis)), " axis is ", encoders[idx].get_error_count());
} }
static void reset_error_count(const int8_t idx, const AxisEnum axis) { static void reset_error_count(const int8_t idx, const AxisEnum axis) {
CHECK_IDX(); CHECK_IDX();
encoders[idx].set_error_count(0); encoders[idx].set_error_count(0);
SERIAL_ECHOLNPGM("Error count on ", AS_CHAR(AXIS_CHAR(axis)), " axis has been reset."); SERIAL_ECHOLNPGM("Error count on ", C(AXIS_CHAR(axis)), " axis has been reset.");
} }
static void enable_ec(const int8_t idx, const bool enabled, const AxisEnum axis) { static void enable_ec(const int8_t idx, const bool enabled, const AxisEnum axis) {
CHECK_IDX(); CHECK_IDX();
encoders[idx].set_ec_enabled(enabled); encoders[idx].set_ec_enabled(enabled);
SERIAL_ECHOPGM("Error correction on ", AS_CHAR(AXIS_CHAR(axis))); SERIAL_ECHOPGM("Error correction on ", C(AXIS_CHAR(axis)));
SERIAL_ECHO_TERNARY(encoders[idx].get_ec_enabled(), " axis is ", "en", "dis", "abled.\n"); SERIAL_ECHO_TERNARY(encoders[idx].get_ec_enabled(), " axis is ", "en", "dis", "abled.\n");
} }
static void set_ec_threshold(const int8_t idx, const float newThreshold, const AxisEnum axis) { static void set_ec_threshold(const int8_t idx, const float newThreshold, const AxisEnum axis) {
CHECK_IDX(); CHECK_IDX();
encoders[idx].set_ec_threshold(newThreshold); encoders[idx].set_ec_threshold(newThreshold);
SERIAL_ECHOLNPGM("Error correct threshold for ", AS_CHAR(AXIS_CHAR(axis)), " axis set to ", newThreshold, "mm."); SERIAL_ECHOLNPGM("Error correct threshold for ", C(AXIS_CHAR(axis)), " axis set to ", newThreshold, "mm.");
} }
static void get_ec_threshold(const int8_t idx, const AxisEnum axis) { static void get_ec_threshold(const int8_t idx, const AxisEnum axis) {
CHECK_IDX(); CHECK_IDX();
const float threshold = encoders[idx].get_ec_threshold(); const float threshold = encoders[idx].get_ec_threshold();
SERIAL_ECHOLNPGM("Error correct threshold for ", AS_CHAR(AXIS_CHAR(axis)), " axis is ", threshold, "mm."); SERIAL_ECHOLNPGM("Error correct threshold for ", C(AXIS_CHAR(axis)), " axis is ", threshold, "mm.");
} }
static int8_t idx_from_axis(const AxisEnum axis) { static int8_t idx_from_axis(const AxisEnum axis) {

View File

@ -67,7 +67,7 @@ public:
} }
// Convert raw measurement to mm // Convert raw measurement to mm
static float raw_to_mm(const uint16_t v) { return v * float(ADC_VREF) * RECIPROCAL(float(MAX_RAW_THERMISTOR_VALUE)); } static float raw_to_mm(const uint16_t v) { return v * (float(ADC_VREF_MV) / 1000.0f) * RECIPROCAL(float(MAX_RAW_THERMISTOR_VALUE)); }
static float raw_to_mm() { return raw_to_mm(raw); } static float raw_to_mm() { return raw_to_mm(raw); }
// A scaled reading is ready // A scaled reading is ready

View File

@ -37,7 +37,7 @@
#include "../module/planner.h" #include "../module/planner.h"
#include "../lcd/marlinui.h" #include "../lcd/marlinui.h"
extern HotendIdleProtection hotend_idle; HotendIdleProtection hotend_idle;
millis_t HotendIdleProtection::next_protect_ms = 0; millis_t HotendIdleProtection::next_protect_ms = 0;

View File

@ -95,7 +95,62 @@ void LEDLights::setup() {
delay(500); delay(500);
} }
#endif // RGB_STARTUP_TEST #endif // RGB_STARTUP_TEST
#elif ALL(PCA9632, RGB_STARTUP_TEST) // PCA9632 RGB_STARTUP_TEST
constexpr int8_t led_pin_count = TERN(HAS_WHITE_LED, 4, 3);
// Startup animation
LEDColor curColor = LEDColorOff();
PCA9632_set_led_color(curColor); // blackout
delay(200);
/**
* LED Pin Counter steps -> events
* | 0-100 | 100-200 | 200-300 | 300-400 |
* fade in steady | fade out
* start next pin fade in
*/
uint16_t led_pin_counters[led_pin_count] = { 1, 0, 0 };
bool canEnd = false;
while (led_pin_counters[0] != 99 || !canEnd) {
if (led_pin_counters[0] == 99) // End loop next time pin0 counter is 99
canEnd = true;
for (uint8_t i = 0; i < led_pin_count; ++i) {
if (led_pin_counters[i] > 0) {
if (++led_pin_counters[i] == 400) // turn off current pin counter in led_pin_counters
led_pin_counters[i] = 0;
else if (led_pin_counters[i] == 201) { // start next pin pwm
led_pin_counters[i + 1 == led_pin_count ? 0 : i + 1] = 1;
i++; // skip next pin in this loop so it doesn't increment twice
}
}
}
uint16_t r, g, b;
r = led_pin_counters[0]; curColor.r = r <= 100 ? r : r <= 300 ? 100 : 400 - r;
g = led_pin_counters[1]; curColor.g = g <= 100 ? g : g <= 300 ? 100 : 400 - g;
b = led_pin_counters[2]; curColor.b = b <= 100 ? b : b <= 300 ? 100 : 400 - b;
#if HAS_WHITE_LED
const uint16_t w = led_pin_counters[3]; curColor.w = w <= 100 ? w : w <= 300 ? 100 : 400 - w;
#endif #endif
PCA9632_set_led_color(curColor);
delay(RGB_STARTUP_TEST_INNER_MS);
}
// Fade to white
for (uint8_t led_pwm = 0; led_pwm <= 100; ++led_pwm) {
NOLESS(curColor.r, led_pwm);
NOLESS(curColor.g, led_pwm);
NOLESS(curColor.b, led_pwm);
TERN_(HAS_WHITE_LED, NOLESS(curColor.w, led_pwm));
PCA9632_set_led_color(curColor);
delay(RGB_STARTUP_TEST_INNER_MS);
}
#endif // PCA9632 && RGB_STARTUP_TEST
TERN_(NEOPIXEL_LED, neo.init()); TERN_(NEOPIXEL_LED, neo.init());
TERN_(PCA9533, PCA9533_init()); TERN_(PCA9533, PCA9533_init());
TERN_(LED_USER_PRESET_STARTUP, set_default()); TERN_(LED_USER_PRESET_STARTUP, set_default());

View File

@ -66,7 +66,7 @@
// Types // Types
// ------------------------ // ------------------------
typedef IF<(TERN0(NEOPIXEL_LED, NEOPIXEL_PIXELS > 127)), int16_t, int8_t>::type pixel_index_t; typedef value_t(TERN0(NEOPIXEL_LED, NEOPIXEL_PIXELS)) pixel_index_t;
// ------------------------ // ------------------------
// Classes // Classes

View File

@ -136,7 +136,7 @@ uint8_t Max7219::suspended; // = 0;
void Max7219::error(FSTR_P const func, const int32_t v1, const int32_t v2/*=-1*/) { void Max7219::error(FSTR_P const func, const int32_t v1, const int32_t v2/*=-1*/) {
#if ENABLED(MAX7219_ERRORS) #if ENABLED(MAX7219_ERRORS)
SERIAL_ECHOPGM("??? Max7219::"); SERIAL_ECHOPGM("??? Max7219::");
SERIAL_ECHOF(func, AS_CHAR('(')); SERIAL_ECHOF(func, C('('));
SERIAL_ECHO(v1); SERIAL_ECHO(v1);
if (v2 > 0) SERIAL_ECHOPGM(", ", v2); if (v2 > 0) SERIAL_ECHOPGM(", ", v2);
SERIAL_CHAR(')'); SERIAL_CHAR(')');
@ -471,7 +471,7 @@ void Max7219::register_setup() {
constexpr millis_t pattern_delay = 4; constexpr millis_t pattern_delay = 4;
int8_t spiralx, spiraly, spiral_dir; int8_t spiralx, spiraly, spiral_dir;
IF<(MAX7219_LEDS > 255), uint16_t, uint8_t>::type spiral_count; uvalue_t(MAX7219_LEDS) spiral_count;
void Max7219::test_pattern() { void Max7219::test_pattern() {
constexpr int8_t way[][2] = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } }; constexpr int8_t way[][2] = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };
@ -707,7 +707,7 @@ void Max7219::idle_tasks() {
#ifdef MAX7219_DEBUG_PLANNER_QUEUE #ifdef MAX7219_DEBUG_PLANNER_QUEUE
static int16_t last_depth = 0; static int16_t last_depth = 0;
const int16_t current_depth = (head - tail + BLOCK_BUFFER_SIZE) & (BLOCK_BUFFER_SIZE - 1) & 0xF; const int16_t current_depth = BLOCK_MOD(head - tail + (BLOCK_BUFFER_SIZE)) & 0xF;
if (current_depth != last_depth) { if (current_depth != last_depth) {
quantity16(MAX7219_DEBUG_PLANNER_QUEUE, last_depth, current_depth, &row_change_mask); quantity16(MAX7219_DEBUG_PLANNER_QUEUE, last_depth, current_depth, &row_change_mask);
last_depth = current_depth; last_depth = current_depth;

View File

@ -140,7 +140,7 @@ void MeatPack::handle_output_char(const uint8_t c) {
#if ENABLED(MP_DEBUG) #if ENABLED(MP_DEBUG)
if (chars_decoded < 1024) { if (chars_decoded < 1024) {
++chars_decoded; ++chars_decoded;
DEBUG_ECHOLNPGM("RB: ", AS_CHAR(c)); DEBUG_ECHOLNPGM("RB: ", C(c));
} }
#endif #endif
} }

View File

@ -140,6 +140,8 @@ int8_t MMU2::get_current_tool() { return extruder == MMU2_NO_TOOL ? -1 : extrude
#if ANY(HAS_PRUSA_MMU2S, MMU_EXTRUDER_SENSOR) #if ANY(HAS_PRUSA_MMU2S, MMU_EXTRUDER_SENSOR)
#define FILAMENT_PRESENT() (READ(FIL_RUNOUT1_PIN) != FIL_RUNOUT1_STATE) #define FILAMENT_PRESENT() (READ(FIL_RUNOUT1_PIN) != FIL_RUNOUT1_STATE)
#else
#define FILAMENT_PRESENT() true
#endif #endif
void mmu2_attn_buzz(const bool two=false) { void mmu2_attn_buzz(const bool two=false) {
@ -827,7 +829,7 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
} }
} }
else if (mmu_print_saved) { else if (mmu_print_saved) {
SERIAL_ECHOLNPGM("MMU starts responding\n"); SERIAL_ECHOLNPGM("\nMMU starts responding");
if (turn_off_nozzle && resume_hotend_temp) { if (turn_off_nozzle && resume_hotend_temp) {
thermalManager.setTargetHotend(resume_hotend_temp, active_extruder); thermalManager.setTargetHotend(resume_hotend_temp, active_extruder);

View File

@ -46,11 +46,11 @@ struct pm_lpf_t {
class PowerMonitor { class PowerMonitor {
private: private:
#if ENABLED(POWER_MONITOR_CURRENT) #if ENABLED(POWER_MONITOR_CURRENT)
static constexpr float amps_adc_scale = float(ADC_VREF) / (POWER_MONITOR_VOLTS_PER_AMP * PM_SAMPLE_RANGE); static constexpr float amps_adc_scale = (float(ADC_VREF_MV) / 1000.0f) / (POWER_MONITOR_VOLTS_PER_AMP * PM_SAMPLE_RANGE);
static pm_lpf_t<amps_adc_scale, PM_K_VALUE, PM_K_SCALE> amps; static pm_lpf_t<amps_adc_scale, PM_K_VALUE, PM_K_SCALE> amps;
#endif #endif
#if ENABLED(POWER_MONITOR_VOLTAGE) #if ENABLED(POWER_MONITOR_VOLTAGE)
static constexpr float volts_adc_scale = float(ADC_VREF) / (POWER_MONITOR_VOLTS_PER_VOLT * PM_SAMPLE_RANGE); static constexpr float volts_adc_scale = (float(ADC_VREF_MV) / 1000.0f) / (POWER_MONITOR_VOLTS_PER_VOLT * PM_SAMPLE_RANGE);
static pm_lpf_t<volts_adc_scale, PM_K_VALUE, PM_K_SCALE> volts; static pm_lpf_t<volts_adc_scale, PM_K_VALUE, PM_K_SCALE> volts;
#endif #endif

View File

@ -67,16 +67,15 @@ uint32_t PrintJobRecovery::cmd_sdpos, // = 0
PrintJobRecovery recovery; PrintJobRecovery recovery;
#ifndef POWER_LOSS_PURGE_LEN
#define POWER_LOSS_PURGE_LEN 0
#endif
#if DISABLED(BACKUP_POWER_SUPPLY) #if DISABLED(BACKUP_POWER_SUPPLY)
#undef POWER_LOSS_RETRACT_LEN // No retract at outage without backup power #undef POWER_LOSS_RETRACT_LEN // No retract at outage without backup power
#endif #endif
#ifndef POWER_LOSS_RETRACT_LEN #ifndef POWER_LOSS_RETRACT_LEN
#define POWER_LOSS_RETRACT_LEN 0 #define POWER_LOSS_RETRACT_LEN 0
#endif #endif
#ifndef POWER_LOSS_PURGE_LEN
#define POWER_LOSS_PURGE_LEN 0
#endif
// Allow power-loss recovery to be aborted // Allow power-loss recovery to be aborted
#define PLR_CAN_ABORT #define PLR_CAN_ABORT
@ -109,6 +108,7 @@ void PrintJobRecovery::changed() {
purge(); purge();
else if (IS_SD_PRINTING()) else if (IS_SD_PRINTING())
save(true); save(true);
TERN_(EXTENSIBLE_UI, ExtUI::onSetPowerLoss(enabled));
} }
/** /**
@ -215,7 +215,7 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW
#endif #endif
#endif #endif
#if HAS_EXTRUDERS #if HAS_HOTEND
HOTEND_LOOP() info.target_temperature[e] = thermalManager.degTargetHotend(e); HOTEND_LOOP() info.target_temperature[e] = thermalManager.degTargetHotend(e);
#endif #endif
@ -311,6 +311,9 @@ void PrintJobRecovery::save(const bool force/*=false*/, const float zraise/*=POW
// and a flag whether the raise was already done here. // and a flag whether the raise was already done here.
if (IS_SD_PRINTING()) save(true, zraise, ENABLED(BACKUP_POWER_SUPPLY)); if (IS_SD_PRINTING()) save(true, zraise, ENABLED(BACKUP_POWER_SUPPLY));
// Tell the LCD about the outage, even though it is about to die
TERN_(EXTENSIBLE_UI, ExtUI::onPowerLoss());
// Disable all heaters to reduce power loss // Disable all heaters to reduce power loss
thermalManager.disable_all_heaters(); thermalManager.disable_all_heaters();
@ -708,7 +711,9 @@ void PrintJobRecovery::resume() {
DEBUG_ECHOLNPGM("flag.dryrun: ", AS_DIGIT(info.flag.dryrun)); DEBUG_ECHOLNPGM("flag.dryrun: ", AS_DIGIT(info.flag.dryrun));
DEBUG_ECHOLNPGM("flag.allow_cold_extrusion: ", AS_DIGIT(info.flag.allow_cold_extrusion)); DEBUG_ECHOLNPGM("flag.allow_cold_extrusion: ", AS_DIGIT(info.flag.allow_cold_extrusion));
#if DISABLED(NO_VOLUMETRICS)
DEBUG_ECHOLNPGM("flag.volumetric_enabled: ", AS_DIGIT(info.flag.volumetric_enabled)); DEBUG_ECHOLNPGM("flag.volumetric_enabled: ", AS_DIGIT(info.flag.volumetric_enabled));
#endif
} }
else else
DEBUG_ECHOLNPGM("INVALID DATA"); DEBUG_ECHOLNPGM("INVALID DATA");

View File

@ -113,7 +113,7 @@ typedef struct {
millis_t print_job_elapsed; millis_t print_job_elapsed;
// Relative axis modes // Relative axis modes
uint8_t axis_relative; relative_t axis_relative;
// Misc. Marlin flags // Misc. Marlin flags
struct { struct {

View File

@ -48,6 +48,9 @@ public:
static void add_marker(const uint32_t sdpos, const uint16_t count); static void add_marker(const uint32_t sdpos, const uint16_t count);
static void loop(); static void loop();
static void cancel(); static void cancel();
static uint8_t count() { return index; }
static int16_t get_marker_counter(const uint8_t i) { return marker[i].counter; }
static uint32_t get_marker_sdpos(const uint8_t i) { return marker[i].sdpos; }
}; };
extern Repeat repeat; extern Repeat repeat;

View File

@ -144,7 +144,7 @@ class TFilamentMonitor : public FilamentMonitorBase {
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG) #if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
if (runout_flags) { if (runout_flags) {
SERIAL_ECHOPGM("Runout Sensors: "); SERIAL_ECHOPGM("Runout Sensors: ");
for (uint8_t i = 0; i < 8; ++i) SERIAL_ECHO('0' + TEST(runout_flags, i)); for (uint8_t i = 0; i < 8; ++i) SERIAL_CHAR('0' + TEST(runout_flags, i));
SERIAL_ECHOPGM(" -> ", extruder); SERIAL_ECHOPGM(" -> ", extruder);
if (ran_out) SERIAL_ECHOPGM(" RUN OUT"); if (ran_out) SERIAL_ECHOPGM(" RUN OUT");
SERIAL_EOL(); SERIAL_EOL();

View File

@ -27,7 +27,7 @@
#include "solenoid.h" #include "solenoid.h"
#include "../module/motion.h" // for active_extruder #include "../module/motion.h" // for active_extruder
#include "../module/tool_change.h" #include "../module/tool_change.h" // for parking_extruder_set_parked
// Used primarily with MANUAL_SOLENOID_CONTROL // Used primarily with MANUAL_SOLENOID_CONTROL
static void set_solenoid(const uint8_t num, const uint8_t state) { static void set_solenoid(const uint8_t num, const uint8_t state) {

View File

@ -57,7 +57,7 @@
#endif #endif
#endif #endif
typedef IF<(SPEED_POWER_MAX > 255), uint16_t, uint8_t>::type cutter_cpower_t; typedef uvalue_t(SPEED_POWER_MAX) cutter_cpower_t;
#if CUTTER_UNIT_IS(RPM) && SPEED_POWER_MAX > 255 #if CUTTER_UNIT_IS(RPM) && SPEED_POWER_MAX > 255
typedef uint16_t cutter_power_t; typedef uint16_t cutter_power_t;

View File

@ -773,8 +773,8 @@
} }
} }
static void tmc_debug_loop(const TMC_debug_enum n, LOGICAL_AXIS_ARGS(const bool)) { static void tmc_debug_loop(const TMC_debug_enum n OPTARGS_LOGICAL(const bool)) {
if (x) { if (TERN0(HAS_X_AXIS, x)) {
#if AXIS_IS_TMC(X) #if AXIS_IS_TMC(X)
tmc_status(stepperX, n); tmc_status(stepperX, n);
#endif #endif
@ -856,8 +856,8 @@
SERIAL_EOL(); SERIAL_EOL();
} }
static void drv_status_loop(const TMC_drv_status_enum n, LOGICAL_AXIS_ARGS(const bool)) { static void drv_status_loop(const TMC_drv_status_enum n OPTARGS_LOGICAL(const bool)) {
if (x) { if (TERN0(HAS_X_AXIS, x)) {
#if AXIS_IS_TMC(X) #if AXIS_IS_TMC(X)
tmc_parse_drv_status(stepperX, n); tmc_parse_drv_status(stepperX, n);
#endif #endif
@ -944,8 +944,8 @@
*/ */
void tmc_report_all(LOGICAL_AXIS_ARGS(const bool)) { void tmc_report_all(LOGICAL_AXIS_ARGS(const bool)) {
#define TMC_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_debug_loop(ITEM, LOGICAL_AXIS_ARGS()); }while(0) #define TMC_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_debug_loop(ITEM OPTARGS_LOGICAL()); }while(0)
#define DRV_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); drv_status_loop(ITEM, LOGICAL_AXIS_ARGS()); }while(0) #define DRV_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); drv_status_loop(ITEM OPTARGS_LOGICAL()); }while(0)
TMC_REPORT("\t", TMC_CODES); TMC_REPORT("\t", TMC_CODES);
#if HAS_DRIVER(TMC2209) #if HAS_DRIVER(TMC2209)
@ -1070,8 +1070,8 @@
} }
#endif #endif
static void tmc_get_registers(TMC_get_registers_enum n, LOGICAL_AXIS_ARGS(const bool)) { static void tmc_get_registers(TMC_get_registers_enum n OPTARGS_LOGICAL(const bool)) {
if (x) { if (TERN0(HAS_X_AXIS, x)) {
#if AXIS_IS_TMC(X) #if AXIS_IS_TMC(X)
tmc_get_registers(stepperX, n); tmc_get_registers(stepperX, n);
#endif #endif
@ -1154,7 +1154,7 @@
} }
void tmc_get_registers(LOGICAL_AXIS_ARGS(bool)) { void tmc_get_registers(LOGICAL_AXIS_ARGS(bool)) {
#define _TMC_GET_REG(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_get_registers(ITEM, LOGICAL_AXIS_ARGS()); }while(0) #define _TMC_GET_REG(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_get_registers(ITEM OPTARGS_LOGICAL()); }while(0)
#define TMC_GET_REG(NAME, TABS) _TMC_GET_REG(STRINGIFY(NAME) TABS, TMC_GET_##NAME) #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("\t", TMC_AXIS_CODES);
TMC_GET_REG(GCONF, "\t\t"); TMC_GET_REG(GCONF, "\t\t");
@ -1236,7 +1236,7 @@ static bool test_connection(TMC &st) {
void test_tmc_connection(LOGICAL_AXIS_ARGS(const bool)) { void test_tmc_connection(LOGICAL_AXIS_ARGS(const bool)) {
uint8_t axis_connection = 0; uint8_t axis_connection = 0;
if (x) { if (TERN0(HAS_X_AXIS, x)) {
#if AXIS_IS_TMC(X) #if AXIS_IS_TMC(X)
axis_connection += test_connection(stepperX); axis_connection += test_connection(stepperX);
#endif #endif

View File

@ -348,7 +348,7 @@ void test_tmc_connection(LOGICAL_AXIS_DECL(const bool, true));
#if USE_SENSORLESS #if USE_SENSORLESS
// Track enabled status of stealthChop and only re-enable where applicable // Track enabled status of stealthChop and only re-enable where applicable
struct sensorless_t { bool NUM_AXIS_ARGS(), x2, y2, z2, z3, z4; }; struct sensorless_t { bool NUM_AXIS_ARGS_() x2, y2, z2, z3, z4; };
#if ENABLED(IMPROVE_HOMING_RELIABILITY) #if ENABLED(IMPROVE_HOMING_RELIABILITY)
extern millis_t sg_guard_period; extern millis_t sg_guard_period;

View File

@ -29,31 +29,11 @@
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE) #define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
#include "../core/debug_out.h" #include "../core/debug_out.h"
PGMSTR(point_name_1, TRAMMING_POINT_NAME_1); #define _TRAM_NAME_DEF(N) PGMSTR(point_name_##N, TRAMMING_POINT_NAME_##N);
PGMSTR(point_name_2, TRAMMING_POINT_NAME_2); #define _TRAM_NAME_ITEM(N) point_name_##N
PGMSTR(point_name_3, TRAMMING_POINT_NAME_3); REPEAT_1(_NR_TRAM_NAMES, _TRAM_NAME_DEF)
#ifdef TRAMMING_POINT_NAME_4
PGMSTR(point_name_4, TRAMMING_POINT_NAME_4);
#ifdef TRAMMING_POINT_NAME_5
PGMSTR(point_name_5, TRAMMING_POINT_NAME_5);
#ifdef TRAMMING_POINT_NAME_6
PGMSTR(point_name_6, TRAMMING_POINT_NAME_6);
#endif
#endif
#endif
PGM_P const tramming_point_name[] PROGMEM = { PGM_P const tramming_point_name[] PROGMEM = { REPLIST_1(_NR_TRAM_NAMES, _TRAM_NAME_ITEM) };
point_name_1, point_name_2, point_name_3
#ifdef TRAMMING_POINT_NAME_4
, point_name_4
#ifdef TRAMMING_POINT_NAME_5
, point_name_5
#ifdef TRAMMING_POINT_NAME_6
, point_name_6
#endif
#endif
#endif
};
#ifdef ASSISTED_TRAMMING_WAIT_POSITION #ifdef ASSISTED_TRAMMING_WAIT_POSITION

View File

@ -31,43 +31,34 @@
constexpr xy_pos_t tramming_points[] = TRAMMING_POINT_XY; constexpr xy_pos_t tramming_points[] = TRAMMING_POINT_XY;
#define G35_PROBE_COUNT COUNT(tramming_points) #define G35_PROBE_COUNT COUNT(tramming_points)
static_assert(WITHIN(G35_PROBE_COUNT, 3, 6), "TRAMMING_POINT_XY requires between 3 and 6 XY positions."); static_assert(WITHIN(G35_PROBE_COUNT, 3, 9), "TRAMMING_POINT_XY requires between 3 and 9 XY positions.");
#define VALIDATE_TRAMMING_POINT(N) static_assert(N >= G35_PROBE_COUNT || Probe::build_time::can_reach(tramming_points[N]), \ #ifdef TRAMMING_POINT_NAME_9
"TRAMMING_POINT_XY point " STRINGIFY(N) " is not reachable with the default NOZZLE_TO_PROBE offset and PROBING_MARGIN.") #define _NR_TRAM_NAMES 9
VALIDATE_TRAMMING_POINT(0); VALIDATE_TRAMMING_POINT(1); VALIDATE_TRAMMING_POINT(2); VALIDATE_TRAMMING_POINT(3); VALIDATE_TRAMMING_POINT(4); VALIDATE_TRAMMING_POINT(5); #elif defined(TRAMMING_POINT_NAME_8)
#define _NR_TRAM_NAMES 8
extern const char point_name_1[], point_name_2[], point_name_3[] #elif defined(TRAMMING_POINT_NAME_7)
#ifdef TRAMMING_POINT_NAME_4 #define _NR_TRAM_NAMES 7
, point_name_4[] #elif defined(TRAMMING_POINT_NAME_6)
#ifdef TRAMMING_POINT_NAME_5
, point_name_5[]
#ifdef TRAMMING_POINT_NAME_6
, point_name_6[]
#endif
#endif
#endif
;
#define _NR_TRAM_NAMES 2
#ifdef TRAMMING_POINT_NAME_3
#undef _NR_TRAM_NAMES
#define _NR_TRAM_NAMES 3
#ifdef TRAMMING_POINT_NAME_4
#undef _NR_TRAM_NAMES
#define _NR_TRAM_NAMES 4
#ifdef TRAMMING_POINT_NAME_5
#undef _NR_TRAM_NAMES
#define _NR_TRAM_NAMES 5
#ifdef TRAMMING_POINT_NAME_6
#undef _NR_TRAM_NAMES
#define _NR_TRAM_NAMES 6 #define _NR_TRAM_NAMES 6
#endif #elif defined(TRAMMING_POINT_NAME_5)
#endif #define _NR_TRAM_NAMES 5
#endif #elif defined(TRAMMING_POINT_NAME_4)
#define _NR_TRAM_NAMES 4
#elif defined(TRAMMING_POINT_NAME_3)
#define _NR_TRAM_NAMES 3
#else
#define _NR_TRAM_NAMES 0
#endif #endif
static_assert(_NR_TRAM_NAMES >= G35_PROBE_COUNT, "Define enough TRAMMING_POINT_NAME_s for all TRAMMING_POINT_XY entries."); static_assert(_NR_TRAM_NAMES >= G35_PROBE_COUNT, "Define enough TRAMMING_POINT_NAME_s for all TRAMMING_POINT_XY entries.");
#undef _NR_TRAM_NAMES
#define _TRAM_NAME_PTR(N) point_name_##N[]
extern const char REPLIST_1(_NR_TRAM_NAMES, _TRAM_NAME_PTR);
#define _CHECK_TRAM_POINT(N) static_assert(Probe::build_time::can_reach(tramming_points[N]), "TRAMMING_POINT_XY point " STRINGIFY(N) " is not reachable with the default NOZZLE_TO_PROBE offset and PROBING_MARGIN.");
REPEAT(_NR_TRAM_NAMES, _CHECK_TRAM_POINT)
#undef _CHECK_TRAM_POINT
extern PGM_P const tramming_point_name[]; extern PGM_P const tramming_point_name[];

View File

@ -628,7 +628,7 @@ void GcodeSuite::G26() {
} }
// Get repeat from 'R', otherwise do one full circuit // Get repeat from 'R', otherwise do one full circuit
int16_t g26_repeats; grid_count_t g26_repeats;
#if HAS_MARLINUI_MENU #if HAS_MARLINUI_MENU
g26_repeats = parser.intval('R', GRID_MAX_POINTS + 1); g26_repeats = parser.intval('R', GRID_MAX_POINTS + 1);
#else #else

View File

@ -106,11 +106,11 @@ public:
#endif #endif
#if ENABLED(AUTO_BED_LEVELING_LINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR)
int abl_points; grid_count_t abl_points;
#elif ENABLED(AUTO_BED_LEVELING_3POINT) #elif ENABLED(AUTO_BED_LEVELING_3POINT)
static constexpr int abl_points = 3; static constexpr grid_count_t abl_points = 3;
#elif ABL_USES_GRID #elif ABL_USES_GRID
static constexpr int abl_points = GRID_MAX_POINTS; static constexpr grid_count_t abl_points = GRID_MAX_POINTS;
#endif #endif
#if ABL_USES_GRID #if ABL_USES_GRID
@ -136,7 +136,7 @@ public:
#if ENABLED(AUTO_BED_LEVELING_LINEAR) #if ENABLED(AUTO_BED_LEVELING_LINEAR)
int indexIntoAB[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y]; int indexIntoAB[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
float eqnAMatrix[(GRID_MAX_POINTS) * 3], // "A" matrix of the linear system of equations float eqnAMatrix[GRID_MAX_POINTS * 3], // "A" matrix of the linear system of equations
eqnBVector[GRID_MAX_POINTS], // "B" vector of Z points eqnBVector[GRID_MAX_POINTS], // "B" vector of Z points
mean; mean;
#endif #endif
@ -145,7 +145,7 @@ public:
#if ABL_USES_GRID && ANY(AUTO_BED_LEVELING_3POINT, AUTO_BED_LEVELING_BILINEAR) #if ABL_USES_GRID && ANY(AUTO_BED_LEVELING_3POINT, AUTO_BED_LEVELING_BILINEAR)
constexpr xy_uint8_t G29_State::grid_points; constexpr xy_uint8_t G29_State::grid_points;
constexpr int G29_State::abl_points; constexpr grid_count_t G29_State::abl_points;
#endif #endif
/** /**
@ -502,20 +502,13 @@ G29_TYPE GcodeSuite::G29() {
#endif #endif
#if ENABLED(AUTO_BED_LEVELING_BILINEAR) #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
if (!abl.dryrun if (!abl.dryrun && (abl.gridSpacing != bedlevel.grid_spacing || abl.probe_position_lf != bedlevel.grid_start)) {
&& (abl.gridSpacing != bedlevel.grid_spacing || abl.probe_position_lf != bedlevel.grid_start) reset_bed_level(); // Reset grid to 0.0 or "not probed". (Also disables ABL)
) { abl.reenable = false; // Can't re-enable (on error) until the new grid is written
// Reset grid to 0.0 or "not probed". (Also disables ABL)
reset_bed_level();
// Can't re-enable (on error) until the new grid is written
abl.reenable = false;
} }
// Pre-populate local Z values from the stored mesh // Pre-populate local Z values from the stored mesh
TERN_(IS_KINEMATIC, COPY(abl.z_values, bedlevel.z_values)); TERN_(IS_KINEMATIC, COPY(abl.z_values, bedlevel.z_values));
#endif
#endif // AUTO_BED_LEVELING_BILINEAR
} // !g29_in_progress } // !g29_in_progress
@ -692,7 +685,7 @@ G29_TYPE GcodeSuite::G29() {
zig ^= true; // zag zig ^= true; // zag
// An index to print current state // An index to print current state
uint8_t pt_index = (PR_OUTER_VAR) * (PR_INNER_SIZE) + 1; grid_count_t pt_index = (PR_OUTER_VAR) * (PR_INNER_SIZE) + 1;
// Inner loop is Y with PROBE_Y_FIRST enabled // Inner loop is Y with PROBE_Y_FIRST enabled
// Inner loop is X with PROBE_Y_FIRST disabled // Inner loop is X with PROBE_Y_FIRST disabled

View File

@ -104,9 +104,8 @@ void GcodeSuite::G29() {
bedlevel.reset(); bedlevel.reset();
mbl_probe_index = 0; mbl_probe_index = 0;
if (!ui.wait_for_move) { if (!ui.wait_for_move) {
queue.inject(parser.seen_test('N') ? F("G28" TERN(CAN_SET_LEVELING_AFTER_G28, "L0", "") "\nG29S2") : F("G29S2")); if (parser.seen_test('N'))
TERN_(EXTENSIBLE_UI, ExtUI::onLevelingStart()); queue.inject(F("G28" TERN_(CAN_SET_LEVELING_AFTER_G28, "L0")));
TERN_(DWIN_LCD_PROUI, DWIN_LevelingStart());
// Position bed horizontally and Z probe vertically. // Position bed horizontally and Z probe vertically.
#if HAS_SAFE_BED_LEVELING #if HAS_SAFE_BED_LEVELING
@ -142,6 +141,11 @@ void GcodeSuite::G29() {
do_blocking_move_to(safe_position); do_blocking_move_to(safe_position);
#endif // HAS_SAFE_BED_LEVELING #endif // HAS_SAFE_BED_LEVELING
queue.inject(F("G29S2"));
TERN_(EXTENSIBLE_UI, ExtUI::onLevelingStart());
TERN_(DWIN_LCD_PROUI, DWIN_LevelingStart());
return; return;
} }
state = MeshNext; state = MeshNext;
@ -170,7 +174,7 @@ void GcodeSuite::G29() {
SET_SOFT_ENDSTOP_LOOSE(false); SET_SOFT_ENDSTOP_LOOSE(false);
} }
// If there's another point to sample, move there with optional lift. // If there's another point to sample, move there with optional lift.
if (mbl_probe_index < (GRID_MAX_POINTS)) { if (mbl_probe_index < GRID_MAX_POINTS) {
// Disable software endstops to allow manual adjustment // Disable software endstops to allow manual adjustment
// If G29 is left hanging without completion they won't be re-enabled! // If G29 is left hanging without completion they won't be re-enabled!
SET_SOFT_ENDSTOP_LOOSE(true); SET_SOFT_ENDSTOP_LOOSE(true);

View File

@ -86,7 +86,7 @@
NUM_AXIS_LIST( NUM_AXIS_LIST(
TERN0(X_SENSORLESS, tmc_enable_stallguard(stepperX)), TERN0(X_SENSORLESS, tmc_enable_stallguard(stepperX)),
TERN0(Y_SENSORLESS, tmc_enable_stallguard(stepperY)), TERN0(Y_SENSORLESS, tmc_enable_stallguard(stepperY)),
false, false, false, false false, false, false, false, false, false, false
) )
, TERN0(X2_SENSORLESS, tmc_enable_stallguard(stepperX2)) , TERN0(X2_SENSORLESS, tmc_enable_stallguard(stepperX2))
, TERN0(Y2_SENSORLESS, tmc_enable_stallguard(stepperY2)) , TERN0(Y2_SENSORLESS, tmc_enable_stallguard(stepperY2))

View File

@ -97,7 +97,7 @@ void ac_cleanup(TERN_(HAS_MULTI_HOTEND, const uint8_t old_tool_index)) {
void print_signed_float(FSTR_P const prefix, const_float_t f) { void print_signed_float(FSTR_P const prefix, const_float_t f) {
SERIAL_ECHOPGM(" "); SERIAL_ECHOPGM(" ");
SERIAL_ECHOF(prefix, AS_CHAR(':')); SERIAL_ECHOF(prefix, C(':'));
serial_offset(f); serial_offset(f);
} }

View File

@ -33,10 +33,13 @@
#include "../../lcd/marlinui.h" #include "../../lcd/marlinui.h"
#include "../../module/motion.h" #include "../../module/motion.h"
#include "../../module/planner.h" #include "../../module/planner.h"
#include "../../module/tool_change.h"
#include "../../module/endstops.h" #include "../../module/endstops.h"
#include "../../feature/bedlevel/bedlevel.h" #include "../../feature/bedlevel/bedlevel.h"
#if HAS_MULTI_HOTEND
#include "../../module/tool_change.h"
#endif
#if !AXIS_CAN_CALIBRATE(X) #if !AXIS_CAN_CALIBRATE(X)
#undef CALIBRATION_MEASURE_LEFT #undef CALIBRATION_MEASURE_LEFT
#undef CALIBRATION_MEASURE_RIGHT #undef CALIBRATION_MEASURE_RIGHT
@ -70,7 +73,7 @@
#define CALIBRATION_MEASUREMENT_CERTAIN 0.5 // mm #define CALIBRATION_MEASUREMENT_CERTAIN 0.5 // mm
#endif #endif
#if ALL(CALIBRATION_MEASURE_LEFT, CALIBRATION_MEASURE_RIGHT) #if ALL(HAS_X_AXIS, CALIBRATION_MEASURE_LEFT, CALIBRATION_MEASURE_RIGHT)
#define HAS_X_CENTER 1 #define HAS_X_CENTER 1
#endif #endif
#if ALL(HAS_Y_AXIS, CALIBRATION_MEASURE_FRONT, CALIBRATION_MEASURE_BACK) #if ALL(HAS_Y_AXIS, CALIBRATION_MEASURE_FRONT, CALIBRATION_MEASURE_BACK)
@ -271,10 +274,10 @@ inline void probe_side(measurements_t &m, const float uncertainty, const side_t
#if AXIS_CAN_CALIBRATE(X) #if AXIS_CAN_CALIBRATE(X)
_ACASE(X, RIGHT, LEFT); _ACASE(X, RIGHT, LEFT);
#endif #endif
#if HAS_Y_AXIS && AXIS_CAN_CALIBRATE(Y) #if AXIS_CAN_CALIBRATE(Y)
_ACASE(Y, BACK, FRONT); _ACASE(Y, BACK, FRONT);
#endif #endif
#if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z) #if AXIS_CAN_CALIBRATE(Z)
case TOP: { case TOP: {
const float measurement = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty); const float measurement = measure(Z_AXIS, -1, true, &m.backlash[TOP], uncertainty);
m.obj_center.z = measurement - dimensions.z / 2; m.obj_center.z = measurement - dimensions.z / 2;
@ -282,22 +285,22 @@ inline void probe_side(measurements_t &m, const float uncertainty, const side_t
return; return;
} }
#endif #endif
#if HAS_I_AXIS && AXIS_CAN_CALIBRATE(I) #if AXIS_CAN_CALIBRATE(I)
_PCASE(I); _PCASE(I);
#endif #endif
#if HAS_J_AXIS && AXIS_CAN_CALIBRATE(J) #if AXIS_CAN_CALIBRATE(J)
_PCASE(J); _PCASE(J);
#endif #endif
#if HAS_K_AXIS && AXIS_CAN_CALIBRATE(K) #if AXIS_CAN_CALIBRATE(K)
_PCASE(K); _PCASE(K);
#endif #endif
#if HAS_U_AXIS && AXIS_CAN_CALIBRATE(U) #if AXIS_CAN_CALIBRATE(U)
_PCASE(U); _PCASE(U);
#endif #endif
#if HAS_V_AXIS && AXIS_CAN_CALIBRATE(V) #if AXIS_CAN_CALIBRATE(V)
_PCASE(V); _PCASE(V);
#endif #endif
#if HAS_W_AXIS && AXIS_CAN_CALIBRATE(W) #if AXIS_CAN_CALIBRATE(W)
_PCASE(W); _PCASE(W);
#endif #endif
default: return; default: return;
@ -395,15 +398,17 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
#if ENABLED(CALIBRATION_REPORTING) #if ENABLED(CALIBRATION_REPORTING)
inline void report_measured_faces(const measurements_t &m) { inline void report_measured_faces(const measurements_t &m) {
SERIAL_ECHOLNPGM("Sides:"); SERIAL_ECHOLNPGM("Sides:");
#if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z) #if AXIS_CAN_CALIBRATE(Z)
SERIAL_ECHOLNPGM(" Top: ", m.obj_side[TOP]); SERIAL_ECHOLNPGM(" Top: ", m.obj_side[TOP]);
#endif #endif
#if HAS_X_AXIS
#if ENABLED(CALIBRATION_MEASURE_LEFT) #if ENABLED(CALIBRATION_MEASURE_LEFT)
SERIAL_ECHOLNPGM(" Left: ", m.obj_side[LEFT]); SERIAL_ECHOLNPGM(" Left: ", m.obj_side[LEFT]);
#endif #endif
#if ENABLED(CALIBRATION_MEASURE_RIGHT) #if ENABLED(CALIBRATION_MEASURE_RIGHT)
SERIAL_ECHOLNPGM(" Right: ", m.obj_side[RIGHT]); SERIAL_ECHOLNPGM(" Right: ", m.obj_side[RIGHT]);
#endif #endif
#endif
#if HAS_Y_AXIS #if HAS_Y_AXIS
#if ENABLED(CALIBRATION_MEASURE_FRONT) #if ENABLED(CALIBRATION_MEASURE_FRONT)
SERIAL_ECHOLNPGM(" Front: ", m.obj_side[FRONT]); SERIAL_ECHOLNPGM(" Front: ", m.obj_side[FRONT]);
@ -503,7 +508,7 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
SERIAL_ECHOLNPGM(" Right: ", m.backlash[RIGHT]); SERIAL_ECHOLNPGM(" Right: ", m.backlash[RIGHT]);
#endif #endif
#endif #endif
#if HAS_Y_AXIS && AXIS_CAN_CALIBRATE(Y) #if AXIS_CAN_CALIBRATE(Y)
#if ENABLED(CALIBRATION_MEASURE_FRONT) #if ENABLED(CALIBRATION_MEASURE_FRONT)
SERIAL_ECHOLNPGM(" Front: ", m.backlash[FRONT]); SERIAL_ECHOLNPGM(" Front: ", m.backlash[FRONT]);
#endif #endif
@ -511,10 +516,10 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
SERIAL_ECHOLNPGM(" Back: ", m.backlash[BACK]); SERIAL_ECHOLNPGM(" Back: ", m.backlash[BACK]);
#endif #endif
#endif #endif
#if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z) #if AXIS_CAN_CALIBRATE(Z)
SERIAL_ECHOLNPGM(" Top: ", m.backlash[TOP]); SERIAL_ECHOLNPGM(" Top: ", m.backlash[TOP]);
#endif #endif
#if HAS_I_AXIS && AXIS_CAN_CALIBRATE(I) #if AXIS_CAN_CALIBRATE(I)
#if ENABLED(CALIBRATION_MEASURE_IMIN) #if ENABLED(CALIBRATION_MEASURE_IMIN)
SERIAL_ECHOLNPGM(" " STR_I_MIN ": ", m.backlash[IMINIMUM]); SERIAL_ECHOLNPGM(" " STR_I_MIN ": ", m.backlash[IMINIMUM]);
#endif #endif
@ -522,7 +527,7 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
SERIAL_ECHOLNPGM(" " STR_I_MAX ": ", m.backlash[IMAXIMUM]); SERIAL_ECHOLNPGM(" " STR_I_MAX ": ", m.backlash[IMAXIMUM]);
#endif #endif
#endif #endif
#if HAS_J_AXIS && AXIS_CAN_CALIBRATE(J) #if AXIS_CAN_CALIBRATE(J)
#if ENABLED(CALIBRATION_MEASURE_JMIN) #if ENABLED(CALIBRATION_MEASURE_JMIN)
SERIAL_ECHOLNPGM(" " STR_J_MIN ": ", m.backlash[JMINIMUM]); SERIAL_ECHOLNPGM(" " STR_J_MIN ": ", m.backlash[JMINIMUM]);
#endif #endif
@ -530,7 +535,7 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
SERIAL_ECHOLNPGM(" " STR_J_MAX ": ", m.backlash[JMAXIMUM]); SERIAL_ECHOLNPGM(" " STR_J_MAX ": ", m.backlash[JMAXIMUM]);
#endif #endif
#endif #endif
#if HAS_K_AXIS && AXIS_CAN_CALIBRATE(K) #if AXIS_CAN_CALIBRATE(K)
#if ENABLED(CALIBRATION_MEASURE_KMIN) #if ENABLED(CALIBRATION_MEASURE_KMIN)
SERIAL_ECHOLNPGM(" " STR_K_MIN ": ", m.backlash[KMINIMUM]); SERIAL_ECHOLNPGM(" " STR_K_MIN ": ", m.backlash[KMINIMUM]);
#endif #endif
@ -538,7 +543,7 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
SERIAL_ECHOLNPGM(" " STR_K_MAX ": ", m.backlash[KMAXIMUM]); SERIAL_ECHOLNPGM(" " STR_K_MAX ": ", m.backlash[KMAXIMUM]);
#endif #endif
#endif #endif
#if HAS_U_AXIS && AXIS_CAN_CALIBRATE(U) #if AXIS_CAN_CALIBRATE(U)
#if ENABLED(CALIBRATION_MEASURE_UMIN) #if ENABLED(CALIBRATION_MEASURE_UMIN)
SERIAL_ECHOLNPGM(" " STR_U_MIN ": ", m.backlash[UMINIMUM]); SERIAL_ECHOLNPGM(" " STR_U_MIN ": ", m.backlash[UMINIMUM]);
#endif #endif
@ -546,7 +551,7 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
SERIAL_ECHOLNPGM(" " STR_U_MAX ": ", m.backlash[UMAXIMUM]); SERIAL_ECHOLNPGM(" " STR_U_MAX ": ", m.backlash[UMAXIMUM]);
#endif #endif
#endif #endif
#if HAS_V_AXIS && AXIS_CAN_CALIBRATE(V) #if AXIS_CAN_CALIBRATE(V)
#if ENABLED(CALIBRATION_MEASURE_VMIN) #if ENABLED(CALIBRATION_MEASURE_VMIN)
SERIAL_ECHOLNPGM(" " STR_V_MIN ": ", m.backlash[VMINIMUM]); SERIAL_ECHOLNPGM(" " STR_V_MIN ": ", m.backlash[VMINIMUM]);
#endif #endif
@ -554,7 +559,7 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
SERIAL_ECHOLNPGM(" " STR_V_MAX ": ", m.backlash[VMAXIMUM]); SERIAL_ECHOLNPGM(" " STR_V_MAX ": ", m.backlash[VMAXIMUM]);
#endif #endif
#endif #endif
#if HAS_W_AXIS && AXIS_CAN_CALIBRATE(W) #if AXIS_CAN_CALIBRATE(W)
#if ENABLED(CALIBRATION_MEASURE_WMIN) #if ENABLED(CALIBRATION_MEASURE_WMIN)
SERIAL_ECHOLNPGM(" " STR_W_MIN ": ", m.backlash[WMINIMUM]); SERIAL_ECHOLNPGM(" " STR_W_MIN ": ", m.backlash[WMINIMUM]);
#endif #endif
@ -575,7 +580,7 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
#if HAS_Y_CENTER && AXIS_CAN_CALIBRATE(Y) #if HAS_Y_CENTER && AXIS_CAN_CALIBRATE(Y)
SERIAL_ECHOLNPGM_P(SP_Y_STR, m.pos_error.y); SERIAL_ECHOLNPGM_P(SP_Y_STR, m.pos_error.y);
#endif #endif
#if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z) #if AXIS_CAN_CALIBRATE(Z)
SERIAL_ECHOLNPGM_P(SP_Z_STR, m.pos_error.z); SERIAL_ECHOLNPGM_P(SP_Z_STR, m.pos_error.z);
#endif #endif
#if HAS_I_CENTER && AXIS_CAN_CALIBRATE(I) #if HAS_I_CENTER && AXIS_CAN_CALIBRATE(I)

View File

@ -34,7 +34,6 @@
#include "../../module/probe.h" #include "../../module/probe.h"
#include "../../feature/bedlevel/bedlevel.h" #include "../../feature/bedlevel/bedlevel.h"
#include "../../module/temperature.h" #include "../../module/temperature.h"
#include "../../module/probe.h"
#include "../../feature/probe_temp_comp.h" #include "../../feature/probe_temp_comp.h"
#include "../../lcd/marlinui.h" #include "../../lcd/marlinui.h"
@ -108,7 +107,6 @@
}; };
auto g76_probe = [](const TempSensorID sid, celsius_t &targ, const xy_pos_t &nozpos) { auto g76_probe = [](const TempSensorID sid, celsius_t &targ, const xy_pos_t &nozpos) {
do_z_clearance(5.0); // Raise nozzle before probing
ptc.set_enabled(false); ptc.set_enabled(false);
const float measured_z = probe.probe_at_point(nozpos, PROBE_PT_STOW, 0, false); // verbose=0, probe_relative=false const float measured_z = probe.probe_at_point(nozpos, PROBE_PT_STOW, 0, false); // verbose=0, probe_relative=false
ptc.set_enabled(true); ptc.set_enabled(true);

View File

@ -46,12 +46,13 @@
void GcodeSuite::M425() { void GcodeSuite::M425() {
bool noArgs = true; bool noArgs = true;
auto axis_can_calibrate = [](const uint8_t a) { auto axis_can_calibrate = [](const uint8_t a) -> bool {
#define _CAN_CASE(N) case N##_AXIS: return AXIS_CAN_CALIBRATE(N); #define _CAN_CASE(N) case N##_AXIS: return bool(AXIS_CAN_CALIBRATE(N));
switch (a) { switch (a) {
default: return false;
MAIN_AXIS_MAP(_CAN_CASE) MAIN_AXIS_MAP(_CAN_CASE)
default: break;
} }
return false;
}; };
LOOP_NUM_AXES(a) { LOOP_NUM_AXES(a) {
@ -111,6 +112,7 @@ void GcodeSuite::M425_report(const bool forReplay/*=true*/) {
#ifdef BACKLASH_SMOOTHING_MM #ifdef BACKLASH_SMOOTHING_MM
, PSTR(" S"), LINEAR_UNIT(backlash.get_smoothing_mm()) , PSTR(" S"), LINEAR_UNIT(backlash.get_smoothing_mm())
#endif #endif
#if NUM_AXES
, LIST_N(DOUBLE(NUM_AXES), , LIST_N(DOUBLE(NUM_AXES),
SP_X_STR, LINEAR_UNIT(backlash.get_distance_mm(X_AXIS)), SP_X_STR, LINEAR_UNIT(backlash.get_distance_mm(X_AXIS)),
SP_Y_STR, LINEAR_UNIT(backlash.get_distance_mm(Y_AXIS)), SP_Y_STR, LINEAR_UNIT(backlash.get_distance_mm(Y_AXIS)),
@ -122,6 +124,7 @@ void GcodeSuite::M425_report(const bool forReplay/*=true*/) {
SP_V_STR, V_AXIS_UNIT(backlash.get_distance_mm(V_AXIS)), SP_V_STR, V_AXIS_UNIT(backlash.get_distance_mm(V_AXIS)),
SP_W_STR, W_AXIS_UNIT(backlash.get_distance_mm(W_AXIS)) SP_W_STR, W_AXIS_UNIT(backlash.get_distance_mm(W_AXIS))
) )
#endif
); );
} }

View File

@ -66,9 +66,6 @@ void GcodeSuite::M48() {
return; return;
} }
if (verbose_level > 0)
SERIAL_ECHOLNPGM("M48 Z-Probe Repeatability Test");
const int8_t n_samples = parser.byteval('P', 10); const int8_t n_samples = parser.byteval('P', 10);
if (!WITHIN(n_samples, 4, 50)) { if (!WITHIN(n_samples, 4, 50)) {
SERIAL_ECHOLNPGM("?Sample size not plausible (4-50)."); SERIAL_ECHOLNPGM("?Sample size not plausible (4-50).");
@ -102,6 +99,9 @@ void GcodeSuite::M48() {
const bool schizoid_flag = parser.boolval('S'); const bool schizoid_flag = parser.boolval('S');
if (schizoid_flag && !seen_L) n_legs = 7; if (schizoid_flag && !seen_L) n_legs = 7;
if (verbose_level > 0)
SERIAL_ECHOLNPGM("M48 Z-Probe Repeatability Test");
if (verbose_level > 2) if (verbose_level > 2)
SERIAL_ECHOLNPGM("Positioning the probe..."); SERIAL_ECHOLNPGM("Positioning the probe...");
@ -223,7 +223,7 @@ void GcodeSuite::M48() {
} // n_legs } // n_legs
// Probe a single point // Probe a single point
const float pz = probe.probe_at_point(test_position, raise_after, 0); const float pz = probe.probe_at_point(test_position, raise_after);
// Break the loop if the probe fails // Break the loop if the probe fails
probing_good = !isnan(pz); probing_good = !isnan(pz);

View File

@ -52,7 +52,7 @@
is_err = true; is_err = true;
else { else {
delta_endstop_adj[i] = v; delta_endstop_adj[i] = v;
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("delta_endstop_adj[", AS_CHAR(AXIS_CHAR(i)), "] = ", v); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("delta_endstop_adj[", C(AXIS_CHAR(i)), "] = ", v);
} }
} }
} }

View File

@ -143,7 +143,8 @@ void GcodeSuite::M201() {
void GcodeSuite::M201_report(const bool forReplay/*=true*/) { void GcodeSuite::M201_report(const bool forReplay/*=true*/) {
report_heading_etc(forReplay, F(STR_MAX_ACCELERATION)); report_heading_etc(forReplay, F(STR_MAX_ACCELERATION));
SERIAL_ECHOLNPGM_P( #if NUM_AXES
SERIAL_ECHOPGM_P(
LIST_N(DOUBLE(NUM_AXES), LIST_N(DOUBLE(NUM_AXES),
PSTR(" M201 X"), LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[X_AXIS]), 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_Y_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Y_AXIS]),
@ -155,10 +156,17 @@ void GcodeSuite::M201_report(const bool forReplay/*=true*/) {
SP_V_STR, V_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[V_AXIS]), SP_V_STR, V_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[V_AXIS]),
SP_W_STR, W_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[W_AXIS]) SP_W_STR, W_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[W_AXIS])
) )
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
, SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_acceleration_mm_per_s2[E_AXIS])
#endif
); );
#endif
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
SERIAL_ECHOPGM_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_acceleration_mm_per_s2[E_AXIS]));
#endif
#if NUM_AXES || (HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS))
SERIAL_EOL();
#endif
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
for (uint8_t i = 0; i < E_STEPPERS; ++i) { for (uint8_t i = 0; i < E_STEPPERS; ++i) {
report_echo_start(forReplay); report_echo_start(forReplay);
@ -191,7 +199,8 @@ void GcodeSuite::M203() {
void GcodeSuite::M203_report(const bool forReplay/*=true*/) { void GcodeSuite::M203_report(const bool forReplay/*=true*/) {
report_heading_etc(forReplay, F(STR_MAX_FEEDRATES)); report_heading_etc(forReplay, F(STR_MAX_FEEDRATES));
SERIAL_ECHOLNPGM_P( #if NUM_AXES
SERIAL_ECHOPGM_P(
LIST_N(DOUBLE(NUM_AXES), LIST_N(DOUBLE(NUM_AXES),
PSTR(" M203 X"), LINEAR_UNIT(planner.settings.max_feedrate_mm_s[X_AXIS]), 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_Y_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Y_AXIS]),
@ -203,10 +212,17 @@ void GcodeSuite::M203_report(const bool forReplay/*=true*/) {
SP_V_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[V_AXIS]), SP_V_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[V_AXIS]),
SP_W_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[W_AXIS]) SP_W_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[W_AXIS])
) )
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
, SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_feedrate_mm_s[E_AXIS])
#endif
); );
#endif
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
SERIAL_ECHOPGM_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_feedrate_mm_s[E_AXIS]));
#endif
#if NUM_AXES || (HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS))
SERIAL_EOL();
#endif
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
for (uint8_t i = 0; i < E_STEPPERS; ++i) { for (uint8_t i = 0; i < E_STEPPERS; ++i) {
if (!forReplay) SERIAL_ECHO_START(); if (!forReplay) SERIAL_ECHO_START();
@ -281,9 +297,6 @@ void GcodeSuite::M205() {
if (parser.seenval('S')) planner.settings.min_feedrate_mm_s = parser.value_linear_units(); if (parser.seenval('S')) planner.settings.min_feedrate_mm_s = parser.value_linear_units();
if (parser.seenval('T')) planner.settings.min_travel_feedrate_mm_s = parser.value_linear_units(); if (parser.seenval('T')) planner.settings.min_travel_feedrate_mm_s = parser.value_linear_units();
#if HAS_JUNCTION_DEVIATION #if HAS_JUNCTION_DEVIATION
#if HAS_CLASSIC_JERK && AXIS_COLLISION('J')
#error "Can't set_max_jerk for 'J' axis because 'J' is used for Junction Deviation."
#endif
if (parser.seenval('J')) { if (parser.seenval('J')) {
const float junc_dev = parser.value_linear_units(); const float junc_dev = parser.value_linear_units();
if (WITHIN(junc_dev, 0.01f, 0.3f)) { if (WITHIN(junc_dev, 0.01f, 0.3f)) {

View File

@ -95,7 +95,9 @@ void GcodeSuite::M217() {
#if ENABLED(TOOLCHANGE_PARK) #if ENABLED(TOOLCHANGE_PARK)
if (parser.seenval('W')) { toolchange_settings.enable_park = parser.value_linear_units(); } if (parser.seenval('W')) { toolchange_settings.enable_park = parser.value_linear_units(); }
#if HAS_X_AXIS
if (parser.seenval('X')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.x = constrain(v, X_MIN_POS, X_MAX_POS); } if (parser.seenval('X')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.x = constrain(v, X_MIN_POS, X_MAX_POS); }
#endif
#if HAS_Y_AXIS #if HAS_Y_AXIS
if (parser.seenval('Y')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.y = constrain(v, Y_MIN_POS, Y_MAX_POS); } if (parser.seenval('Y')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.y = constrain(v, Y_MIN_POS, Y_MAX_POS); }
#endif #endif
@ -183,8 +185,9 @@ void GcodeSuite::M217_report(const bool forReplay/*=true*/) {
#endif #endif
#if ENABLED(TOOLCHANGE_PARK) #if ENABLED(TOOLCHANGE_PARK)
{
SERIAL_ECHOPGM(" W", LINEAR_UNIT(toolchange_settings.enable_park)); SERIAL_ECHOPGM(" W", LINEAR_UNIT(toolchange_settings.enable_park));
#if NUM_AXES
{
SERIAL_ECHOPGM_P( SERIAL_ECHOPGM_P(
SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x) SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x)
#if HAS_Y_AXIS #if HAS_Y_AXIS
@ -203,6 +206,7 @@ void GcodeSuite::M217_report(const bool forReplay/*=true*/) {
); );
} }
#endif #endif
#endif
#if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED) #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
SERIAL_ECHOPGM(" V", LINEAR_UNIT(enable_first_prime)); SERIAL_ECHOPGM(" V", LINEAR_UNIT(enable_first_prime));

View File

@ -46,9 +46,15 @@ void GcodeSuite::M218() {
const int8_t target_extruder = get_target_extruder_from_command(); const int8_t target_extruder = get_target_extruder_from_command();
if (target_extruder < 0) return; if (target_extruder < 0) return;
#if HAS_X_AXIS
if (parser.seenval('X')) hotend_offset[target_extruder].x = parser.value_linear_units(); if (parser.seenval('X')) hotend_offset[target_extruder].x = parser.value_linear_units();
#endif
#if HAS_Y_AXIS
if (parser.seenval('Y')) hotend_offset[target_extruder].y = parser.value_linear_units(); if (parser.seenval('Y')) hotend_offset[target_extruder].y = parser.value_linear_units();
#endif
#if HAS_Z_AXIS
if (parser.seenval('Z')) hotend_offset[target_extruder].z = parser.value_linear_units(); if (parser.seenval('Z')) hotend_offset[target_extruder].z = parser.value_linear_units();
#endif
#if ENABLED(DELTA) #if ENABLED(DELTA)
if (target_extruder == active_extruder) if (target_extruder == active_extruder)

View File

@ -66,6 +66,9 @@ void GcodeSuite::M281_report(const bool forReplay/*=true*/) {
#endif #endif
#elif ENABLED(SWITCHING_NOZZLE) #elif ENABLED(SWITCHING_NOZZLE)
case SWITCHING_NOZZLE_SERVO_NR: case SWITCHING_NOZZLE_SERVO_NR:
#if ENABLED(SWITCHING_NOZZLE_TWO_SERVOS)
case SWITCHING_NOZZLE_E1_SERVO_NR:
#endif
#elif ENABLED(BLTOUCH) || (HAS_Z_SERVO_PROBE && defined(Z_SERVO_ANGLES)) #elif ENABLED(BLTOUCH) || (HAS_Z_SERVO_PROBE && defined(Z_SERVO_ANGLES))
case Z_PROBE_SERVO_NR: case Z_PROBE_SERVO_NR:
#endif #endif

View File

@ -93,6 +93,8 @@ void GcodeSuite::M92() {
void GcodeSuite::M92_report(const bool forReplay/*=true*/, const int8_t e/*=-1*/) { void GcodeSuite::M92_report(const bool forReplay/*=true*/, const int8_t e/*=-1*/) {
report_heading_etc(forReplay, F(STR_STEPS_PER_UNIT)); report_heading_etc(forReplay, F(STR_STEPS_PER_UNIT));
#if NUM_AXES
#define PRINT_EOL
SERIAL_ECHOPGM_P(LIST_N(DOUBLE(NUM_AXES), SERIAL_ECHOPGM_P(LIST_N(DOUBLE(NUM_AXES),
PSTR(" M92 X"), LINEAR_UNIT(planner.settings.axis_steps_per_mm[X_AXIS]), 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_Y_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Y_AXIS]),
@ -104,10 +106,14 @@ void GcodeSuite::M92_report(const bool forReplay/*=true*/, const int8_t e/*=-1*/
SP_V_STR, V_AXIS_UNIT(planner.settings.axis_steps_per_mm[V_AXIS]), SP_V_STR, V_AXIS_UNIT(planner.settings.axis_steps_per_mm[V_AXIS]),
SP_W_STR, W_AXIS_UNIT(planner.settings.axis_steps_per_mm[W_AXIS]) SP_W_STR, W_AXIS_UNIT(planner.settings.axis_steps_per_mm[W_AXIS])
)); ));
#endif
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS) #if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
#define PRINT_EOL
SERIAL_ECHOPGM_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS])); SERIAL_ECHOPGM_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS]));
#endif #endif
SERIAL_EOL();
if (ENABLED(PRINT_EOL)) SERIAL_EOL();
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
for (uint8_t i = 0; i < E_STEPPERS; ++i) { for (uint8_t i = 0; i < E_STEPPERS; ++i) {

View File

@ -55,23 +55,20 @@ void GcodeSuite::M111() {
} }
else { else {
SERIAL_ECHOPGM(STR_DEBUG_OFF); SERIAL_ECHOPGM(STR_DEBUG_OFF);
#if !defined(__AVR__) || !defined(USBCON) #if !(defined(__AVR__) && defined(USBCON))
#if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS) #if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS)
SERIAL_ECHOPGM("\nBuffer Overruns: ", MYSERIAL1.buffer_overruns()); SERIAL_ECHOPGM("\nBuffer Overruns: ", MYSERIAL1.buffer_overruns());
#endif #endif
#if ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS) #if ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS)
SERIAL_ECHOPGM("\nFraming Errors: ", MYSERIAL1.framing_errors()); SERIAL_ECHOPGM("\nFraming Errors: ", MYSERIAL1.framing_errors());
#endif #endif
#if ENABLED(SERIAL_STATS_DROPPED_RX) #if ENABLED(SERIAL_STATS_DROPPED_RX)
SERIAL_ECHOPGM("\nDropped bytes: ", MYSERIAL1.dropped()); SERIAL_ECHOPGM("\nDropped bytes: ", MYSERIAL1.dropped());
#endif #endif
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
SERIAL_ECHOPGM("\nMax RX Queue Size: ", MYSERIAL1.rxMaxEnqueued()); SERIAL_ECHOPGM("\nMax RX Queue Size: ", MYSERIAL1.rxMaxEnqueued());
#endif #endif
#endif // !__AVR__ || !USBCON #endif // !(__AVR__ && USBCON)
} }
SERIAL_EOL(); SERIAL_EOL();
} }

View File

@ -48,6 +48,7 @@ inline stepper_flags_t selected_axis_bits() {
selected.bits = e_axis_mask; selected.bits = e_axis_mask;
} }
#endif #endif
#if NUM_AXES
selected.bits |= NUM_AXIS_GANG( selected.bits |= NUM_AXIS_GANG(
(parser.seen_test('X') << X_AXIS), (parser.seen_test('X') << X_AXIS),
| (parser.seen_test('Y') << Y_AXIS), | (parser.seen_test('Y') << Y_AXIS),
@ -59,6 +60,7 @@ inline stepper_flags_t selected_axis_bits() {
| (parser.seen_test(AXIS8_NAME) << V_AXIS), | (parser.seen_test(AXIS8_NAME) << V_AXIS),
| (parser.seen_test(AXIS9_NAME) << W_AXIS) | (parser.seen_test(AXIS9_NAME) << W_AXIS)
); );
#endif
return selected; return selected;
} }

View File

@ -89,19 +89,15 @@ void GcodeSuite::M3_M4(const bool is_M4) {
#endif #endif
auto get_s_power = [] { auto get_s_power = [] {
float u;
if (parser.seenval('S')) { if (parser.seenval('S')) {
const float v = parser.value_float(); const float v = parser.value_float();
u = TERN(LASER_POWER_TRAP, v, cutter.power_to_range(v)); cutter.menuPower = cutter.unitPower = TERN(LASER_POWER_TRAP, v, cutter.power_to_range(v));
} }
else if (cutter.cutter_mode == CUTTER_MODE_STANDARD) else if (cutter.cutter_mode == CUTTER_MODE_STANDARD)
u = cutter.cpwr_to_upwr(SPEED_POWER_STARTUP); cutter.menuPower = cutter.unitPower = cutter.cpwr_to_upwr(SPEED_POWER_STARTUP);
cutter.menuPower = cutter.unitPower = u;
// PWM not implied, power converted to OCR from unit definition and on/off if not PWM. // PWM not implied, power converted to OCR from unit definition and on/off if not PWM.
cutter.power = TERN(SPINDLE_LASER_USE_PWM, cutter.upower_to_ocr(u), u > 0 ? 255 : 0); cutter.power = TERN(SPINDLE_LASER_USE_PWM, cutter.upower_to_ocr(cutter.unitPower), cutter.unitPower > 0 ? 255 : 0);
return u;
}; };
if (cutter.cutter_mode == CUTTER_MODE_CONTINUOUS || cutter.cutter_mode == CUTTER_MODE_DYNAMIC) { // Laser power in inline mode if (cutter.cutter_mode == CUTTER_MODE_CONTINUOUS || cutter.cutter_mode == CUTTER_MODE_DYNAMIC) { // Laser power in inline mode

View File

@ -25,7 +25,6 @@
#if ENABLED(DIRECT_PIN_CONTROL) #if ENABLED(DIRECT_PIN_CONTROL)
#include "../gcode.h" #include "../gcode.h"
#include "../../MarlinCore.h" // for pin_is_protected
#if HAS_FAN #if HAS_FAN
#include "../../module/temperature.h" #include "../../module/temperature.h"
@ -38,6 +37,8 @@
#define OUTPUT_OPEN_DRAIN OUTPUT_OPEN_DRAIN #define OUTPUT_OPEN_DRAIN OUTPUT_OPEN_DRAIN
#endif #endif
bool pin_is_protected(const pin_t pin);
void protected_pin_err() { void protected_pin_err() {
SERIAL_ERROR_MSG(STR_ERR_PROTECTED_PIN); SERIAL_ERROR_MSG(STR_ERR_PROTECTED_PIN);
} }
@ -53,6 +54,7 @@ void protected_pin_err() {
* I Flag to ignore Marlin's pin protection * I Flag to ignore Marlin's pin protection
* *
* T<mode> Pin mode: 0=INPUT 1=OUTPUT 2=INPUT_PULLUP 3=INPUT_PULLDOWN * T<mode> Pin mode: 0=INPUT 1=OUTPUT 2=INPUT_PULLUP 3=INPUT_PULLDOWN
* 4=INPUT_ANALOG 5=OUTPUT_OPEN_DRAIN
*/ */
void GcodeSuite::M42() { void GcodeSuite::M42() {
const int pin_index = PARSED_PIN_INDEX('P', GET_PIN_MAP_INDEX(LED_PIN)); const int pin_index = PARSED_PIN_INDEX('P', GET_PIN_MAP_INDEX(LED_PIN));

View File

@ -127,25 +127,24 @@
case DXC_MIRRORED_MODE: DEBUG_ECHOPGM("MIRRORED"); break; case DXC_MIRRORED_MODE: DEBUG_ECHOPGM("MIRRORED"); break;
} }
DEBUG_ECHOPGM("\nActive Ext: ", active_extruder); DEBUG_ECHOPGM("\nActive Ext: ", active_extruder);
if (!active_extruder_parked) DEBUG_ECHOPGM(" NOT "); if (!active_extruder_parked) DEBUG_ECHOPGM(" NOT ", F(" parked."));
DEBUG_ECHOPGM(" parked."); DEBUG_ECHOLNPGM(
DEBUG_ECHOPGM("\nactive_extruder_x_pos: ", current_position.x); "\nactive_extruder_x_pos: ", current_position.x,
DEBUG_ECHOPGM("\ninactive_extruder_x: ", inactive_extruder_x); "\ninactive_extruder_x: ", inactive_extruder_x,
DEBUG_ECHOPGM("\nextruder_duplication_enabled: ", extruder_duplication_enabled); "\nextruder_duplication_enabled: ", extruder_duplication_enabled,
DEBUG_ECHOPGM("\nduplicate_extruder_x_offset: ", duplicate_extruder_x_offset); "\nduplicate_extruder_x_offset: ", duplicate_extruder_x_offset,
DEBUG_ECHOPGM("\nduplicate_extruder_temp_offset: ", duplicate_extruder_temp_offset); "\nduplicate_extruder_temp_offset: ", duplicate_extruder_temp_offset,
DEBUG_ECHOPGM("\ndelayed_move_time: ", delayed_move_time); "\ndelayed_move_time: ", delayed_move_time,
DEBUG_ECHOPGM("\nX1 Home X: ", x_home_pos(0), "\nX1_MIN_POS=", X1_MIN_POS, "\nX1_MAX_POS=", X1_MAX_POS); "\nX1 Home: ", x_home_pos(0), " X1_MIN_POS=", X1_MIN_POS, " X1_MAX_POS=", X1_MAX_POS,
DEBUG_ECHOPGM("\nX2 Home X: ", x_home_pos(1), "\nX2_MIN_POS=", X2_MIN_POS, "\nX2_MAX_POS=", X2_MAX_POS); "\nX2 Home: ", x_home_pos(1), " X2_MIN_POS=", X2_MIN_POS, " X2_MAX_POS=", X2_MAX_POS,
DEBUG_ECHOPGM("\nX2_HOME_DIR=", X2_HOME_DIR, "\nX2_HOME_POS=", X2_HOME_POS); "\nDEFAULT_DUAL_X_CARRIAGE_MODE=", STRINGIFY(DEFAULT_DUAL_X_CARRIAGE_MODE),
DEBUG_ECHOPGM("\nDEFAULT_DUAL_X_CARRIAGE_MODE=", STRINGIFY(DEFAULT_DUAL_X_CARRIAGE_MODE)); "\toolchange_settings.z_raise=", toolchange_settings.z_raise,
DEBUG_ECHOPGM("\toolchange_settings.z_raise=", toolchange_settings.z_raise); "\nDEFAULT_DUPLICATION_X_OFFSET=", DEFAULT_DUPLICATION_X_OFFSET
DEBUG_ECHOPGM("\nDEFAULT_DUPLICATION_X_OFFSET=", DEFAULT_DUPLICATION_X_OFFSET); );
DEBUG_EOL();
HOTEND_LOOP() { HOTEND_LOOP() {
DEBUG_ECHOPGM_P(SP_T_STR, e); DEBUG_ECHOPGM_P(SP_T_STR, e);
LOOP_NUM_AXES(a) DEBUG_ECHOPGM(" hotend_offset[", e, "].", AS_CHAR(AXIS_CHAR(a) | 0x20), "=", hotend_offset[e][a]); LOOP_NUM_AXES(a) DEBUG_ECHOPGM(" hotend_offset[", e, "].", C(AXIS_CHAR(a) | 0x20), "=", hotend_offset[e][a]);
DEBUG_EOL(); DEBUG_EOL();
} }
DEBUG_EOL(); DEBUG_EOL();

View File

@ -22,7 +22,7 @@
#include "../../inc/MarlinConfig.h" #include "../../inc/MarlinConfig.h"
#if ALL(SPI_FLASH, HAS_MEDIA, MARLIN_DEV_MODE) #if SPI_FLASH_BACKUP
#include "../gcode.h" #include "../gcode.h"
#include "../../sd/cardreader.h" #include "../../sd/cardreader.h"
@ -85,4 +85,4 @@ void GcodeSuite::M994() {
card.closefile(); card.closefile();
} }
#endif // SPI_FLASH && HAS_MEDIA && MARLIN_DEV_MODE #endif // SPI_FLASH_BACKUP

View File

@ -48,6 +48,14 @@
*/ */
void GcodeSuite::T(const int8_t tool_index) { void GcodeSuite::T(const int8_t tool_index) {
#if HAS_MULTI_EXTRUDER
// For 'T' with no parameter report the current tool.
if (parser.string_arg && *parser.string_arg == '*') {
SERIAL_ECHOLNPGM(STR_ACTIVE_EXTRUDER, active_extruder);
return;
}
#endif
DEBUG_SECTION(log_T, "T", DEBUGGING(LEVELING)); DEBUG_SECTION(log_T, "T", DEBUGGING(LEVELING));
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("...(", tool_index, ")"); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("...(", tool_index, ")");
@ -63,8 +71,8 @@ void GcodeSuite::T(const int8_t tool_index) {
tool_change(tool_index tool_change(tool_index
#if HAS_MULTI_EXTRUDER #if HAS_MULTI_EXTRUDER
, TERN(PARKING_EXTRUDER, false, tool_index == active_extruder) // For PARKING_EXTRUDER motion is decided in tool_change() , parser.boolval('S')
|| parser.boolval('S') || TERN(PARKING_EXTRUDER, false, tool_index == active_extruder) // For PARKING_EXTRUDER motion is decided in tool_change()
#endif #endif
); );
} }

View File

@ -22,7 +22,7 @@
#include "../../../inc/MarlinConfig.h" #include "../../../inc/MarlinConfig.h"
#if HAS_SHAPING #if HAS_ZV_SHAPING
#include "../../gcode.h" #include "../../gcode.h"
#include "../../../module/stepper.h" #include "../../../module/stepper.h"

View File

@ -60,6 +60,7 @@ void GcodeSuite::M150() {
#if ENABLED(NEOPIXEL_LED) #if ENABLED(NEOPIXEL_LED)
const pixel_index_t index = parser.intval('I', -1); const pixel_index_t index = parser.intval('I', -1);
const bool seenK = parser.seen_test('K');
#if ENABLED(NEOPIXEL2_SEPARATE) #if ENABLED(NEOPIXEL2_SEPARATE)
#ifndef NEOPIXEL_M150_DEFAULT #ifndef NEOPIXEL_M150_DEFAULT
#define NEOPIXEL_M150_DEFAULT -1 #define NEOPIXEL_M150_DEFAULT -1
@ -69,12 +70,13 @@ void GcodeSuite::M150() {
int8_t brightness = neo.brightness(), unit = parser.intval('S', NEOPIXEL_M150_DEFAULT); int8_t brightness = neo.brightness(), unit = parser.intval('S', NEOPIXEL_M150_DEFAULT);
switch (unit) { switch (unit) {
case -1: neo2.neoindex = index; // fall-thru case -1: neo2.neoindex = index; // fall-thru
case 0: neo.neoindex = index; old_color = parser.seen('K') ? neo.pixel_color(index >= 0 ? index : 0) : 0; break; case 0: neo.neoindex = index; old_color = seenK ? neo.pixel_color(_MAX(index, 0)) : 0; break;
case 1: neo2.neoindex = index; brightness = neo2.brightness(); old_color = parser.seen('K') ? neo2.pixel_color(index >= 0 ? index : 0) : 0; break; case 1: neo2.neoindex = index; brightness = neo2.brightness(); old_color = seenK ? neo2.pixel_color(_MAX(index, 0)) : 0; break;
} }
#else #else
const uint8_t brightness = neo.brightness(); const uint8_t brightness = neo.brightness();
neo.neoindex = index; neo.neoindex = index;
old_color = seenK ? neo.pixel_color(_MAX(index, 0)) : 0;
#endif #endif
#endif #endif

View File

@ -50,16 +50,19 @@ void GcodeSuite::G60() {
{ {
const xyze_pos_t &pos = stored_position[slot]; const xyze_pos_t &pos = stored_position[slot];
DEBUG_ECHOPGM(STR_SAVED_POS " S", slot, " :"); DEBUG_ECHOPGM(STR_SAVED_POS " S", slot, " :");
DEBUG_ECHOLNPGM_P( #if NUM_AXES
DEBUG_ECHOPGM_P(
LIST_N(DOUBLE(NUM_AXES), LIST_N(DOUBLE(NUM_AXES),
SP_X_LBL, pos.x, SP_Y_LBL, pos.y, SP_Z_LBL, pos.z, SP_X_LBL, pos.x, SP_Y_LBL, pos.y, SP_Z_LBL, pos.z,
SP_I_LBL, pos.i, SP_J_LBL, pos.j, SP_K_LBL, pos.k, SP_I_LBL, pos.i, SP_J_LBL, pos.j, SP_K_LBL, pos.k,
SP_U_LBL, pos.u, SP_V_LBL, pos.v, SP_W_LBL, pos.w SP_U_LBL, pos.u, SP_V_LBL, pos.v, SP_W_LBL, pos.w
) )
#if HAS_EXTRUDERS
, SP_E_LBL, pos.e
#endif
); );
#endif
#if HAS_EXTRUDERS
DEBUG_ECHOPGM_P(SP_E_LBL, pos.e);
#endif
DEBUG_EOL();
} }
#endif #endif
} }

View File

@ -96,7 +96,7 @@ void GcodeSuite::M125() {
const bool show_lcd = TERN0(HAS_MARLINUI_MENU, parser.boolval('P')); const bool show_lcd = TERN0(HAS_MARLINUI_MENU, parser.boolval('P'));
if (pause_print(retract, park_point, show_lcd, 0)) { if (pause_print(retract, park_point, show_lcd, 0)) {
if (ENABLED(EXTENSIBLE_UI) || ALL(EMERGENCY_PARSER, HOST_PROMPT_SUPPORT) || !sd_printing || show_lcd) { if (ENABLED(HAS_DISPLAY) || ALL(EMERGENCY_PARSER, HOST_PROMPT_SUPPORT) || !sd_printing || show_lcd) {
wait_for_confirmation(false, 0); wait_for_confirmation(false, 0);
resume_print(0, 0, -retract, 0); resume_print(0, 0, -retract, 0);
} }

View File

@ -57,10 +57,12 @@ static void set_stealth_status(const bool enable, const int8_t eindex) {
LOOP_LOGICAL_AXES(i) if (parser.seen(AXIS_CHAR(i))) { LOOP_LOGICAL_AXES(i) if (parser.seen(AXIS_CHAR(i))) {
switch (i) { switch (i) {
#if HAS_X_AXIS
case X_AXIS: case X_AXIS:
TERN_(X_HAS_STEALTHCHOP, if (index < 0 || index == 0) TMC_SET_STEALTH(X)); TERN_(X_HAS_STEALTHCHOP, if (index < 0 || index == 0) TMC_SET_STEALTH(X));
TERN_(X2_HAS_STEALTHCHOP, if (index < 0 || index == 1) TMC_SET_STEALTH(X2)); TERN_(X2_HAS_STEALTHCHOP, if (index < 0 || index == 1) TMC_SET_STEALTH(X2));
break; break;
#endif
#if HAS_Y_AXIS #if HAS_Y_AXIS
case Y_AXIS: case Y_AXIS:
@ -198,13 +200,13 @@ void GcodeSuite::M569_report(const bool forReplay/*=true*/) {
if (chop_x2 || chop_y2 || chop_z2) { if (chop_x2 || chop_y2 || chop_z2) {
say_M569(forReplay, F("I1")); say_M569(forReplay, F("I1"));
if (chop_x2) SERIAL_ECHOPGM_P(SP_X_STR); NUM_AXIS_CODE(
#if HAS_Y_AXIS if (chop_x2) SERIAL_ECHOPGM_P(SP_X_STR),
if (chop_y2) SERIAL_ECHOPGM_P(SP_Y_STR); if (chop_y2) SERIAL_ECHOPGM_P(SP_Y_STR),
#endif if (chop_z2) SERIAL_ECHOPGM_P(SP_Z_STR),
#if HAS_Z_AXIS NOOP, NOOP, NOOP,
if (chop_z2) SERIAL_ECHOPGM_P(SP_Z_STR); NOOP, NOOP, NOOP
#endif );
SERIAL_EOL(); SERIAL_EOL();
} }

View File

@ -35,7 +35,7 @@
#define M91x_USE(ST) (AXIS_DRIVER_TYPE(ST, TMC2130) || AXIS_DRIVER_TYPE(ST, TMC2160) || AXIS_DRIVER_TYPE(ST, TMC2208) || AXIS_DRIVER_TYPE(ST, TMC2209) || AXIS_DRIVER_TYPE(ST, TMC2660) || AXIS_DRIVER_TYPE(ST, TMC5130) || AXIS_DRIVER_TYPE(ST, TMC5160)) #define M91x_USE(ST) (AXIS_DRIVER_TYPE(ST, TMC2130) || AXIS_DRIVER_TYPE(ST, TMC2160) || AXIS_DRIVER_TYPE(ST, TMC2208) || AXIS_DRIVER_TYPE(ST, TMC2209) || AXIS_DRIVER_TYPE(ST, TMC2660) || AXIS_DRIVER_TYPE(ST, TMC5130) || AXIS_DRIVER_TYPE(ST, TMC5160))
#define M91x_USE_E(N) (E_STEPPERS > N && M91x_USE(E##N)) #define M91x_USE_E(N) (E_STEPPERS > N && M91x_USE(E##N))
#if M91x_USE(X) || M91x_USE(X2) #if HAS_X_AXIS && (M91x_USE(X) || M91x_USE(X2))
#define M91x_SOME_X 1 #define M91x_SOME_X 1
#endif #endif
#if HAS_Y_AXIS && (M91x_USE(Y) || M91x_USE(Y2)) #if HAS_Y_AXIS && (M91x_USE(Y) || M91x_USE(Y2))

View File

@ -118,7 +118,7 @@ void GcodeSuite::M919() {
// Get the chopper timing for the specified axis and index // Get the chopper timing for the specified axis and index
switch (i) { switch (i) {
default: // A specified axis isn't Trinamic default: // A specified axis isn't Trinamic
SERIAL_ECHOLNPGM("?Axis ", AS_CHAR(AXIS_CHAR(i)), " has no TMC drivers."); SERIAL_ECHOLNPGM("?Axis ", C(AXIS_CHAR(i)), " has no TMC drivers.");
break; break;
#if AXIS_IS_TMC(X) || AXIS_IS_TMC(X2) #if AXIS_IS_TMC(X) || AXIS_IS_TMC(X2)

View File

@ -81,7 +81,7 @@ millis_t GcodeSuite::previous_move_ms = 0,
// Relative motion mode for each logical axis // Relative motion mode for each logical axis
static constexpr xyze_bool_t ar_init = AXIS_RELATIVE_MODES; static constexpr xyze_bool_t ar_init = AXIS_RELATIVE_MODES;
axis_bits_t GcodeSuite::axis_relative = 0 LOGICAL_AXIS_GANG( relative_t GcodeSuite::axis_relative = 0 LOGICAL_AXIS_GANG(
| (ar_init.e << REL_E), | (ar_init.e << REL_E),
| (ar_init.x << REL_X), | (ar_init.x << REL_X),
| (ar_init.y << REL_Y), | (ar_init.y << REL_Y),
@ -581,7 +581,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 102: M102(); break; // M102: Configure Bed Distance Sensor case 102: M102(); break; // M102: Configure Bed Distance Sensor
#endif #endif
#if HAS_EXTRUDERS #if HAS_HOTEND
case 104: M104(); break; // M104: Set hot end temperature case 104: M104(); break; // M104: Set hot end temperature
case 109: M109(); break; // M109: Wait for hotend temperature to reach target case 109: M109(); break; // M109: Wait for hotend temperature to reach target
#endif #endif
@ -934,7 +934,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 575: M575(); break; // M575: Set serial baudrate case 575: M575(); break; // M575: Set serial baudrate
#endif #endif
#if HAS_SHAPING #if HAS_ZV_SHAPING
case 593: M593(); break; // M593: Set Input Shaping parameters case 593: M593(); break; // M593: Set Input Shaping parameters
#endif #endif
@ -1058,7 +1058,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 422: M422(); break; // M422: Set Z Stepper automatic alignment position using probe case 422: M422(); break; // M422: Set Z Stepper automatic alignment position using probe
#endif #endif
#if ALL(SPI_FLASH, HAS_MEDIA, MARLIN_DEV_MODE) #if SPI_FLASH_BACKUP
case 993: M993(); break; // M993: Backup SPI Flash to SD case 993: M993(); break; // M993: Backup SPI Flash to SD
case 994: M994(); break; // M994: Load a Backup from SD to SPI Flash case 994: M994(); break; // M994: Load a Backup from SD to SPI Flash
#endif #endif
@ -1121,7 +1121,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
if (!no_ok) queue.ok_to_send(); if (!no_ok) queue.ok_to_send();
SERIAL_OUT(msgDone); // Call the msgDone serial hook to signal command processing done SERIAL_IMPL.msgDone(); // Call the msgDone serial hook to signal command processing done
} }
#if ENABLED(M100_FREE_MEMORY_DUMPER) #if ENABLED(M100_FREE_MEMORY_DUMPER)

View File

@ -300,6 +300,7 @@
* M913 - Set HYBRID_THRESHOLD speed. (Requires HYBRID_THRESHOLD) * M913 - Set HYBRID_THRESHOLD speed. (Requires HYBRID_THRESHOLD)
* M914 - Set StallGuard sensitivity. (Requires SENSORLESS_HOMING or SENSORLESS_PROBING) * M914 - Set StallGuard sensitivity. (Requires SENSORLESS_HOMING or SENSORLESS_PROBING)
* M919 - Get or Set motor Chopper Times (time_off, hysteresis_end, hysteresis_start) using axis codes XYZE, etc. If no parameters are given, report. (Requires at least one _DRIVER_TYPE defined as TMC2130/2160/5130/5160/2208/2209/2660) * M919 - Get or Set motor Chopper Times (time_off, hysteresis_end, hysteresis_start) using axis codes XYZE, etc. If no parameters are given, report. (Requires at least one _DRIVER_TYPE defined as TMC2130/2160/5130/5160/2208/2209/2660)
* M936 - OTA update firmware. (Requires OTA_FIRMWARE_UPDATE)
* M951 - Set Magnetic Parking Extruder parameters. (Requires MAGNETIC_PARKING_EXTRUDER) * M951 - Set Magnetic Parking Extruder parameters. (Requires MAGNETIC_PARKING_EXTRUDER)
* M3426 - Read MCP3426 ADC over I2C. (Requires HAS_MCP3426_ADC) * M3426 - Read MCP3426 ADC over I2C. (Requires HAS_MCP3426_ADC)
* M7219 - Control Max7219 Matrix LEDs. (Requires MAX7219_GCODE) * M7219 - Control Max7219 Matrix LEDs. (Requires MAX7219_GCODE)
@ -344,14 +345,20 @@ enum AxisRelative : uint8_t {
#if HAS_EXTRUDERS #if HAS_EXTRUDERS
, E_MODE_ABS, E_MODE_REL , E_MODE_ABS, E_MODE_REL
#endif #endif
, NUM_REL_MODES
}; };
typedef bits_t(NUM_REL_MODES) relative_t;
extern const char G28_STR[]; extern const char G28_STR[];
class GcodeSuite { class GcodeSuite {
public: public:
static axis_bits_t axis_relative; static relative_t axis_relative;
GcodeSuite() { // Relative motion mode for each logical axis
axis_relative = AxisBits(AXIS_RELATIVE_MODES).bits;
}
static bool axis_is_relative(const AxisEnum a) { static bool axis_is_relative(const AxisEnum a) {
#if HAS_EXTRUDERS #if HAS_EXTRUDERS
@ -713,7 +720,7 @@ private:
static void M102_report(const bool forReplay=true); static void M102_report(const bool forReplay=true);
#endif #endif
#if HAS_EXTRUDERS #if HAS_HOTEND
static void M104_M109(const bool isM109); static void M104_M109(const bool isM109);
FORCE_INLINE static void M104() { M104_M109(false); } FORCE_INLINE static void M104() { M104_M109(false); }
FORCE_INLINE static void M109() { M104_M109(true); } FORCE_INLINE static void M109() { M104_M109(true); }
@ -1081,7 +1088,7 @@ private:
static void M575(); static void M575();
#endif #endif
#if HAS_SHAPING #if HAS_ZV_SHAPING
static void M593(); static void M593();
static void M593_report(const bool forReplay=true); static void M593_report(const bool forReplay=true);
#endif #endif

View File

@ -39,22 +39,15 @@
//#define MINIMAL_CAP_LINES // Don't even mention the disabled capabilities //#define MINIMAL_CAP_LINES // Don't even mention the disabled capabilities
#if ENABLED(EXTENDED_CAPABILITIES_REPORT) #if ENABLED(EXTENDED_CAPABILITIES_REPORT)
inline void cap_line(FSTR_P const name, const bool ena=true) {
#if ENABLED(MINIMAL_CAP_LINES) #if ENABLED(MINIMAL_CAP_LINES)
#define cap_line(S,C) if (C) _cap_line(S) if (ena) SERIAL_ECHOLNPGM("Cap:", name, ":1");
static void _cap_line(FSTR_P const name) {
SERIAL_ECHOPGM("Cap:");
SERIAL_ECHOF(name);
SERIAL_ECHOLNPGM(":1");
}
#else #else
#define cap_line(V...) _cap_line(V) SERIAL_ECHOPGM("Cap:", name);
static void _cap_line(FSTR_P const name, bool ena=false) {
SERIAL_ECHOPGM("Cap:");
SERIAL_ECHOF(name);
SERIAL_CHAR(':', '0' + ena); SERIAL_CHAR(':', '0' + ena);
SERIAL_EOL(); SERIAL_EOL();
}
#endif #endif
}
#endif #endif
/** /**
@ -104,10 +97,10 @@ void GcodeSuite::M115() {
serial_index_t port = queue.ring_buffer.command_port(); serial_index_t port = queue.ring_buffer.command_port();
// PAREN_COMMENTS // PAREN_COMMENTS
TERN_(PAREN_COMMENTS, cap_line(F("PAREN_COMMENTS"), true)); TERN_(PAREN_COMMENTS, cap_line(F("PAREN_COMMENTS")));
// QUOTED_STRINGS // QUOTED_STRINGS
TERN_(GCODE_QUOTED_STRINGS, cap_line(F("QUOTED_STRINGS"), true)); TERN_(GCODE_QUOTED_STRINGS, cap_line(F("QUOTED_STRINGS")));
// SERIAL_XON_XOFF // SERIAL_XON_XOFF
cap_line(F("SERIAL_XON_XOFF"), ENABLED(SERIAL_XON_XOFF)); cap_line(F("SERIAL_XON_XOFF"), ENABLED(SERIAL_XON_XOFF));
@ -128,10 +121,10 @@ void GcodeSuite::M115() {
cap_line(F("AUTOREPORT_TEMP"), ENABLED(AUTO_REPORT_TEMPERATURES)); cap_line(F("AUTOREPORT_TEMP"), ENABLED(AUTO_REPORT_TEMPERATURES));
// PROGRESS (M530 S L, M531 <file>, M532 X L) // PROGRESS (M530 S L, M531 <file>, M532 X L)
cap_line(F("PROGRESS")); cap_line(F("PROGRESS"), false);
// Print Job timer M75, M76, M77 // Print Job timer M75, M76, M77
cap_line(F("PRINT_JOB"), true); cap_line(F("PRINT_JOB"));
// AUTOLEVEL (G29) // AUTOLEVEL (G29)
cap_line(F("AUTOLEVEL"), ENABLED(HAS_AUTOLEVEL)); cap_line(F("AUTOLEVEL"), ENABLED(HAS_AUTOLEVEL));
@ -157,9 +150,9 @@ void GcodeSuite::M115() {
// SPINDLE AND LASER CONTROL (M3, M4, M5) // SPINDLE AND LASER CONTROL (M3, M4, M5)
#if ENABLED(SPINDLE_FEATURE) #if ENABLED(SPINDLE_FEATURE)
cap_line(F("SPINDLE"), true); cap_line(F("SPINDLE"));
#elif ENABLED(LASER_FEATURE) #elif ENABLED(LASER_FEATURE)
cap_line(F("LASER"), true); cap_line(F("LASER"));
#endif #endif
// EMERGENCY_PARSER (M108, M112, M410, M876) // EMERGENCY_PARSER (M108, M112, M410, M876)
@ -236,7 +229,7 @@ void GcodeSuite::M115() {
const xyz_pos_t lmin = dmin.asLogical(), lmax = dmax.asLogical(), const xyz_pos_t lmin = dmin.asLogical(), lmax = dmax.asLogical(),
wmin = cmin.asLogical(), wmax = cmax.asLogical(); wmin = cmin.asLogical(), wmax = cmax.asLogical();
SERIAL_ECHOLNPGM( SERIAL_ECHOPGM(
"area:{" "area:{"
"full:{" "full:{"
"min:{" "min:{"
@ -253,6 +246,8 @@ void GcodeSuite::M115() {
), ),
"}" // max "}" // max
"}," // full "}," // full
);
SERIAL_ECHOLNPGM(
"work:{" "work:{"
"min:{" "min:{"
LIST_N(DOUBLE(NUM_AXES), LIST_N(DOUBLE(NUM_AXES),

View File

@ -37,7 +37,7 @@ static void config_prefix(PGM_P const name, PGM_P const pref=nullptr, const int8
SERIAL_ECHOPGM("Config:"); SERIAL_ECHOPGM("Config:");
if (pref) SERIAL_ECHOPGM_P(pref); if (pref) SERIAL_ECHOPGM_P(pref);
if (ind >= 0) { SERIAL_ECHO(ind); SERIAL_CHAR(':'); } if (ind >= 0) { SERIAL_ECHO(ind); SERIAL_CHAR(':'); }
SERIAL_ECHOPGM_P(name, AS_CHAR(':')); SERIAL_ECHOPGM_P(name, C(':'));
} }
static void config_line(PGM_P const name, const float val, PGM_P const pref=nullptr, const int8_t ind=-1) { static void config_line(PGM_P const name, const float val, PGM_P const pref=nullptr, const int8_t ind=-1) {
config_prefix(name, pref, ind); config_prefix(name, pref, ind);

View File

@ -30,10 +30,24 @@
#include "../../libs/buzzer.h" // Buzzer, if possible #include "../../libs/buzzer.h" // Buzzer, if possible
/** /**
* M300: Play beep sound S<frequency Hz> P<duration ms> * M300: Play a Tone / Add a tone to the queue
*
* S<frequency> - (Hz) The frequency of the tone. 0 for silence.
* P<duration> - (ms) The duration of the tone.
*
* With SOUND_MENU_ITEM:
* E<0|1> - Mute or enable sound
*/ */
void GcodeSuite::M300() { void GcodeSuite::M300() {
uint16_t const frequency = parser.ushortval('S', 260);
#if ENABLED(SOUND_MENU_ITEM)
if (parser.seen('E')) {
ui.sound_on = parser.value_bool();
return;
}
#endif
const uint16_t frequency = parser.ushortval('S', 260);
uint16_t duration = parser.ushortval('P', 1000); uint16_t duration = parser.ushortval('P', 1000);
// Limits the tone duration to 0-5 seconds. // Limits the tone duration to 0-5 seconds.

View File

@ -38,7 +38,8 @@ void GcodeSuite::G4() {
SERIAL_ECHOLNPGM(STR_Z_MOVE_COMP); SERIAL_ECHOLNPGM(STR_Z_MOVE_COMP);
#endif #endif
if (dwell_ms) {
if (!ui.has_status()) LCD_MESSAGE(MSG_DWELL); if (!ui.has_status()) LCD_MESSAGE(MSG_DWELL);
dwell(dwell_ms); dwell(dwell_ms);
}
} }

View File

@ -189,7 +189,13 @@ void GCodeParser::parse(char *p) {
#endif #endif
// Bail if there's no command code number // Bail if there's no command code number
if (!TERN(SIGNED_CODENUM, NUMERIC_SIGNED(*p), NUMERIC(*p))) return; if (!TERN(SIGNED_CODENUM, NUMERIC_SIGNED(*p), NUMERIC(*p))) {
if (TERN0(HAS_MULTI_EXTRUDER, letter == 'T')) {
p[0] = '*'; p[1] = '\0'; string_arg = p; // Convert 'T' alone into 'T*'
command_letter = letter;
}
return;
}
// Save the command letter at this point // Save the command letter at this point
// A '?' signifies an unknown command // A '?' signifies an unknown command
@ -333,7 +339,7 @@ void GCodeParser::parse(char *p) {
#if ENABLED(DEBUG_GCODE_PARSER) #if ENABLED(DEBUG_GCODE_PARSER)
if (debug) { if (debug) {
SERIAL_ECHOPGM("Got param ", AS_CHAR(param), " at index ", p - command_ptr - 1); SERIAL_ECHOPGM("Got param ", C(param), " at index ", p - command_ptr - 1);
if (has_val) SERIAL_ECHOPGM(" (has_val)"); if (has_val) SERIAL_ECHOPGM(" (has_val)");
} }
#endif #endif

View File

@ -288,6 +288,17 @@ public:
// Bool is true with no value or non-zero // Bool is true with no value or non-zero
static bool value_bool() { return !has_value() || !!value_byte(); } static bool value_bool() { return !has_value() || !!value_byte(); }
static constexpr bool axis_is_rotational(const AxisEnum axis) {
return (false
|| TERN0(AXIS4_ROTATES, axis == I_AXIS)
|| TERN0(AXIS5_ROTATES, axis == J_AXIS)
|| TERN0(AXIS6_ROTATES, axis == K_AXIS)
|| TERN0(AXIS7_ROTATES, axis == U_AXIS)
|| TERN0(AXIS8_ROTATES, axis == V_AXIS)
|| TERN0(AXIS9_ROTATES, axis == W_AXIS)
);
}
// Units modes: Inches, Fahrenheit, Kelvin // Units modes: Inches, Fahrenheit, Kelvin
#if ENABLED(INCH_MODE_SUPPORT) #if ENABLED(INCH_MODE_SUPPORT)
@ -307,14 +318,7 @@ public:
} }
static float axis_unit_factor(const AxisEnum axis) { static float axis_unit_factor(const AxisEnum axis) {
if (false if (axis_is_rotational(axis)) return 1.0f;
|| TERN0(AXIS4_ROTATES, axis == I_AXIS)
|| TERN0(AXIS5_ROTATES, axis == J_AXIS)
|| TERN0(AXIS6_ROTATES, axis == K_AXIS)
|| TERN0(AXIS7_ROTATES, axis == U_AXIS)
|| TERN0(AXIS8_ROTATES, axis == V_AXIS)
|| TERN0(AXIS9_ROTATES, axis == W_AXIS)
) return 1.0f;
#if HAS_EXTRUDERS #if HAS_EXTRUDERS
if (axis >= E_AXIS && volumetric_enabled) return volumetric_unit_factor; if (axis >= E_AXIS && volumetric_enabled) return volumetric_unit_factor;
#endif #endif
@ -327,12 +331,12 @@ public:
#else #else
static float mm_to_linear_unit(const_float_t mm) { return mm; } static constexpr float mm_to_linear_unit(const_float_t mm) { return mm; }
static float mm_to_volumetric_unit(const_float_t mm) { return mm; } static constexpr float mm_to_volumetric_unit(const_float_t mm) { return mm; }
static float linear_value_to_mm(const_float_t v) { return v; } static constexpr float linear_value_to_mm(const_float_t v) { return v; }
static float axis_value_to_mm(const AxisEnum, const float v) { return v; } static constexpr float axis_value_to_mm(const AxisEnum, const float v) { return v; }
static float per_axis_value(const AxisEnum, const float v) { return v; } static constexpr float per_axis_value(const AxisEnum, const float v) { return v; }
#endif #endif
@ -402,7 +406,7 @@ public:
#else // !TEMPERATURE_UNITS_SUPPORT #else // !TEMPERATURE_UNITS_SUPPORT
static float to_temp_units(int16_t c) { return (float)c; } static constexpr float to_temp_units(int16_t c) { return (float)c; }
static celsius_t value_celsius() { return value_int(); } static celsius_t value_celsius() { return value_int(); }
static celsius_t value_celsius_diff() { return value_int(); } static celsius_t value_celsius_diff() { return value_int(); }

View File

@ -37,14 +37,6 @@ GCodeQueue queue;
#include "../MarlinCore.h" #include "../MarlinCore.h"
#include "../core/bug_on.h" #include "../core/bug_on.h"
#if ENABLED(PRINTER_EVENT_LEDS)
#include "../feature/leds/printer_event_leds.h"
#endif
#if HAS_ETHERNET
#include "../feature/ethernet.h"
#endif
#if ENABLED(BINARY_FILE_TRANSFER) #if ENABLED(BINARY_FILE_TRANSFER)
#include "../feature/binary_stream.h" #include "../feature/binary_stream.h"
#endif #endif
@ -307,6 +299,24 @@ static bool serial_data_available(serial_index_t index) {
inline int read_serial(const serial_index_t index) { return SERIAL_IMPL.read(index); } inline int read_serial(const serial_index_t index) { return SERIAL_IMPL.read(index); }
#if (defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32)) && defined(USBCON)
/**
* arduinoststm32's USB receive buffer is not well behaved when the buffer overflows
*
* This can happen when the host programs (such as Pronterface) automatically
* send M105 temperature requests.
*/
void GCodeQueue::flush_rx() {
// Flush receive buffer
for (uint8_t p = 0; p < NUM_SERIAL; ++p) {
if (!serial_data_available(p)) continue; // No data for this port? Skip.
while (SERIAL_IMPL.available(p)) (void)read_serial(p);
}
}
#endif // (ARDUINO_ARCH_STM32F4 || ARDUINO_ARCH_STM32) && USBCON
void GCodeQueue::gcode_line_error(FSTR_P const ferr, const serial_index_t serial_ind) { void GCodeQueue::gcode_line_error(FSTR_P const ferr, const serial_index_t serial_ind) {
PORT_REDIRECT(SERIAL_PORTMASK(serial_ind)); // Reply to the serial port that sent the command PORT_REDIRECT(SERIAL_PORTMASK(serial_ind)); // Reply to the serial port that sent the command
SERIAL_ERROR_START(); SERIAL_ERROR_START();

View File

@ -201,6 +201,12 @@ public:
*/ */
static void flush_and_request_resend(const serial_index_t serial_ind); static void flush_and_request_resend(const serial_index_t serial_ind);
#if (defined(ARDUINO_ARCH_STM32F4) || defined(ARDUINO_ARCH_STM32)) && defined(USBCON)
static void flush_rx();
#else
static void flush_rx() {}
#endif
/** /**
* (Re)Set the current line number for the last received command * (Re)Set the current line number for the last received command
*/ */

View File

@ -29,9 +29,19 @@
/** /**
* M34: Set SD Card Sorting Options * M34: Set SD Card Sorting Options
*
* S - Default sorting (i.e., SDSORT_REVERSE)
* S-1 - Reverse alpha sorting
* S0 - FID Order (not always newest)
* S1 - Forward alpha sorting
* S2 - Alias for S-1 [deprecated]
*
* F-1 - Folders above files
* F0 - Sort According to 'S'
* F1 - Folders after files
*/ */
void GcodeSuite::M34() { void GcodeSuite::M34() {
if (parser.seen('S')) card.setSortOn(parser.value_bool()); if (parser.seen('S')) card.setSortOn(SortFlag(parser.ushortval('S', TERN(SDSORT_REVERSE, AS_REV, AS_FWD))));
if (parser.seenval('F')) { if (parser.seenval('F')) {
const int v = parser.value_long(); const int v = parser.value_long();
card.setSortFolders(v < 0 ? -1 : v > 0 ? 1 : 0); card.setSortFolders(v < 0 ? -1 : v > 0 ? 1 : 0);

View File

@ -28,7 +28,7 @@
#include "../../inc/MarlinConfigPre.h" #include "../../inc/MarlinConfigPre.h"
#if HAS_EXTRUDERS #if HAS_HOTEND
#include "../gcode.h" #include "../gcode.h"
#include "../../module/temperature.h" #include "../../module/temperature.h"
@ -45,10 +45,6 @@
#endif #endif
#endif #endif
#if ENABLED(SINGLENOZZLE_STANDBY_TEMP)
#include "../../module/tool_change.h"
#endif
/** /**
* M104: Set Hotend Temperature target and return immediately * M104: Set Hotend Temperature target and return immediately
* M109: Set Hotend Temperature target and wait * M109: Set Hotend Temperature target and wait
@ -135,4 +131,4 @@ void GcodeSuite::M104_M109(const bool isM109) {
(void)thermalManager.wait_for_hotend(target_extruder, no_wait_for_cooling); (void)thermalManager.wait_for_hotend(target_extruder, no_wait_for_cooling);
} }
#endif // EXTRUDERS #endif // HAS_HOTEND

View File

@ -87,13 +87,15 @@ void GcodeSuite::M140_M190(const bool isM190) {
// With PRINTJOB_TIMER_AUTOSTART, M190 can start the timer, and M140 can stop it // With PRINTJOB_TIMER_AUTOSTART, M190 can start the timer, and M140 can stop it
TERN_(PRINTJOB_TIMER_AUTOSTART, thermalManager.auto_job_check_timer(isM190, !isM190)); TERN_(PRINTJOB_TIMER_AUTOSTART, thermalManager.auto_job_check_timer(isM190, !isM190));
if (isM190) if (isM190) {
thermalManager.wait_for_bed(no_wait_for_cooling); thermalManager.wait_for_bed(no_wait_for_cooling);
else }
else {
ui.set_status_reset_fn([]{ ui.set_status_reset_fn([]{
const celsius_t c = thermalManager.degTargetBed(); const celsius_t c = thermalManager.degTargetBed();
return c < 30 || thermalManager.degBedNear(c); return c < 30 || thermalManager.degBedNear(c);
}); });
}
} }
#endif // HAS_HEATED_BED #endif // HAS_HEATED_BED

View File

@ -25,6 +25,7 @@
#if HAS_PID_HEATING #if HAS_PID_HEATING
#include "../gcode.h" #include "../gcode.h"
#include "../queue.h" // for flush_tx
#include "../../lcd/marlinui.h" #include "../../lcd/marlinui.h"
#include "../../module/temperature.h" #include "../../module/temperature.h"
@ -94,6 +95,8 @@ void GcodeSuite::M303() {
LCD_MESSAGE(MSG_PID_AUTOTUNE); LCD_MESSAGE(MSG_PID_AUTOTUNE);
thermalManager.PID_autotune(temp, hid, c, u); thermalManager.PID_autotune(temp, hid, c, u);
ui.reset_status(); ui.reset_status();
queue.flush_rx();
} }
#endif // HAS_PID_HEATING #endif // HAS_PID_HEATING

View File

@ -52,15 +52,15 @@ void GcodeSuite::M306() {
if (parser.seen("ACFPRH")) { if (parser.seen("ACFPRH")) {
const heater_id_t hid = (heater_id_t)parser.intval('E', 0); const heater_id_t hid = (heater_id_t)parser.intval('E', 0);
MPC_t &constants = thermalManager.temp_hotend[hid].constants; MPC_t &mpc = thermalManager.temp_hotend[hid].mpc;
if (parser.seenval('P')) constants.heater_power = parser.value_float(); if (parser.seenval('P')) mpc.heater_power = parser.value_float();
if (parser.seenval('C')) constants.block_heat_capacity = parser.value_float(); if (parser.seenval('C')) mpc.block_heat_capacity = parser.value_float();
if (parser.seenval('R')) constants.sensor_responsiveness = parser.value_float(); if (parser.seenval('R')) mpc.sensor_responsiveness = parser.value_float();
if (parser.seenval('A')) constants.ambient_xfer_coeff_fan0 = parser.value_float(); if (parser.seenval('A')) mpc.ambient_xfer_coeff_fan0 = parser.value_float();
#if ENABLED(MPC_INCLUDE_FAN) #if ENABLED(MPC_INCLUDE_FAN)
if (parser.seenval('F')) constants.fan255_adjustment = parser.value_float() - constants.ambient_xfer_coeff_fan0; if (parser.seenval('F')) mpc.fan255_adjustment = parser.value_float() - mpc.ambient_xfer_coeff_fan0;
#endif #endif
if (parser.seenval('H')) constants.filament_heat_capacity_permm = parser.value_float(); if (parser.seenval('H')) mpc.filament_heat_capacity_permm = parser.value_float();
return; return;
} }
@ -71,16 +71,16 @@ void GcodeSuite::M306_report(const bool forReplay/*=true*/) {
report_heading(forReplay, F("Model predictive control")); report_heading(forReplay, F("Model predictive control"));
HOTEND_LOOP() { HOTEND_LOOP() {
report_echo_start(forReplay); report_echo_start(forReplay);
MPC_t& constants = thermalManager.temp_hotend[e].constants; MPC_t& mpc = thermalManager.temp_hotend[e].mpc;
SERIAL_ECHOPGM(" M306 E", e); SERIAL_ECHOPGM(" M306 E", e);
SERIAL_ECHOPAIR_F(" P", constants.heater_power, 2); SERIAL_ECHOPAIR_F(" P", mpc.heater_power, 2);
SERIAL_ECHOPAIR_F(" C", constants.block_heat_capacity, 2); SERIAL_ECHOPAIR_F(" C", mpc.block_heat_capacity, 2);
SERIAL_ECHOPAIR_F(" R", constants.sensor_responsiveness, 4); SERIAL_ECHOPAIR_F(" R", mpc.sensor_responsiveness, 4);
SERIAL_ECHOPAIR_F(" A", constants.ambient_xfer_coeff_fan0, 4); SERIAL_ECHOPAIR_F(" A", mpc.ambient_xfer_coeff_fan0, 4);
#if ENABLED(MPC_INCLUDE_FAN) #if ENABLED(MPC_INCLUDE_FAN)
SERIAL_ECHOPAIR_F(" F", constants.ambient_xfer_coeff_fan0 + constants.fan255_adjustment, 4); SERIAL_ECHOPAIR_F(" F", mpc.ambient_xfer_coeff_fan0 + mpc.fan255_adjustment, 4);
#endif #endif
SERIAL_ECHOPAIR_F(" H", constants.filament_heat_capacity_permm, 4); SERIAL_ECHOPAIR_F(" H", mpc.filament_heat_capacity_permm, 4);
SERIAL_EOL(); SERIAL_EOL();
} }
} }

View File

@ -38,7 +38,7 @@ void GcodeSuite::M149() {
void GcodeSuite::M149_report(const bool forReplay/*=true*/) { void GcodeSuite::M149_report(const bool forReplay/*=true*/) {
report_heading_etc(forReplay, F(STR_TEMPERATURE_UNITS)); report_heading_etc(forReplay, F(STR_TEMPERATURE_UNITS));
SERIAL_ECHOPGM(" M149 ", AS_CHAR(parser.temp_units_code()), " ; Units in "); SERIAL_ECHOPGM(" M149 ", C(parser.temp_units_code()), " ; Units in ");
SERIAL_ECHOLNF(parser.temp_units_name()); SERIAL_ECHOLNF(parser.temp_units_name());
} }

View File

@ -72,13 +72,13 @@ void ESDiagClass::Draw() {
DWINUI::Draw_Button(BTN_Continue, 86, 250); DWINUI::Draw_Button(BTN_Continue, 86, 250);
DWINUI::cursor.y = 80; DWINUI::cursor.y = 80;
#define ES_LABEL(S) draw_es_label(F(STR_##S)) #define ES_LABEL(S) draw_es_label(F(STR_##S))
#if HAS_X_MIN #if USE_X_MIN
ES_LABEL(X_MIN); ES_LABEL(X_MIN);
#endif #endif
#if HAS_Y_MIN #if USE_Y_MIN
ES_LABEL(Y_MIN); ES_LABEL(Y_MIN);
#endif #endif
#if HAS_Z_MIN #if USE_Z_MIN
ES_LABEL(Z_MIN); ES_LABEL(Z_MIN);
#endif #endif
#if HAS_FILAMENT_SENSOR #if HAS_FILAMENT_SENSOR
@ -90,13 +90,13 @@ void ESDiagClass::Draw() {
void ESDiagClass::Update() { void ESDiagClass::Update() {
DWINUI::cursor.y = 80; DWINUI::cursor.y = 80;
#define ES_REPORT(S) draw_es_state(READ(S##_PIN) != S##_ENDSTOP_INVERTING) #define ES_REPORT(S) draw_es_state(READ(S##_PIN) != S##_ENDSTOP_INVERTING)
#if HAS_X_MIN #if USE_X_MIN
ES_REPORT(X_MIN); ES_REPORT(X_MIN);
#endif #endif
#if HAS_Y_MIN #if USE_Y_MIN
ES_REPORT(Y_MIN); ES_REPORT(Y_MIN);
#endif #endif
#if HAS_Z_MIN #if USE_Z_MIN
ES_REPORT(Z_MIN); ES_REPORT(Z_MIN);
#endif #endif
#if HAS_FILAMENT_SENSOR #if HAS_FILAMENT_SENSOR

View File

@ -48,11 +48,13 @@ void W25QXXFlash::init(uint8_t spiRate) {
* STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1 * STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1
* so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2 * so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2
*/ */
#ifndef SPI_CLOCK_MAX
#if SPI_DEVICE == 1 #if SPI_DEVICE == 1
#define SPI_CLOCK_MAX SPI_CLOCK_DIV4 #define SPI_CLOCK_MAX SPI_CLOCK_DIV4
#else #else
#define SPI_CLOCK_MAX SPI_CLOCK_DIV2 #define SPI_CLOCK_MAX SPI_CLOCK_DIV2
#endif #endif
#endif
uint8_t clock; uint8_t clock;
switch (spiRate) { switch (spiRate) {
case SPI_FULL_SPEED: clock = SPI_CLOCK_MAX; break; case SPI_FULL_SPEED: clock = SPI_CLOCK_MAX; break;

View File

@ -27,7 +27,9 @@
#include "circularqueue.h" #include "circularqueue.h"
#ifndef TONE_QUEUE_LENGTH
#define TONE_QUEUE_LENGTH 4 #define TONE_QUEUE_LENGTH 4
#endif
/** /**
* @brief Tone structure * @brief Tone structure

View File

@ -20,7 +20,7 @@
* *
*/ */
#include "../inc/MarlinConfigPre.h" #include "../inc/MarlinConfig.h"
#if NEED_HEX_PRINT #if NEED_HEX_PRINT
@ -41,28 +41,26 @@ char* hex_byte(const uint8_t b) {
return &_hex[byte_start + 4]; return &_hex[byte_start + 4];
} }
inline void _hex_word(const uint16_t w) { inline void __hex_word(const uint16_t w) {
_hex[byte_start + 2] = hex_nybble(w >> 12); _hex[byte_start + 2] = hex_nybble(w >> 12);
_hex[byte_start + 3] = hex_nybble(w >> 8); _hex[byte_start + 3] = hex_nybble(w >> 8);
_hex[byte_start + 4] = hex_nybble(w >> 4); _hex[byte_start + 4] = hex_nybble(w >> 4);
_hex[byte_start + 5] = hex_nybble(w); _hex[byte_start + 5] = hex_nybble(w);
} }
char* hex_word(const uint16_t w) { char* _hex_word(const uint16_t w) {
_hex_word(w); __hex_word(w);
return &_hex[byte_start + 2]; return &_hex[byte_start + 2];
} }
#ifdef CPU_32_BIT char* _hex_long(const uintptr_t l) {
char* hex_long(const uintptr_t l) {
_hex[2] = hex_nybble(l >> 28); _hex[2] = hex_nybble(l >> 28);
_hex[3] = hex_nybble(l >> 24); _hex[3] = hex_nybble(l >> 24);
_hex[4] = hex_nybble(l >> 20); _hex[4] = hex_nybble(l >> 20);
_hex[5] = hex_nybble(l >> 16); _hex[5] = hex_nybble(l >> 16);
_hex_word((uint16_t)(l & 0xFFFF)); __hex_word((uint16_t)(l & 0xFFFF));
return &_hex[2]; return &_hex[2];
} }
#endif
char* hex_address(const void * const w) { char* hex_address(const void * const w) {
#ifdef CPU_32_BIT #ifdef CPU_32_BIT
@ -78,11 +76,11 @@ void print_hex_byte(const uint8_t b) { SERIAL_ECHO(hex_byte(b)); }
void print_hex_word(const uint16_t w) { SERIAL_ECHO(hex_word(w)); } void print_hex_word(const uint16_t w) { SERIAL_ECHO(hex_word(w)); }
void print_hex_address(const void * const w) { SERIAL_ECHO(hex_address(w)); } void print_hex_address(const void * const w) { SERIAL_ECHO(hex_address(w)); }
void print_hex_long(const uint32_t w, const char delimiter) { void print_hex_long(const uint32_t w, const char delimiter/*='\0'*/) {
SERIAL_ECHOPGM("0x"); SERIAL_ECHOPGM("0x");
for (int B = 24; B >= 8; B -= 8) { for (int B = 24; B >= 8; B -= 8) {
print_hex_byte(w >> B); print_hex_byte(w >> B);
SERIAL_CHAR(delimiter); if (delimiter) SERIAL_CHAR(delimiter);
} }
print_hex_byte(w); print_hex_byte(w);
} }

View File

@ -31,11 +31,15 @@ constexpr char hex_nybble(const uint8_t n) {
return (n & 0xF) + ((n & 0xF) < 10 ? '0' : 'A' - 10); return (n & 0xF) + ((n & 0xF) < 10 ? '0' : 'A' - 10);
} }
char* hex_byte(const uint8_t b); char* hex_byte(const uint8_t b);
char* hex_word(const uint16_t w); char* _hex_word(const uint16_t w);
char* hex_address(const void * const w); char* hex_address(const void * const w);
char* _hex_long(const uintptr_t l);
template<typename T> char* hex_word(T w) { return _hex_word((uint16_t)w); }
template<typename T> char* hex_long(T w) { return _hex_long((uint32_t)w); }
void print_hex_nybble(const uint8_t n); void print_hex_nybble(const uint8_t n);
void print_hex_byte(const uint8_t b); void print_hex_byte(const uint8_t b);
void print_hex_word(const uint16_t w); void print_hex_word(const uint16_t w);
void print_hex_address(const void * const w); void print_hex_address(const void * const w);
void print_hex_long(const uint32_t w, const char delimiter); void print_hex_long(const uint32_t w, const char delimiter='\0');

View File

@ -25,16 +25,27 @@
#include "../inc/MarlinConfigPre.h" #include "../inc/MarlinConfigPre.h"
#include "../core/utility.h" #include "../core/utility.h"
constexpr char DIGIT(const uint8_t n) { return '0' + n; }
template <typename T1, typename T2>
constexpr char DIGIMOD(const T1 n, const T2 f) { return DIGIT((n / f) % 10); }
template <typename T1, typename T2>
constexpr char RJDIGIT(const T1 n, const T2 f) { return (n >= (T1)f ? DIGIMOD(n, f) : ' '); }
template <typename T>
constexpr char MINUSOR(T &n, const char alt) { return (n >= 0) ? alt : (n = -n) ? '-' : '-'; }
constexpr long INTFLOAT(const float V, const int N) {
return long((V * 10.0f * pow(10.0f, N) + (V < 0.0f ? -5.0f : 5.0f)) / 10.0f);
}
constexpr long UINTFLOAT(const float V, const int N) {
return INTFLOAT(V < 0.0f ? -V : V, N);
}
char conv[9] = { 0 }; char conv[9] = { 0 };
#define DIGIT(n) ('0' + (n)) // Format uint8_t (0-100) as rj string with __3% / _23% / 123% format
#define DIGIMOD(n, f) DIGIT((n)/(f) % 10)
#define RJDIGIT(n, f) ((n) >= (f) ? DIGIMOD(n, f) : ' ')
#define MINUSOR(n, alt) (n >= 0 ? (alt) : (n = -n, '-'))
#define INTFLOAT(V,N) (((V) * 10 * pow(10, N) + ((V) < 0 ? -5: 5)) / 10) // pow10?
#define UINTFLOAT(V,N) INTFLOAT((V) < 0 ? -(V) : (V), N)
// Format uint8_t (0-100) as rj string with 123% / _12% / __1% format
const char* pcttostrpctrj(const uint8_t i) { const char* pcttostrpctrj(const uint8_t i) {
conv[4] = RJDIGIT(i, 100); conv[4] = RJDIGIT(i, 100);
conv[5] = RJDIGIT(i, 10); conv[5] = RJDIGIT(i, 10);
@ -48,7 +59,7 @@ const char* ui8tostr4pctrj(const uint8_t i) {
return pcttostrpctrj(ui8_to_percent(i)); return pcttostrpctrj(ui8_to_percent(i));
} }
// Convert unsigned 8bit int to string 123 format // Convert unsigned 8bit int to string with __3 / _23 / 123 format
const char* ui8tostr3rj(const uint8_t i) { const char* ui8tostr3rj(const uint8_t i) {
conv[5] = RJDIGIT(i, 100); conv[5] = RJDIGIT(i, 100);
conv[6] = RJDIGIT(i, 10); conv[6] = RJDIGIT(i, 10);
@ -63,7 +74,7 @@ const char* ui8tostr2(const uint8_t i) {
return &conv[6]; return &conv[6];
} }
// Convert signed 8bit int to rj string with 123 or -12 format // Convert signed 8bit int to rj string with __3 / _23 / 123 / -_3 / -23 format
const char* i8tostr3rj(const int8_t x) { const char* i8tostr3rj(const int8_t x) {
int xx = x; int xx = x;
conv[5] = MINUSOR(xx, RJDIGIT(xx, 100)); conv[5] = MINUSOR(xx, RJDIGIT(xx, 100));
@ -211,7 +222,7 @@ const char* ftostr41ns(const_float_t f) {
return &conv[3]; return &conv[3];
} }
// Convert signed float to fixed-length string with 12.34 / _2.34 / -2.34 or -23.45 / 123.45 format // Convert float to fixed-length string with 12.34 / _2.34 / -2.34 or -23.45 / 123.45 format
const char* ftostr42_52(const_float_t f) { const char* ftostr42_52(const_float_t f) {
if (f <= -10 || f >= 100) return ftostr52(f); // -23.45 / 123.45 if (f <= -10 || f >= 100) return ftostr52(f); // -23.45 / 123.45
long i = INTFLOAT(f, 2); long i = INTFLOAT(f, 2);
@ -223,7 +234,7 @@ const char* ftostr42_52(const_float_t f) {
return &conv[3]; return &conv[3];
} }
// Convert signed float to fixed-length string with 023.45 / -23.45 format // Convert float to fixed-length string with 023.45 / -23.45 format
const char* ftostr52(const_float_t f) { const char* ftostr52(const_float_t f) {
long i = INTFLOAT(f, 2); long i = INTFLOAT(f, 2);
conv[2] = MINUSOR(i, DIGIMOD(i, 10000)); conv[2] = MINUSOR(i, DIGIMOD(i, 10000));
@ -235,7 +246,7 @@ const char* ftostr52(const_float_t f) {
return &conv[2]; return &conv[2];
} }
// Convert signed float to fixed-length string with 12.345 / _2.345 / -2.345 or -23.45 / 123.45 format // Convert float to fixed-length string with 12.345 / _2.345 / -2.345 or -23.45 / 123.45 format
const char* ftostr53_63(const_float_t f) { const char* ftostr53_63(const_float_t f) {
if (f <= -10 || f >= 100) return ftostr63(f); // -23.456 / 123.456 if (f <= -10 || f >= 100) return ftostr63(f); // -23.456 / 123.456
long i = INTFLOAT(f, 3); long i = INTFLOAT(f, 3);
@ -248,7 +259,7 @@ const char* ftostr53_63(const_float_t f) {
return &conv[2]; return &conv[2];
} }
// Convert signed float to fixed-length string with 023.456 / -23.456 format // Convert float to fixed-length string with 023.456 / -23.456 format
const char* ftostr63(const_float_t f) { const char* ftostr63(const_float_t f) {
long i = INTFLOAT(f, 3); long i = INTFLOAT(f, 3);
conv[1] = MINUSOR(i, DIGIMOD(i, 100000)); conv[1] = MINUSOR(i, DIGIMOD(i, 100000));
@ -407,17 +418,17 @@ const char* ftostr52sp(const_float_t f) {
conv[3] = RJDIGIT(i, 1000); conv[3] = RJDIGIT(i, 1000);
conv[4] = DIGIMOD(i, 100); conv[4] = DIGIMOD(i, 100);
if ((dig = i % 10)) { // second digit after decimal point? if ((dig = i % 10)) { // Second digit after decimal point?
conv[5] = '.'; conv[5] = '.';
conv[6] = DIGIMOD(i, 10); conv[6] = DIGIMOD(i, 10);
conv[7] = DIGIT(dig); conv[7] = DIGIT(dig);
} }
else { else {
if ((dig = (i / 10) % 10)) { // first digit after decimal point? if ((dig = (i / 10) % 10)) { // First digit after decimal point?
conv[5] = '.'; conv[5] = '.';
conv[6] = DIGIT(dig); conv[6] = DIGIT(dig);
} }
else // nothing after decimal point else // Nothing after decimal point
conv[5] = conv[6] = ' '; conv[5] = conv[6] = ' ';
conv[7] = ' '; conv[7] = ' ';
} }

View File

@ -242,7 +242,7 @@ void home_delta() {
#endif #endif
// Move all carriages together linearly until an endstop is hit. // Move all carriages together linearly until an endstop is hit.
current_position.z = DIFF_TERN(HAS_BED_PROBE, delta_height + 10, probe.offset.z); current_position.z = DIFF_TERN(USE_PROBE_FOR_Z_HOMING, delta_height + 10, probe.offset.z);
line_to_current_position(homing_feedrate(Z_AXIS)); line_to_current_position(homing_feedrate(Z_AXIS));
planner.synchronize(); planner.synchronize();
TERN_(HAS_DELTA_SENSORLESS_PROBING, endstops.report_states()); TERN_(HAS_DELTA_SENSORLESS_PROBING, endstops.report_states());

View File

@ -109,7 +109,7 @@ Endstops::endstop_mask_t Endstops::live_state = 0;
void Endstops::init() { void Endstops::init() {
#if HAS_X_MIN #if USE_X_MIN
#if ENABLED(ENDSTOPPULLUP_XMIN) #if ENABLED(ENDSTOPPULLUP_XMIN)
SET_INPUT_PULLUP(X_MIN_PIN); SET_INPUT_PULLUP(X_MIN_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_XMIN) #elif ENABLED(ENDSTOPPULLDOWN_XMIN)
@ -119,7 +119,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_X2_MIN #if USE_X2_MIN
#if ENABLED(ENDSTOPPULLUP_XMIN) #if ENABLED(ENDSTOPPULLUP_XMIN)
SET_INPUT_PULLUP(X2_MIN_PIN); SET_INPUT_PULLUP(X2_MIN_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_XMIN) #elif ENABLED(ENDSTOPPULLDOWN_XMIN)
@ -129,7 +129,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_Y_MIN #if USE_Y_MIN
#if ENABLED(ENDSTOPPULLUP_YMIN) #if ENABLED(ENDSTOPPULLUP_YMIN)
SET_INPUT_PULLUP(Y_MIN_PIN); SET_INPUT_PULLUP(Y_MIN_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_YMIN) #elif ENABLED(ENDSTOPPULLDOWN_YMIN)
@ -139,7 +139,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_Y2_MIN #if USE_Y2_MIN
#if ENABLED(ENDSTOPPULLUP_YMIN) #if ENABLED(ENDSTOPPULLUP_YMIN)
SET_INPUT_PULLUP(Y2_MIN_PIN); SET_INPUT_PULLUP(Y2_MIN_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_YMIN) #elif ENABLED(ENDSTOPPULLDOWN_YMIN)
@ -149,7 +149,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_Z_MIN #if USE_Z_MIN
#if ENABLED(ENDSTOPPULLUP_ZMIN) #if ENABLED(ENDSTOPPULLUP_ZMIN)
SET_INPUT_PULLUP(Z_MIN_PIN); SET_INPUT_PULLUP(Z_MIN_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_ZMIN) #elif ENABLED(ENDSTOPPULLDOWN_ZMIN)
@ -159,7 +159,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_Z2_MIN #if USE_Z2_MIN
#if ENABLED(ENDSTOPPULLUP_ZMIN) #if ENABLED(ENDSTOPPULLUP_ZMIN)
SET_INPUT_PULLUP(Z2_MIN_PIN); SET_INPUT_PULLUP(Z2_MIN_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_ZMIN) #elif ENABLED(ENDSTOPPULLDOWN_ZMIN)
@ -169,7 +169,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_Z3_MIN #if USE_Z3_MIN
#if ENABLED(ENDSTOPPULLUP_ZMIN) #if ENABLED(ENDSTOPPULLUP_ZMIN)
SET_INPUT_PULLUP(Z3_MIN_PIN); SET_INPUT_PULLUP(Z3_MIN_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_ZMIN) #elif ENABLED(ENDSTOPPULLDOWN_ZMIN)
@ -179,7 +179,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_Z4_MIN #if USE_Z4_MIN
#if ENABLED(ENDSTOPPULLUP_ZMIN) #if ENABLED(ENDSTOPPULLUP_ZMIN)
SET_INPUT_PULLUP(Z4_MIN_PIN); SET_INPUT_PULLUP(Z4_MIN_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_ZMIN) #elif ENABLED(ENDSTOPPULLDOWN_ZMIN)
@ -189,7 +189,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_X_MAX #if USE_X_MAX
#if ENABLED(ENDSTOPPULLUP_XMAX) #if ENABLED(ENDSTOPPULLUP_XMAX)
SET_INPUT_PULLUP(X_MAX_PIN); SET_INPUT_PULLUP(X_MAX_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_XMAX) #elif ENABLED(ENDSTOPPULLDOWN_XMAX)
@ -199,7 +199,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_X2_MAX #if USE_X2_MAX
#if ENABLED(ENDSTOPPULLUP_XMAX) #if ENABLED(ENDSTOPPULLUP_XMAX)
SET_INPUT_PULLUP(X2_MAX_PIN); SET_INPUT_PULLUP(X2_MAX_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_XMAX) #elif ENABLED(ENDSTOPPULLDOWN_XMAX)
@ -209,7 +209,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_Y_MAX #if USE_Y_MAX
#if ENABLED(ENDSTOPPULLUP_YMAX) #if ENABLED(ENDSTOPPULLUP_YMAX)
SET_INPUT_PULLUP(Y_MAX_PIN); SET_INPUT_PULLUP(Y_MAX_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_YMAX) #elif ENABLED(ENDSTOPPULLDOWN_YMAX)
@ -219,7 +219,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_Y2_MAX #if USE_Y2_MAX
#if ENABLED(ENDSTOPPULLUP_YMAX) #if ENABLED(ENDSTOPPULLUP_YMAX)
SET_INPUT_PULLUP(Y2_MAX_PIN); SET_INPUT_PULLUP(Y2_MAX_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_YMAX) #elif ENABLED(ENDSTOPPULLDOWN_YMAX)
@ -229,7 +229,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_Z_MAX #if USE_Z_MAX
#if ENABLED(ENDSTOPPULLUP_ZMAX) #if ENABLED(ENDSTOPPULLUP_ZMAX)
SET_INPUT_PULLUP(Z_MAX_PIN); SET_INPUT_PULLUP(Z_MAX_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_ZMAX) #elif ENABLED(ENDSTOPPULLDOWN_ZMAX)
@ -239,7 +239,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_Z2_MAX #if USE_Z2_MAX
#if ENABLED(ENDSTOPPULLUP_ZMAX) #if ENABLED(ENDSTOPPULLUP_ZMAX)
SET_INPUT_PULLUP(Z2_MAX_PIN); SET_INPUT_PULLUP(Z2_MAX_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_ZMAX) #elif ENABLED(ENDSTOPPULLDOWN_ZMAX)
@ -249,7 +249,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_Z3_MAX #if USE_Z3_MAX
#if ENABLED(ENDSTOPPULLUP_ZMAX) #if ENABLED(ENDSTOPPULLUP_ZMAX)
SET_INPUT_PULLUP(Z3_MAX_PIN); SET_INPUT_PULLUP(Z3_MAX_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_ZMAX) #elif ENABLED(ENDSTOPPULLDOWN_ZMAX)
@ -259,7 +259,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_Z4_MAX #if USE_Z4_MAX
#if ENABLED(ENDSTOPPULLUP_ZMAX) #if ENABLED(ENDSTOPPULLUP_ZMAX)
SET_INPUT_PULLUP(Z4_MAX_PIN); SET_INPUT_PULLUP(Z4_MAX_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_ZMAX) #elif ENABLED(ENDSTOPPULLDOWN_ZMAX)
@ -269,7 +269,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_I_MIN #if USE_I_MIN
#if ENABLED(ENDSTOPPULLUP_IMIN) #if ENABLED(ENDSTOPPULLUP_IMIN)
SET_INPUT_PULLUP(I_MIN_PIN); SET_INPUT_PULLUP(I_MIN_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_IMIN) #elif ENABLED(ENDSTOPPULLDOWN_IMIN)
@ -279,7 +279,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_I_MAX #if USE_I_MAX
#if ENABLED(ENDSTOPPULLUP_IMAX) #if ENABLED(ENDSTOPPULLUP_IMAX)
SET_INPUT_PULLUP(I_MAX_PIN); SET_INPUT_PULLUP(I_MAX_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_IMAX) #elif ENABLED(ENDSTOPPULLDOWN_IMAX)
@ -289,7 +289,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_J_MIN #if USE_J_MIN
#if ENABLED(ENDSTOPPULLUP_JMIN) #if ENABLED(ENDSTOPPULLUP_JMIN)
SET_INPUT_PULLUP(J_MIN_PIN); SET_INPUT_PULLUP(J_MIN_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_IMIN) #elif ENABLED(ENDSTOPPULLDOWN_IMIN)
@ -299,7 +299,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_J_MAX #if USE_J_MAX
#if ENABLED(ENDSTOPPULLUP_JMAX) #if ENABLED(ENDSTOPPULLUP_JMAX)
SET_INPUT_PULLUP(J_MAX_PIN); SET_INPUT_PULLUP(J_MAX_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_JMAX) #elif ENABLED(ENDSTOPPULLDOWN_JMAX)
@ -309,7 +309,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_K_MIN #if USE_K_MIN
#if ENABLED(ENDSTOPPULLUP_KMIN) #if ENABLED(ENDSTOPPULLUP_KMIN)
SET_INPUT_PULLUP(K_MIN_PIN); SET_INPUT_PULLUP(K_MIN_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_KMIN) #elif ENABLED(ENDSTOPPULLDOWN_KMIN)
@ -319,7 +319,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_K_MAX #if USE_K_MAX
#if ENABLED(ENDSTOPPULLUP_KMAX) #if ENABLED(ENDSTOPPULLUP_KMAX)
SET_INPUT_PULLUP(K_MAX_PIN); SET_INPUT_PULLUP(K_MAX_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_KMIN) #elif ENABLED(ENDSTOPPULLDOWN_KMIN)
@ -329,7 +329,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_U_MIN #if USE_U_MIN
#if ENABLED(ENDSTOPPULLUP_UMIN) #if ENABLED(ENDSTOPPULLUP_UMIN)
SET_INPUT_PULLUP(U_MIN_PIN); SET_INPUT_PULLUP(U_MIN_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_UMIN) #elif ENABLED(ENDSTOPPULLDOWN_UMIN)
@ -339,7 +339,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_U_MAX #if USE_U_MAX
#if ENABLED(ENDSTOPPULLUP_UMAX) #if ENABLED(ENDSTOPPULLUP_UMAX)
SET_INPUT_PULLUP(U_MAX_PIN); SET_INPUT_PULLUP(U_MAX_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_UMIN) #elif ENABLED(ENDSTOPPULLDOWN_UMIN)
@ -349,7 +349,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_V_MIN #if USE_V_MIN
#if ENABLED(ENDSTOPPULLUP_VMIN) #if ENABLED(ENDSTOPPULLUP_VMIN)
SET_INPUT_PULLUP(V_MIN_PIN); SET_INPUT_PULLUP(V_MIN_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_VMIN) #elif ENABLED(ENDSTOPPULLDOWN_VMIN)
@ -359,7 +359,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_V_MAX #if USE_V_MAX
#if ENABLED(ENDSTOPPULLUP_VMAX) #if ENABLED(ENDSTOPPULLUP_VMAX)
SET_INPUT_PULLUP(V_MAX_PIN); SET_INPUT_PULLUP(V_MAX_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_VMIN) #elif ENABLED(ENDSTOPPULLDOWN_VMIN)
@ -369,7 +369,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_W_MIN #if USE_W_MIN
#if ENABLED(ENDSTOPPULLUP_WMIN) #if ENABLED(ENDSTOPPULLUP_WMIN)
SET_INPUT_PULLUP(W_MIN_PIN); SET_INPUT_PULLUP(W_MIN_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_WMIN) #elif ENABLED(ENDSTOPPULLDOWN_WMIN)
@ -379,7 +379,7 @@ void Endstops::init() {
#endif #endif
#endif #endif
#if HAS_W_MAX #if USE_W_MAX
#if ENABLED(ENDSTOPPULLUP_WMAX) #if ENABLED(ENDSTOPPULLUP_WMAX)
SET_INPUT_PULLUP(W_MAX_PIN); SET_INPUT_PULLUP(W_MAX_PIN);
#elif ENABLED(ENDSTOPPULLDOWN_WMIN) #elif ENABLED(ENDSTOPPULLDOWN_WMIN)
@ -578,88 +578,88 @@ void __O2 Endstops::report_states() {
TERN_(BLTOUCH, bltouch._set_SW_mode()); TERN_(BLTOUCH, bltouch._set_SW_mode());
SERIAL_ECHOLNPGM(STR_M119_REPORT); SERIAL_ECHOLNPGM(STR_M119_REPORT);
#define ES_REPORT(S) print_es_state(READ_ENDSTOP(S##_PIN) != S##_ENDSTOP_INVERTING, F(STR_##S)) #define ES_REPORT(S) print_es_state(READ_ENDSTOP(S##_PIN) != S##_ENDSTOP_INVERTING, F(STR_##S))
#if HAS_X_MIN #if USE_X_MIN
ES_REPORT(X_MIN); ES_REPORT(X_MIN);
#endif #endif
#if HAS_X2_MIN #if USE_X2_MIN
ES_REPORT(X2_MIN); ES_REPORT(X2_MIN);
#endif #endif
#if HAS_X_MAX #if USE_X_MAX
ES_REPORT(X_MAX); ES_REPORT(X_MAX);
#endif #endif
#if HAS_X2_MAX #if USE_X2_MAX
ES_REPORT(X2_MAX); ES_REPORT(X2_MAX);
#endif #endif
#if HAS_Y_MIN #if USE_Y_MIN
ES_REPORT(Y_MIN); ES_REPORT(Y_MIN);
#endif #endif
#if HAS_Y2_MIN #if USE_Y2_MIN
ES_REPORT(Y2_MIN); ES_REPORT(Y2_MIN);
#endif #endif
#if HAS_Y_MAX #if USE_Y_MAX
ES_REPORT(Y_MAX); ES_REPORT(Y_MAX);
#endif #endif
#if HAS_Y2_MAX #if USE_Y2_MAX
ES_REPORT(Y2_MAX); ES_REPORT(Y2_MAX);
#endif #endif
#if HAS_Z_MIN #if USE_Z_MIN
ES_REPORT(Z_MIN); ES_REPORT(Z_MIN);
#endif #endif
#if HAS_Z2_MIN #if USE_Z2_MIN
ES_REPORT(Z2_MIN); ES_REPORT(Z2_MIN);
#endif #endif
#if HAS_Z3_MIN #if USE_Z3_MIN
ES_REPORT(Z3_MIN); ES_REPORT(Z3_MIN);
#endif #endif
#if HAS_Z4_MIN #if USE_Z4_MIN
ES_REPORT(Z4_MIN); ES_REPORT(Z4_MIN);
#endif #endif
#if HAS_Z_MAX #if USE_Z_MAX
ES_REPORT(Z_MAX); ES_REPORT(Z_MAX);
#endif #endif
#if HAS_Z2_MAX #if USE_Z2_MAX
ES_REPORT(Z2_MAX); ES_REPORT(Z2_MAX);
#endif #endif
#if HAS_Z3_MAX #if USE_Z3_MAX
ES_REPORT(Z3_MAX); ES_REPORT(Z3_MAX);
#endif #endif
#if HAS_Z4_MAX #if USE_Z4_MAX
ES_REPORT(Z4_MAX); ES_REPORT(Z4_MAX);
#endif #endif
#if HAS_I_MIN #if USE_I_MIN
ES_REPORT(I_MIN); ES_REPORT(I_MIN);
#endif #endif
#if HAS_I_MAX #if USE_I_MAX
ES_REPORT(I_MAX); ES_REPORT(I_MAX);
#endif #endif
#if HAS_J_MIN #if USE_J_MIN
ES_REPORT(J_MIN); ES_REPORT(J_MIN);
#endif #endif
#if HAS_J_MAX #if USE_J_MAX
ES_REPORT(J_MAX); ES_REPORT(J_MAX);
#endif #endif
#if HAS_K_MIN #if USE_K_MIN
ES_REPORT(K_MIN); ES_REPORT(K_MIN);
#endif #endif
#if HAS_K_MAX #if USE_K_MAX
ES_REPORT(K_MAX); ES_REPORT(K_MAX);
#endif #endif
#if HAS_U_MIN #if USE_U_MIN
ES_REPORT(U_MIN); ES_REPORT(U_MIN);
#endif #endif
#if HAS_U_MAX #if USE_U_MAX
ES_REPORT(U_MAX); ES_REPORT(U_MAX);
#endif #endif
#if HAS_V_MIN #if USE_V_MIN
ES_REPORT(V_MIN); ES_REPORT(V_MIN);
#endif #endif
#if HAS_V_MAX #if USE_V_MAX
ES_REPORT(V_MAX); ES_REPORT(V_MAX);
#endif #endif
#if HAS_W_MIN #if USE_W_MIN
ES_REPORT(W_MIN); ES_REPORT(W_MIN);
#endif #endif
#if HAS_W_MAX #if USE_W_MAX
ES_REPORT(W_MAX); ES_REPORT(W_MAX);
#endif #endif
#if ENABLED(PROBE_ACTIVATION_SWITCH) #if ENABLED(PROBE_ACTIVATION_SWITCH)
@ -747,10 +747,10 @@ void Endstops::update() {
/** /**
* Check and update endstops * Check and update endstops
*/ */
#if HAS_X_MIN && !X_SPI_SENSORLESS #if USE_X_MIN && !X_SPI_SENSORLESS
UPDATE_ENDSTOP_BIT(X, MIN); UPDATE_ENDSTOP_BIT(X, MIN);
#if ENABLED(X_DUAL_ENDSTOPS) #if ENABLED(X_DUAL_ENDSTOPS)
#if HAS_X2_MIN #if USE_X2_MIN
UPDATE_ENDSTOP_BIT(X2, MIN); UPDATE_ENDSTOP_BIT(X2, MIN);
#else #else
COPY_LIVE_STATE(X_MIN, X2_MIN); COPY_LIVE_STATE(X_MIN, X2_MIN);
@ -758,10 +758,10 @@ void Endstops::update() {
#endif #endif
#endif #endif
#if HAS_X_MAX && !X_SPI_SENSORLESS #if USE_X_MAX && !X_SPI_SENSORLESS
UPDATE_ENDSTOP_BIT(X, MAX); UPDATE_ENDSTOP_BIT(X, MAX);
#if ENABLED(X_DUAL_ENDSTOPS) #if ENABLED(X_DUAL_ENDSTOPS)
#if HAS_X2_MAX #if USE_X2_MAX
UPDATE_ENDSTOP_BIT(X2, MAX); UPDATE_ENDSTOP_BIT(X2, MAX);
#else #else
COPY_LIVE_STATE(X_MAX, X2_MAX); COPY_LIVE_STATE(X_MAX, X2_MAX);
@ -769,10 +769,10 @@ void Endstops::update() {
#endif #endif
#endif #endif
#if HAS_Y_MIN && !Y_SPI_SENSORLESS #if USE_Y_MIN && !Y_SPI_SENSORLESS
UPDATE_ENDSTOP_BIT(Y, MIN); UPDATE_ENDSTOP_BIT(Y, MIN);
#if ENABLED(Y_DUAL_ENDSTOPS) #if ENABLED(Y_DUAL_ENDSTOPS)
#if HAS_Y2_MIN #if USE_Y2_MIN
UPDATE_ENDSTOP_BIT(Y2, MIN); UPDATE_ENDSTOP_BIT(Y2, MIN);
#else #else
COPY_LIVE_STATE(Y_MIN, Y2_MIN); COPY_LIVE_STATE(Y_MIN, Y2_MIN);
@ -780,10 +780,10 @@ void Endstops::update() {
#endif #endif
#endif #endif
#if HAS_Y_MAX && !Y_SPI_SENSORLESS #if USE_Y_MAX && !Y_SPI_SENSORLESS
UPDATE_ENDSTOP_BIT(Y, MAX); UPDATE_ENDSTOP_BIT(Y, MAX);
#if ENABLED(Y_DUAL_ENDSTOPS) #if ENABLED(Y_DUAL_ENDSTOPS)
#if HAS_Y2_MAX #if USE_Y2_MAX
UPDATE_ENDSTOP_BIT(Y2, MAX); UPDATE_ENDSTOP_BIT(Y2, MAX);
#else #else
COPY_LIVE_STATE(Y_MAX, Y2_MAX); COPY_LIVE_STATE(Y_MAX, Y2_MAX);
@ -791,23 +791,23 @@ void Endstops::update() {
#endif #endif
#endif #endif
#if HAS_Z_MIN && NONE(Z_SPI_SENSORLESS, Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) #if USE_Z_MIN && NONE(Z_SPI_SENSORLESS, Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
UPDATE_ENDSTOP_BIT(Z, MIN); UPDATE_ENDSTOP_BIT(Z, MIN);
#if ENABLED(Z_MULTI_ENDSTOPS) #if ENABLED(Z_MULTI_ENDSTOPS)
#if HAS_Z2_MIN #if USE_Z2_MIN
UPDATE_ENDSTOP_BIT(Z2, MIN); UPDATE_ENDSTOP_BIT(Z2, MIN);
#else #else
COPY_LIVE_STATE(Z_MIN, Z2_MIN); COPY_LIVE_STATE(Z_MIN, Z2_MIN);
#endif #endif
#if NUM_Z_STEPPERS >= 3 #if NUM_Z_STEPPERS >= 3
#if HAS_Z3_MIN #if USE_Z3_MIN
UPDATE_ENDSTOP_BIT(Z3, MIN); UPDATE_ENDSTOP_BIT(Z3, MIN);
#else #else
COPY_LIVE_STATE(Z_MIN, Z3_MIN); COPY_LIVE_STATE(Z_MIN, Z3_MIN);
#endif #endif
#endif #endif
#if NUM_Z_STEPPERS >= 4 #if NUM_Z_STEPPERS >= 4
#if HAS_Z4_MIN #if USE_Z4_MIN
UPDATE_ENDSTOP_BIT(Z4, MIN); UPDATE_ENDSTOP_BIT(Z4, MIN);
#else #else
COPY_LIVE_STATE(Z_MIN, Z4_MIN); COPY_LIVE_STATE(Z_MIN, Z4_MIN);
@ -822,24 +822,24 @@ void Endstops::update() {
UPDATE_ENDSTOP_BIT(Z, TERN(USES_Z_MIN_PROBE_PIN, MIN_PROBE, MIN)); UPDATE_ENDSTOP_BIT(Z, TERN(USES_Z_MIN_PROBE_PIN, MIN_PROBE, MIN));
#endif #endif
#if HAS_Z_MAX && !Z_SPI_SENSORLESS #if USE_Z_MAX && !Z_SPI_SENSORLESS
// Check both Z dual endstops // Check both Z dual endstops
#if ENABLED(Z_MULTI_ENDSTOPS) #if ENABLED(Z_MULTI_ENDSTOPS)
UPDATE_ENDSTOP_BIT(Z, MAX); UPDATE_ENDSTOP_BIT(Z, MAX);
#if HAS_Z2_MAX #if USE_Z2_MAX
UPDATE_ENDSTOP_BIT(Z2, MAX); UPDATE_ENDSTOP_BIT(Z2, MAX);
#else #else
COPY_LIVE_STATE(Z_MAX, Z2_MAX); COPY_LIVE_STATE(Z_MAX, Z2_MAX);
#endif #endif
#if NUM_Z_STEPPERS >= 3 #if NUM_Z_STEPPERS >= 3
#if HAS_Z3_MAX #if USE_Z3_MAX
UPDATE_ENDSTOP_BIT(Z3, MAX); UPDATE_ENDSTOP_BIT(Z3, MAX);
#else #else
COPY_LIVE_STATE(Z_MAX, Z3_MAX); COPY_LIVE_STATE(Z_MAX, Z3_MAX);
#endif #endif
#endif #endif
#if NUM_Z_STEPPERS >= 4 #if NUM_Z_STEPPERS >= 4
#if HAS_Z4_MAX #if USE_Z4_MAX
UPDATE_ENDSTOP_BIT(Z4, MAX); UPDATE_ENDSTOP_BIT(Z4, MAX);
#else #else
COPY_LIVE_STATE(Z_MAX, Z4_MAX); COPY_LIVE_STATE(Z_MAX, Z4_MAX);
@ -851,7 +851,7 @@ void Endstops::update() {
#endif #endif
#endif #endif
#if HAS_I_MIN && !I_SPI_SENSORLESS #if USE_I_MIN && !I_SPI_SENSORLESS
#if ENABLED(I_DUAL_ENDSTOPS) #if ENABLED(I_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(I, MIN); UPDATE_ENDSTOP_BIT(I, MIN);
#if HAS_I2_MIN #if HAS_I2_MIN
@ -864,7 +864,7 @@ void Endstops::update() {
#endif #endif
#endif #endif
#if HAS_I_MAX && !I_SPI_SENSORLESS #if USE_I_MAX && !I_SPI_SENSORLESS
#if ENABLED(I_DUAL_ENDSTOPS) #if ENABLED(I_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(I, MAX); UPDATE_ENDSTOP_BIT(I, MAX);
#if HAS_I2_MAX #if HAS_I2_MAX
@ -877,7 +877,7 @@ void Endstops::update() {
#endif #endif
#endif #endif
#if HAS_J_MIN && !J_SPI_SENSORLESS #if USE_J_MIN && !J_SPI_SENSORLESS
#if ENABLED(J_DUAL_ENDSTOPS) #if ENABLED(J_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(J, MIN); UPDATE_ENDSTOP_BIT(J, MIN);
#if HAS_J2_MIN #if HAS_J2_MIN
@ -890,7 +890,7 @@ void Endstops::update() {
#endif #endif
#endif #endif
#if HAS_J_MAX && !J_SPI_SENSORLESS #if USE_J_MAX && !J_SPI_SENSORLESS
#if ENABLED(J_DUAL_ENDSTOPS) #if ENABLED(J_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(J, MAX); UPDATE_ENDSTOP_BIT(J, MAX);
#if HAS_J2_MAX #if HAS_J2_MAX
@ -903,7 +903,7 @@ void Endstops::update() {
#endif #endif
#endif #endif
#if HAS_K_MIN && !K_SPI_SENSORLESS #if USE_K_MIN && !K_SPI_SENSORLESS
#if ENABLED(K_DUAL_ENDSTOPS) #if ENABLED(K_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(K, MIN); UPDATE_ENDSTOP_BIT(K, MIN);
#if HAS_K2_MIN #if HAS_K2_MIN
@ -916,7 +916,7 @@ void Endstops::update() {
#endif #endif
#endif #endif
#if HAS_K_MAX && !K_SPI_SENSORLESS #if USE_K_MAX && !K_SPI_SENSORLESS
#if ENABLED(K_DUAL_ENDSTOPS) #if ENABLED(K_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(K, MAX); UPDATE_ENDSTOP_BIT(K, MAX);
#if HAS_K2_MAX #if HAS_K2_MAX
@ -929,7 +929,7 @@ void Endstops::update() {
#endif #endif
#endif #endif
#if HAS_U_MIN && !U_SPI_SENSORLESS #if USE_U_MIN && !U_SPI_SENSORLESS
#if ENABLED(U_DUAL_ENDSTOPS) #if ENABLED(U_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(U, MIN); UPDATE_ENDSTOP_BIT(U, MIN);
#if HAS_U2_MIN #if HAS_U2_MIN
@ -942,7 +942,7 @@ void Endstops::update() {
#endif #endif
#endif #endif
#if HAS_U_MAX && !U_SPI_SENSORLESS #if USE_U_MAX && !U_SPI_SENSORLESS
#if ENABLED(U_DUAL_ENDSTOPS) #if ENABLED(U_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(U, MAX); UPDATE_ENDSTOP_BIT(U, MAX);
#if HAS_U2_MAX #if HAS_U2_MAX
@ -955,7 +955,7 @@ void Endstops::update() {
#endif #endif
#endif #endif
#if HAS_V_MIN && !V_SPI_SENSORLESS #if USE_V_MIN && !V_SPI_SENSORLESS
#if ENABLED(V_DUAL_ENDSTOPS) #if ENABLED(V_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(V, MIN); UPDATE_ENDSTOP_BIT(V, MIN);
#if HAS_V2_MIN #if HAS_V2_MIN
@ -967,7 +967,7 @@ void Endstops::update() {
UPDATE_ENDSTOP_BIT(V, MIN); UPDATE_ENDSTOP_BIT(V, MIN);
#endif #endif
#endif #endif
#if HAS_V_MAX && !V_SPI_SENSORLESS #if USE_V_MAX && !V_SPI_SENSORLESS
#if ENABLED(O_DUAL_ENDSTOPS) #if ENABLED(O_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(V, MAX); UPDATE_ENDSTOP_BIT(V, MAX);
#if HAS_V2_MAX #if HAS_V2_MAX
@ -980,7 +980,7 @@ void Endstops::update() {
#endif #endif
#endif #endif
#if HAS_W_MIN && !W_SPI_SENSORLESS #if USE_W_MIN && !W_SPI_SENSORLESS
#if ENABLED(W_DUAL_ENDSTOPS) #if ENABLED(W_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(W, MIN); UPDATE_ENDSTOP_BIT(W, MIN);
#if HAS_W2_MIN #if HAS_W2_MIN
@ -992,7 +992,7 @@ void Endstops::update() {
UPDATE_ENDSTOP_BIT(W, MIN); UPDATE_ENDSTOP_BIT(W, MIN);
#endif #endif
#endif #endif
#if HAS_W_MAX && !W_SPI_SENSORLESS #if USE_W_MAX && !W_SPI_SENSORLESS
#if ENABLED(W_DUAL_ENDSTOPS) #if ENABLED(W_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(W, MAX); UPDATE_ENDSTOP_BIT(W, MAX);
#if HAS_W2_MAX #if HAS_W2_MAX
@ -1110,7 +1110,8 @@ void Endstops::update() {
if (G38_move && TEST_ENDSTOP(Z_MIN_PROBE) == TERN1(G38_PROBE_AWAY, (G38_move < 4))) { if (G38_move && TEST_ENDSTOP(Z_MIN_PROBE) == TERN1(G38_PROBE_AWAY, (G38_move < 4))) {
G38_did_trigger = true; G38_did_trigger = true;
#define _G38_SET(Q) | (stepper.axis_is_moving(_AXIS(Q)) << _AXIS(Q)) #define _G38_SET(Q) | (stepper.axis_is_moving(_AXIS(Q)) << _AXIS(Q))
#define _G38_RESP(Q) if (stepper.axis_is_moving(_AXIS(Q))) { _ENDSTOP_HIT(Q, ENDSTOP); planner.endstop_triggered(_AXIS(Q)); } #define _G38_RESP(Q) if (moving[_AXIS(Q)]) { _ENDSTOP_HIT(Q, ENDSTOP); planner.endstop_triggered(_AXIS(Q)); }
const Flags<NUM_AXES> moving = { uvalue_t(NUM_AXES)(0 MAIN_AXIS_MAP(_G38_SET)) };
MAIN_AXIS_MAP(_G38_RESP); MAIN_AXIS_MAP(_G38_RESP);
} }
#endif #endif
@ -1119,7 +1120,7 @@ void Endstops::update() {
if (stepper.axis_is_moving(X_AXIS)) { if (stepper.axis_is_moving(X_AXIS)) {
if (stepper.motor_direction(X_AXIS_HEAD)) { // -direction if (stepper.motor_direction(X_AXIS_HEAD)) { // -direction
#if HAS_X_MIN || (X_SPI_SENSORLESS && X_HOME_TO_MIN) #if USE_X_MIN || (X_SPI_SENSORLESS && X_HOME_TO_MIN)
PROCESS_ENDSTOP_X(MIN); PROCESS_ENDSTOP_X(MIN);
#if CORE_DIAG(XY, Y, MIN) #if CORE_DIAG(XY, Y, MIN)
PROCESS_CORE_ENDSTOP(Y,MIN,X,MIN); PROCESS_CORE_ENDSTOP(Y,MIN,X,MIN);
@ -1133,7 +1134,7 @@ void Endstops::update() {
#endif #endif
} }
else { // +direction else { // +direction
#if HAS_X_MAX || (X_SPI_SENSORLESS && X_HOME_TO_MAX) #if USE_X_MAX || (X_SPI_SENSORLESS && X_HOME_TO_MAX)
PROCESS_ENDSTOP_X(MAX); PROCESS_ENDSTOP_X(MAX);
#if CORE_DIAG(XY, Y, MIN) #if CORE_DIAG(XY, Y, MIN)
PROCESS_CORE_ENDSTOP(Y,MIN,X,MAX); PROCESS_CORE_ENDSTOP(Y,MIN,X,MAX);
@ -1151,7 +1152,7 @@ void Endstops::update() {
#if HAS_Y_AXIS #if HAS_Y_AXIS
if (stepper.axis_is_moving(Y_AXIS)) { if (stepper.axis_is_moving(Y_AXIS)) {
if (stepper.motor_direction(Y_AXIS_HEAD)) { // -direction if (stepper.motor_direction(Y_AXIS_HEAD)) { // -direction
#if HAS_Y_MIN || (Y_SPI_SENSORLESS && Y_HOME_TO_MIN) #if USE_Y_MIN || (Y_SPI_SENSORLESS && Y_HOME_TO_MIN)
PROCESS_ENDSTOP_Y(MIN); PROCESS_ENDSTOP_Y(MIN);
#if CORE_DIAG(XY, X, MIN) #if CORE_DIAG(XY, X, MIN)
PROCESS_CORE_ENDSTOP(X,MIN,Y,MIN); PROCESS_CORE_ENDSTOP(X,MIN,Y,MIN);
@ -1165,7 +1166,7 @@ void Endstops::update() {
#endif #endif
} }
else { // +direction else { // +direction
#if HAS_Y_MAX || (Y_SPI_SENSORLESS && Y_HOME_TO_MAX) #if USE_Y_MAX || (Y_SPI_SENSORLESS && Y_HOME_TO_MAX)
PROCESS_ENDSTOP_Y(MAX); PROCESS_ENDSTOP_Y(MAX);
#if CORE_DIAG(XY, X, MIN) #if CORE_DIAG(XY, X, MIN)
PROCESS_CORE_ENDSTOP(X,MIN,Y,MAX); PROCESS_CORE_ENDSTOP(X,MIN,Y,MAX);
@ -1185,7 +1186,7 @@ void Endstops::update() {
if (stepper.axis_is_moving(Z_AXIS)) { if (stepper.axis_is_moving(Z_AXIS)) {
if (stepper.motor_direction(Z_AXIS_HEAD)) { // Z -direction. Gantry down, bed up. if (stepper.motor_direction(Z_AXIS_HEAD)) { // Z -direction. Gantry down, bed up.
#if HAS_Z_MIN || (Z_SPI_SENSORLESS && Z_HOME_TO_MIN) #if USE_Z_MIN || (Z_SPI_SENSORLESS && Z_HOME_TO_MIN)
if ( TERN1(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, z_probe_enabled) if ( TERN1(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, z_probe_enabled)
&& TERN1(USES_Z_MIN_PROBE_PIN, !z_probe_enabled) && TERN1(USES_Z_MIN_PROBE_PIN, !z_probe_enabled)
) PROCESS_ENDSTOP_Z(MIN); ) PROCESS_ENDSTOP_Z(MIN);
@ -1206,7 +1207,7 @@ void Endstops::update() {
#endif #endif
} }
else { // Z +direction. Gantry up, bed down. else { // Z +direction. Gantry up, bed down.
#if HAS_Z_MAX || (Z_SPI_SENSORLESS && Z_HOME_TO_MAX) #if USE_Z_MAX || (Z_SPI_SENSORLESS && Z_HOME_TO_MAX)
#if ENABLED(Z_MULTI_ENDSTOPS) #if ENABLED(Z_MULTI_ENDSTOPS)
PROCESS_ENDSTOP_Z(MAX); PROCESS_ENDSTOP_Z(MAX);
#elif TERN1(USES_Z_MIN_PROBE_PIN, Z_MAX_PIN != Z_MIN_PROBE_PIN) // No probe or probe is Z_MIN || Probe is not Z_MAX #elif TERN1(USES_Z_MIN_PROBE_PIN, Z_MAX_PIN != Z_MIN_PROBE_PIN) // No probe or probe is Z_MIN || Probe is not Z_MAX
@ -1229,12 +1230,12 @@ void Endstops::update() {
#if HAS_I_AXIS #if HAS_I_AXIS
if (stepper.axis_is_moving(I_AXIS)) { if (stepper.axis_is_moving(I_AXIS)) {
if (stepper.motor_direction(I_AXIS_HEAD)) { // -direction if (stepper.motor_direction(I_AXIS_HEAD)) { // -direction
#if HAS_I_MIN || (I_SPI_SENSORLESS && I_HOME_TO_MIN) #if USE_I_MIN || (I_SPI_SENSORLESS && I_HOME_TO_MIN)
PROCESS_ENDSTOP(I, MIN); PROCESS_ENDSTOP(I, MIN);
#endif #endif
} }
else { // +direction else { // +direction
#if HAS_I_MAX || (I_SPI_SENSORLESS && I_HOME_TO_MAX) #if USE_I_MAX || (I_SPI_SENSORLESS && I_HOME_TO_MAX)
PROCESS_ENDSTOP(I, MAX); PROCESS_ENDSTOP(I, MAX);
#endif #endif
} }
@ -1244,12 +1245,12 @@ void Endstops::update() {
#if HAS_J_AXIS #if HAS_J_AXIS
if (stepper.axis_is_moving(J_AXIS)) { if (stepper.axis_is_moving(J_AXIS)) {
if (stepper.motor_direction(J_AXIS_HEAD)) { // -direction if (stepper.motor_direction(J_AXIS_HEAD)) { // -direction
#if HAS_J_MIN || (J_SPI_SENSORLESS && J_HOME_TO_MIN) #if USE_J_MIN || (J_SPI_SENSORLESS && J_HOME_TO_MIN)
PROCESS_ENDSTOP(J, MIN); PROCESS_ENDSTOP(J, MIN);
#endif #endif
} }
else { // +direction else { // +direction
#if HAS_J_MAX || (J_SPI_SENSORLESS && J_HOME_TO_MAX) #if USE_J_MAX || (J_SPI_SENSORLESS && J_HOME_TO_MAX)
PROCESS_ENDSTOP(J, MAX); PROCESS_ENDSTOP(J, MAX);
#endif #endif
} }
@ -1259,12 +1260,12 @@ void Endstops::update() {
#if HAS_K_AXIS #if HAS_K_AXIS
if (stepper.axis_is_moving(K_AXIS)) { if (stepper.axis_is_moving(K_AXIS)) {
if (stepper.motor_direction(K_AXIS_HEAD)) { // -direction if (stepper.motor_direction(K_AXIS_HEAD)) { // -direction
#if HAS_K_MIN || (K_SPI_SENSORLESS && K_HOME_TO_MIN) #if USE_K_MIN || (K_SPI_SENSORLESS && K_HOME_TO_MIN)
PROCESS_ENDSTOP(K, MIN); PROCESS_ENDSTOP(K, MIN);
#endif #endif
} }
else { // +direction else { // +direction
#if HAS_K_MAX || (K_SPI_SENSORLESS && K_HOME_TO_MAX) #if USE_K_MAX || (K_SPI_SENSORLESS && K_HOME_TO_MAX)
PROCESS_ENDSTOP(K, MAX); PROCESS_ENDSTOP(K, MAX);
#endif #endif
} }
@ -1274,12 +1275,12 @@ void Endstops::update() {
#if HAS_U_AXIS #if HAS_U_AXIS
if (stepper.axis_is_moving(U_AXIS)) { if (stepper.axis_is_moving(U_AXIS)) {
if (stepper.motor_direction(U_AXIS_HEAD)) { // -direction if (stepper.motor_direction(U_AXIS_HEAD)) { // -direction
#if HAS_U_MIN || (U_SPI_SENSORLESS && U_HOME_TO_MIN) #if USE_U_MIN || (U_SPI_SENSORLESS && U_HOME_TO_MIN)
PROCESS_ENDSTOP(U, MIN); PROCESS_ENDSTOP(U, MIN);
#endif #endif
} }
else { // +direction else { // +direction
#if HAS_U_MAX || (U_SPI_SENSORLESS && U_HOME_TO_MAX) #if USE_U_MAX || (U_SPI_SENSORLESS && U_HOME_TO_MAX)
PROCESS_ENDSTOP(U, MAX); PROCESS_ENDSTOP(U, MAX);
#endif #endif
} }
@ -1289,12 +1290,12 @@ void Endstops::update() {
#if HAS_V_AXIS #if HAS_V_AXIS
if (stepper.axis_is_moving(V_AXIS)) { if (stepper.axis_is_moving(V_AXIS)) {
if (stepper.motor_direction(V_AXIS_HEAD)) { // -direction if (stepper.motor_direction(V_AXIS_HEAD)) { // -direction
#if HAS_V_MIN || (V_SPI_SENSORLESS && V_HOME_TO_MIN) #if USE_V_MIN || (V_SPI_SENSORLESS && V_HOME_TO_MIN)
PROCESS_ENDSTOP(V, MIN); PROCESS_ENDSTOP(V, MIN);
#endif #endif
} }
else { // +direction else { // +direction
#if HAS_V_MAX || (V_SPI_SENSORLESS && V_HOME_TO_MAX) #if USE_V_MAX || (V_SPI_SENSORLESS && V_HOME_TO_MAX)
PROCESS_ENDSTOP(V, MAX); PROCESS_ENDSTOP(V, MAX);
#endif #endif
} }
@ -1304,12 +1305,12 @@ void Endstops::update() {
#if HAS_W_AXIS #if HAS_W_AXIS
if (stepper.axis_is_moving(W_AXIS)) { if (stepper.axis_is_moving(W_AXIS)) {
if (stepper.motor_direction(W_AXIS_HEAD)) { // -direction if (stepper.motor_direction(W_AXIS_HEAD)) { // -direction
#if HAS_W_MIN || (W_SPI_SENSORLESS && W_HOME_TO_MIN) #if USE_W_MIN || (W_SPI_SENSORLESS && W_HOME_TO_MIN)
PROCESS_ENDSTOP(W, MIN); PROCESS_ENDSTOP(W, MIN);
#endif #endif
} }
else { // +direction else { // +direction
#if HAS_W_MAX || (W_SPI_SENSORLESS && W_HOME_TO_MAX) #if USE_W_MAX || (W_SPI_SENSORLESS && W_HOME_TO_MAX)
PROCESS_ENDSTOP(W, MAX); PROCESS_ENDSTOP(W, MAX);
#endif #endif
} }
@ -1420,183 +1421,183 @@ void Endstops::update() {
#define ES_GET_STATE(S) if (READ_ENDSTOP(S##_PIN)) SBI(live_state_local, S) #define ES_GET_STATE(S) if (READ_ENDSTOP(S##_PIN)) SBI(live_state_local, S)
#if HAS_X_MIN #if USE_X_MIN
ES_GET_STATE(X_MIN); ES_GET_STATE(X_MIN);
#endif #endif
#if HAS_X_MAX #if USE_X_MAX
ES_GET_STATE(X_MAX); ES_GET_STATE(X_MAX);
#endif #endif
#if HAS_Y_MIN #if USE_Y_MIN
ES_GET_STATE(Y_MIN); ES_GET_STATE(Y_MIN);
#endif #endif
#if HAS_Y_MAX #if USE_Y_MAX
ES_GET_STATE(Y_MAX); ES_GET_STATE(Y_MAX);
#endif #endif
#if HAS_Z_MIN #if USE_Z_MIN
ES_GET_STATE(Z_MIN); ES_GET_STATE(Z_MIN);
#endif #endif
#if HAS_Z_MAX #if USE_Z_MAX
ES_GET_STATE(Z_MAX); ES_GET_STATE(Z_MAX);
#endif #endif
#if HAS_Z_MIN_PROBE_PIN #if HAS_Z_MIN_PROBE_PIN
ES_GET_STATE(Z_MIN_PROBE); ES_GET_STATE(Z_MIN_PROBE);
#endif #endif
#if HAS_X2_MIN #if USE_X2_MIN
ES_GET_STATE(X2_MIN); ES_GET_STATE(X2_MIN);
#endif #endif
#if HAS_X2_MAX #if USE_X2_MAX
ES_GET_STATE(X2_MAX); ES_GET_STATE(X2_MAX);
#endif #endif
#if HAS_Y2_MIN #if USE_Y2_MIN
ES_GET_STATE(Y2_MIN); ES_GET_STATE(Y2_MIN);
#endif #endif
#if HAS_Y2_MAX #if USE_Y2_MAX
ES_GET_STATE(Y2_MAX); ES_GET_STATE(Y2_MAX);
#endif #endif
#if HAS_Z2_MIN #if USE_Z2_MIN
ES_GET_STATE(Z2_MIN); ES_GET_STATE(Z2_MIN);
#endif #endif
#if HAS_Z2_MAX #if USE_Z2_MAX
ES_GET_STATE(Z2_MAX); ES_GET_STATE(Z2_MAX);
#endif #endif
#if HAS_Z3_MIN #if USE_Z3_MIN
ES_GET_STATE(Z3_MIN); ES_GET_STATE(Z3_MIN);
#endif #endif
#if HAS_Z3_MAX #if USE_Z3_MAX
ES_GET_STATE(Z3_MAX); ES_GET_STATE(Z3_MAX);
#endif #endif
#if HAS_Z4_MIN #if USE_Z4_MIN
ES_GET_STATE(Z4_MIN); ES_GET_STATE(Z4_MIN);
#endif #endif
#if HAS_Z4_MAX #if USE_Z4_MAX
ES_GET_STATE(Z4_MAX); ES_GET_STATE(Z4_MAX);
#endif #endif
#if HAS_I_MAX #if USE_I_MAX
ES_GET_STATE(I_MAX); ES_GET_STATE(I_MAX);
#endif #endif
#if HAS_I_MIN #if USE_I_MIN
ES_GET_STATE(I_MIN); ES_GET_STATE(I_MIN);
#endif #endif
#if HAS_J_MAX #if USE_J_MAX
ES_GET_STATE(J_MAX); ES_GET_STATE(J_MAX);
#endif #endif
#if HAS_J_MIN #if USE_J_MIN
ES_GET_STATE(J_MIN); ES_GET_STATE(J_MIN);
#endif #endif
#if HAS_K_MAX #if USE_K_MAX
ES_GET_STATE(K_MAX); ES_GET_STATE(K_MAX);
#endif #endif
#if HAS_K_MIN #if USE_K_MIN
ES_GET_STATE(K_MIN); ES_GET_STATE(K_MIN);
#endif #endif
#if HAS_U_MAX #if USE_U_MAX
ES_GET_STATE(U_MAX); ES_GET_STATE(U_MAX);
#endif #endif
#if HAS_U_MIN #if USE_U_MIN
ES_GET_STATE(U_MIN); ES_GET_STATE(U_MIN);
#endif #endif
#if HAS_V_MAX #if USE_V_MAX
ES_GET_STATE(V_MAX); ES_GET_STATE(V_MAX);
#endif #endif
#if HAS_V_MIN #if USE_V_MIN
ES_GET_STATE(V_MIN); ES_GET_STATE(V_MIN);
#endif #endif
#if HAS_W_MAX #if USE_W_MAX
ES_GET_STATE(W_MAX); ES_GET_STATE(W_MAX);
#endif #endif
#if HAS_W_MIN #if USE_W_MIN
ES_GET_STATE(W_MIN); ES_GET_STATE(W_MIN);
#endif #endif
uint16_t endstop_change = live_state_local ^ old_live_state_local; const uint16_t endstop_change = live_state_local ^ old_live_state_local;
#define ES_REPORT_CHANGE(S) if (TEST(endstop_change, S)) SERIAL_ECHOPGM(" " STRINGIFY(S) ":", TEST(live_state_local, S)) #define ES_REPORT_CHANGE(S) if (TEST(endstop_change, S)) SERIAL_ECHOPGM(" " STRINGIFY(S) ":", TEST(live_state_local, S))
if (endstop_change) { if (endstop_change) {
#if HAS_X_MIN #if USE_X_MIN
ES_REPORT_CHANGE(X_MIN); ES_REPORT_CHANGE(X_MIN);
#endif #endif
#if HAS_X_MAX #if USE_X_MAX
ES_REPORT_CHANGE(X_MAX); ES_REPORT_CHANGE(X_MAX);
#endif #endif
#if HAS_Y_MIN #if USE_Y_MIN
ES_REPORT_CHANGE(Y_MIN); ES_REPORT_CHANGE(Y_MIN);
#endif #endif
#if HAS_Y_MAX #if USE_Y_MAX
ES_REPORT_CHANGE(Y_MAX); ES_REPORT_CHANGE(Y_MAX);
#endif #endif
#if HAS_Z_MIN #if USE_Z_MIN
ES_REPORT_CHANGE(Z_MIN); ES_REPORT_CHANGE(Z_MIN);
#endif #endif
#if HAS_Z_MAX #if USE_Z_MAX
ES_REPORT_CHANGE(Z_MAX); ES_REPORT_CHANGE(Z_MAX);
#endif #endif
#if HAS_Z_MIN_PROBE_PIN #if HAS_Z_MIN_PROBE_PIN
ES_REPORT_CHANGE(Z_MIN_PROBE); ES_REPORT_CHANGE(Z_MIN_PROBE);
#endif #endif
#if HAS_X2_MIN #if USE_X2_MIN
ES_REPORT_CHANGE(X2_MIN); ES_REPORT_CHANGE(X2_MIN);
#endif #endif
#if HAS_X2_MAX #if USE_X2_MAX
ES_REPORT_CHANGE(X2_MAX); ES_REPORT_CHANGE(X2_MAX);
#endif #endif
#if HAS_Y2_MIN #if USE_Y2_MIN
ES_REPORT_CHANGE(Y2_MIN); ES_REPORT_CHANGE(Y2_MIN);
#endif #endif
#if HAS_Y2_MAX #if USE_Y2_MAX
ES_REPORT_CHANGE(Y2_MAX); ES_REPORT_CHANGE(Y2_MAX);
#endif #endif
#if HAS_Z2_MIN #if USE_Z2_MIN
ES_REPORT_CHANGE(Z2_MIN); ES_REPORT_CHANGE(Z2_MIN);
#endif #endif
#if HAS_Z2_MAX #if USE_Z2_MAX
ES_REPORT_CHANGE(Z2_MAX); ES_REPORT_CHANGE(Z2_MAX);
#endif #endif
#if HAS_Z3_MIN #if USE_Z3_MIN
ES_REPORT_CHANGE(Z3_MIN); ES_REPORT_CHANGE(Z3_MIN);
#endif #endif
#if HAS_Z3_MAX #if USE_Z3_MAX
ES_REPORT_CHANGE(Z3_MAX); ES_REPORT_CHANGE(Z3_MAX);
#endif #endif
#if HAS_Z4_MIN #if USE_Z4_MIN
ES_REPORT_CHANGE(Z4_MIN); ES_REPORT_CHANGE(Z4_MIN);
#endif #endif
#if HAS_Z4_MAX #if USE_Z4_MAX
ES_REPORT_CHANGE(Z4_MAX); ES_REPORT_CHANGE(Z4_MAX);
#endif #endif
#if HAS_I_MIN #if USE_I_MIN
ES_REPORT_CHANGE(I_MIN); ES_REPORT_CHANGE(I_MIN);
#endif #endif
#if HAS_I_MAX #if USE_I_MAX
ES_REPORT_CHANGE(I_MAX); ES_REPORT_CHANGE(I_MAX);
#endif #endif
#if HAS_J_MIN #if USE_J_MIN
ES_REPORT_CHANGE(J_MIN); ES_REPORT_CHANGE(J_MIN);
#endif #endif
#if HAS_J_MAX #if USE_J_MAX
ES_REPORT_CHANGE(J_MAX); ES_REPORT_CHANGE(J_MAX);
#endif #endif
#if HAS_K_MIN #if USE_K_MIN
ES_REPORT_CHANGE(K_MIN); ES_REPORT_CHANGE(K_MIN);
#endif #endif
#if HAS_K_MAX #if USE_K_MAX
ES_REPORT_CHANGE(K_MAX); ES_REPORT_CHANGE(K_MAX);
#endif #endif
#if HAS_U_MIN #if USE_U_MIN
ES_REPORT_CHANGE(U_MIN); ES_REPORT_CHANGE(U_MIN);
#endif #endif
#if HAS_U_MAX #if USE_U_MAX
ES_REPORT_CHANGE(U_MAX); ES_REPORT_CHANGE(U_MAX);
#endif #endif
#if HAS_V_MIN #if USE_V_MIN
ES_REPORT_CHANGE(V_MIN); ES_REPORT_CHANGE(V_MIN);
#endif #endif
#if HAS_V_MAX #if USE_V_MAX
ES_REPORT_CHANGE(V_MAX); ES_REPORT_CHANGE(V_MAX);
#endif #endif
#if HAS_W_MIN #if USE_W_MIN
ES_REPORT_CHANGE(W_MIN); ES_REPORT_CHANGE(W_MIN);
#endif #endif
#if HAS_W_MAX #if USE_W_MAX
ES_REPORT_CHANGE(W_MAX); ES_REPORT_CHANGE(W_MAX);
#endif #endif

View File

@ -51,44 +51,44 @@
*/ */
enum EndstopEnum : char { enum EndstopEnum : char {
// Common XYZ (ABC) endstops. Defined according to USE_[XYZ](MIN|MAX)_PLUG settings. // Common XYZ (ABC) endstops. Defined according to USE_[XYZ](MIN|MAX)_PLUG settings.
_ES_ITEM(HAS_X_MIN, X_MIN) _ES_ITEM(USE_X_MIN, X_MIN)
_ES_ITEM(HAS_X_MAX, X_MAX) _ES_ITEM(USE_X_MAX, X_MAX)
_ES_ITEM(HAS_Y_MIN, Y_MIN) _ES_ITEM(USE_Y_MIN, Y_MIN)
_ES_ITEM(HAS_Y_MAX, Y_MAX) _ES_ITEM(USE_Y_MAX, Y_MAX)
_ES_ITEM(HAS_Z_MIN, Z_MIN) _ES_ITEM(USE_Z_MIN, Z_MIN)
_ES_ITEM(HAS_Z_MAX, Z_MAX) _ES_ITEM(USE_Z_MAX, Z_MAX)
_ES_ITEM(HAS_I_MIN, I_MIN) _ES_ITEM(USE_I_MIN, I_MIN)
_ES_ITEM(HAS_I_MAX, I_MAX) _ES_ITEM(USE_I_MAX, I_MAX)
_ES_ITEM(HAS_J_MIN, J_MIN) _ES_ITEM(USE_J_MIN, J_MIN)
_ES_ITEM(HAS_J_MAX, J_MAX) _ES_ITEM(USE_J_MAX, J_MAX)
_ES_ITEM(HAS_K_MIN, K_MIN) _ES_ITEM(USE_K_MIN, K_MIN)
_ES_ITEM(HAS_K_MAX, K_MAX) _ES_ITEM(USE_K_MAX, K_MAX)
_ES_ITEM(HAS_U_MIN, U_MIN) _ES_ITEM(USE_U_MIN, U_MIN)
_ES_ITEM(HAS_U_MAX, U_MAX) _ES_ITEM(USE_U_MAX, U_MAX)
_ES_ITEM(HAS_V_MIN, V_MIN) _ES_ITEM(USE_V_MIN, V_MIN)
_ES_ITEM(HAS_V_MAX, V_MAX) _ES_ITEM(USE_V_MAX, V_MAX)
_ES_ITEM(HAS_W_MIN, W_MIN) _ES_ITEM(USE_W_MIN, W_MIN)
_ES_ITEM(HAS_W_MAX, W_MAX) _ES_ITEM(USE_W_MAX, W_MAX)
// Extra Endstops for XYZ // Extra Endstops for XYZ
#if ENABLED(X_DUAL_ENDSTOPS) #if ENABLED(X_DUAL_ENDSTOPS)
_ES_ITEM(HAS_X_MIN, X2_MIN) _ES_ITEM(USE_X_MIN, X2_MIN)
_ES_ITEM(HAS_X_MAX, X2_MAX) _ES_ITEM(USE_X_MAX, X2_MAX)
#endif #endif
#if ENABLED(Y_DUAL_ENDSTOPS) #if ENABLED(Y_DUAL_ENDSTOPS)
_ES_ITEM(HAS_Y_MIN, Y2_MIN) _ES_ITEM(USE_Y_MIN, Y2_MIN)
_ES_ITEM(HAS_Y_MAX, Y2_MAX) _ES_ITEM(USE_Y_MAX, Y2_MAX)
#endif #endif
#if ENABLED(Z_MULTI_ENDSTOPS) #if ENABLED(Z_MULTI_ENDSTOPS)
_ES_ITEM(HAS_Z_MIN, Z2_MIN) _ES_ITEM(USE_Z_MIN, Z2_MIN)
_ES_ITEM(HAS_Z_MAX, Z2_MAX) _ES_ITEM(USE_Z_MAX, Z2_MAX)
#if NUM_Z_STEPPERS >= 3 #if NUM_Z_STEPPERS >= 3
_ES_ITEM(HAS_Z_MIN, Z3_MIN) _ES_ITEM(USE_Z_MIN, Z3_MIN)
_ES_ITEM(HAS_Z_MAX, Z3_MAX) _ES_ITEM(USE_Z_MAX, Z3_MAX)
#endif #endif
#if NUM_Z_STEPPERS >= 4 #if NUM_Z_STEPPERS >= 4
_ES_ITEM(HAS_Z_MIN, Z4_MIN) _ES_ITEM(USE_Z_MIN, Z4_MIN)
_ES_ITEM(HAS_Z_MAX, Z4_MAX) _ES_ITEM(USE_Z_MAX, Z4_MAX)
#endif #endif
#endif #endif
@ -101,28 +101,28 @@ enum EndstopEnum : char {
NUM_ENDSTOP_STATES NUM_ENDSTOP_STATES
// Endstops can be either MIN or MAX but not both // Endstops can be either MIN or MAX but not both
#if HAS_X_MIN || HAS_X_MAX #if USE_X_MIN || USE_X_MAX
, X_ENDSTOP = TERN(X_HOME_TO_MAX, X_MAX, X_MIN) , X_ENDSTOP = TERN(X_HOME_TO_MAX, X_MAX, X_MIN)
#if ENABLED(X_DUAL_ENDSTOPS) #if ENABLED(X_DUAL_ENDSTOPS)
, X2_ENDSTOP = TERN(X_HOME_TO_MAX, X2_MAX, X2_MIN) , X2_ENDSTOP = TERN(X_HOME_TO_MAX, X2_MAX, X2_MIN)
#endif #endif
#endif #endif
#if HAS_Y_MIN || HAS_Y_MAX #if USE_Y_MIN || USE_Y_MAX
, Y_ENDSTOP = TERN(Y_HOME_TO_MAX, Y_MAX, Y_MIN) , Y_ENDSTOP = TERN(Y_HOME_TO_MAX, Y_MAX, Y_MIN)
#if ENABLED(Y_DUAL_ENDSTOPS) #if ENABLED(Y_DUAL_ENDSTOPS)
, Y2_ENDSTOP = TERN(Y_HOME_TO_MAX, Y2_MAX, Y2_MIN) , Y2_ENDSTOP = TERN(Y_HOME_TO_MAX, Y2_MAX, Y2_MIN)
#endif #endif
#endif #endif
#if HAS_Z_MIN || HAS_Z_MAX || HOMING_Z_WITH_PROBE #if USE_Z_MIN || USE_Z_MAX || HOMING_Z_WITH_PROBE
, Z_ENDSTOP = TERN(HOMING_Z_WITH_PROBE, Z_MIN_PROBE, TERN(Z_HOME_TO_MAX, Z_MAX, Z_MIN)) , Z_ENDSTOP = TERN(HOMING_Z_WITH_PROBE, Z_MIN_PROBE, TERN(Z_HOME_TO_MAX, Z_MAX, Z_MIN))
#endif #endif
#if HAS_I_MIN || HAS_I_MAX #if USE_I_MIN || USE_I_MAX
, I_ENDSTOP = TERN(I_HOME_TO_MAX, I_MAX, I_MIN) , I_ENDSTOP = TERN(I_HOME_TO_MAX, I_MAX, I_MIN)
#endif #endif
#if HAS_J_MIN || HAS_J_MAX #if USE_J_MIN || USE_J_MAX
, J_ENDSTOP = TERN(J_HOME_TO_MAX, J_MAX, J_MIN) , J_ENDSTOP = TERN(J_HOME_TO_MAX, J_MAX, J_MIN)
#endif #endif
#if HAS_K_MIN || HAS_K_MAX #if USE_K_MIN || USE_K_MAX
, K_ENDSTOP = TERN(K_HOME_TO_MAX, K_MAX, K_MIN) , K_ENDSTOP = TERN(K_HOME_TO_MAX, K_MAX, K_MIN)
#endif #endif
}; };
@ -133,7 +133,7 @@ enum EndstopEnum : char {
class Endstops { class Endstops {
public: public:
typedef IF<(NUM_ENDSTOP_STATES > 8), uint16_t, uint8_t>::type endstop_mask_t; typedef bits_t(NUM_ENDSTOP_STATES) endstop_mask_t;
#if ENABLED(X_DUAL_ENDSTOPS) #if ENABLED(X_DUAL_ENDSTOPS)
static float x2_endstop_adj; static float x2_endstop_adj;

View File

@ -191,6 +191,7 @@ inline void report_more_positions() {
// Report the logical position for a given machine position // Report the logical position for a given machine position
inline void report_logical_position(const xyze_pos_t &rpos) { inline void report_logical_position(const xyze_pos_t &rpos) {
const xyze_pos_t lpos = rpos.asLogical(); const xyze_pos_t lpos = rpos.asLogical();
#if NUM_AXES
SERIAL_ECHOPGM_P( SERIAL_ECHOPGM_P(
LIST_N(DOUBLE(NUM_AXES), LIST_N(DOUBLE(NUM_AXES),
X_LBL, lpos.x, X_LBL, lpos.x,
@ -203,10 +204,11 @@ inline void report_logical_position(const xyze_pos_t &rpos) {
SP_V_LBL, lpos.v, SP_V_LBL, lpos.v,
SP_W_LBL, lpos.w SP_W_LBL, lpos.w
) )
#if HAS_EXTRUDERS
, SP_E_LBL, lpos.e
#endif
); );
#endif
#if HAS_EXTRUDERS
SERIAL_ECHOPGM_P(SP_E_LBL, lpos.e);
#endif
} }
// Report the real current position according to the steppers. // Report the real current position according to the steppers.
@ -354,7 +356,7 @@ void report_current_position_projected() {
#else // CARTESIAN #else // CARTESIAN
// Return true if the given position is within the machine bounds. // Return true if the given position is within the machine bounds.
bool position_is_reachable(const_float_t rx, const_float_t ry) { bool position_is_reachable(TERN_(HAS_X_AXIS, const_float_t rx) OPTARG(HAS_Y_AXIS, const_float_t ry)) {
if (TERN0(HAS_Y_AXIS, !COORDINATE_OKAY(ry, Y_MIN_POS - fslop, Y_MAX_POS + fslop))) return false; if (TERN0(HAS_Y_AXIS, !COORDINATE_OKAY(ry, Y_MIN_POS - fslop, Y_MAX_POS + fslop))) return false;
#if ENABLED(DUAL_X_CARRIAGE) #if ENABLED(DUAL_X_CARRIAGE)
if (active_extruder) if (active_extruder)
@ -362,7 +364,8 @@ void report_current_position_projected() {
else else
return COORDINATE_OKAY(rx, X1_MIN_POS - fslop, X1_MAX_POS + fslop); return COORDINATE_OKAY(rx, X1_MIN_POS - fslop, X1_MAX_POS + fslop);
#else #else
return COORDINATE_OKAY(rx, X_MIN_POS - fslop, X_MAX_POS + fslop); if (TERN0(HAS_X_AXIS, !COORDINATE_OKAY(rx, X_MIN_POS - fslop, X_MAX_POS + fslop))) return false;
return true;
#endif #endif
} }
@ -515,27 +518,32 @@ void line_to_current_position(const_feedRate_t fr_mm_s/*=feedrate_mm_s*/) {
void _internal_move_to_destination(const_feedRate_t fr_mm_s/*=0.0f*/ void _internal_move_to_destination(const_feedRate_t fr_mm_s/*=0.0f*/
OPTARG(IS_KINEMATIC, const bool is_fast/*=false*/) OPTARG(IS_KINEMATIC, const bool is_fast/*=false*/)
) { ) {
const feedRate_t old_feedrate = feedrate_mm_s; REMEMBER(fr, feedrate_mm_s);
REMEMBER(pct, feedrate_percentage, 100);
TERN_(HAS_EXTRUDERS, REMEMBER(fac, planner.e_factor[active_extruder], 1.0f));
if (fr_mm_s) feedrate_mm_s = fr_mm_s; if (fr_mm_s) feedrate_mm_s = fr_mm_s;
const uint16_t old_pct = feedrate_percentage;
feedrate_percentage = 100;
#if HAS_EXTRUDERS
const float old_fac = planner.e_factor[active_extruder];
planner.e_factor[active_extruder] = 1.0f;
#endif
if (TERN0(IS_KINEMATIC, is_fast)) if (TERN0(IS_KINEMATIC, is_fast))
TERN(IS_KINEMATIC, prepare_fast_move_to_destination(), NOOP); TERN(IS_KINEMATIC, prepare_fast_move_to_destination(), NOOP);
else else
prepare_line_to_destination(); prepare_line_to_destination();
feedrate_mm_s = old_feedrate;
feedrate_percentage = old_pct;
TERN_(HAS_EXTRUDERS, planner.e_factor[active_extruder] = old_fac);
} }
#if SECONDARY_AXES
void secondary_axis_moves(SECONDARY_AXIS_ARGS(const_float_t), const_feedRate_t fr_mm_s) {
auto move_one = [&](const AxisEnum a, const_float_t p) {
const feedRate_t fr = fr_mm_s ?: homing_feedrate(a);
current_position[a] = p; line_to_current_position(fr);
};
SECONDARY_AXIS_CODE(
move_one(I_AXIS, i), move_one(J_AXIS, j), move_one(K_AXIS, k),
move_one(U_AXIS, u), move_one(V_AXIS, v), move_one(W_AXIS, w)
);
}
#endif
/** /**
* Plan a move to (X, Y, Z, [I, [J, [K...]]]) and set the current_position * Plan a move to (X, Y, Z, [I, [J, [K...]]]) and set the current_position
* Plan a move to (X, Y, Z, [I, [J, [K...]]]) with separation of Z from other components. * Plan a move to (X, Y, Z, [I, [J, [K...]]]) with separation of Z from other components.
@ -545,23 +553,17 @@ 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. * - Delta may lower Z first to get into the free motion zone.
* - Before returning, wait for the planner buffer to empty. * - Before returning, wait for the planner buffer to empty.
*/ */
void do_blocking_move_to(NUM_AXIS_ARGS(const_float_t), const_feedRate_t fr_mm_s/*=0.0f*/) { void do_blocking_move_to(NUM_AXIS_ARGS_(const_float_t) const_feedRate_t fr_mm_s/*=0.0f*/) {
DEBUG_SECTION(log_move, "do_blocking_move_to", DEBUGGING(LEVELING)); DEBUG_SECTION(log_move, "do_blocking_move_to", DEBUGGING(LEVELING));
#if NUM_AXES
if (DEBUGGING(LEVELING)) DEBUG_XYZ("> ", NUM_AXIS_ARGS()); if (DEBUGGING(LEVELING)) DEBUG_XYZ("> ", NUM_AXIS_ARGS());
#endif
const feedRate_t xy_feedrate = fr_mm_s ?: feedRate_t(XY_PROBE_FEEDRATE_MM_S); const feedRate_t xy_feedrate = fr_mm_s ?: feedRate_t(XY_PROBE_FEEDRATE_MM_S);
#if HAS_Z_AXIS #if HAS_Z_AXIS
const feedRate_t z_feedrate = fr_mm_s ?: homing_feedrate(Z_AXIS); const feedRate_t z_feedrate = fr_mm_s ?: homing_feedrate(Z_AXIS);
#endif #endif
SECONDARY_AXIS_CODE(
const feedRate_t i_feedrate = fr_mm_s ?: homing_feedrate(I_AXIS),
const feedRate_t j_feedrate = fr_mm_s ?: homing_feedrate(J_AXIS),
const feedRate_t k_feedrate = fr_mm_s ?: homing_feedrate(K_AXIS),
const feedRate_t u_feedrate = fr_mm_s ?: homing_feedrate(U_AXIS),
const feedRate_t v_feedrate = fr_mm_s ?: homing_feedrate(V_AXIS),
const feedRate_t w_feedrate = fr_mm_s ?: homing_feedrate(W_AXIS)
);
#if IS_KINEMATIC && DISABLED(POLARGRAPH) #if IS_KINEMATIC && DISABLED(POLARGRAPH)
// kinematic machines are expected to home to a point 1.5x their range? never reachable. // kinematic machines are expected to home to a point 1.5x their range? never reachable.
@ -604,6 +606,10 @@ void do_blocking_move_to(NUM_AXIS_ARGS(const_float_t), const_feedRate_t fr_mm_s/
if (DEBUGGING(LEVELING)) DEBUG_POS("z lower move", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("z lower move", current_position);
} }
#if SECONDARY_AXES
secondary_axis_moves(SECONDARY_AXIS_LIST(i, j, k, u, v, w), fr_mm_s);
#endif
#elif IS_SCARA #elif IS_SCARA
// If Z needs to raise, do it before moving XY // If Z needs to raise, do it before moving XY
@ -611,6 +617,10 @@ void do_blocking_move_to(NUM_AXIS_ARGS(const_float_t), const_feedRate_t fr_mm_s/
destination.set(x, y); prepare_internal_fast_move_to_destination(xy_feedrate); destination.set(x, y); prepare_internal_fast_move_to_destination(xy_feedrate);
#if SECONDARY_AXES
secondary_axis_moves(SECONDARY_AXIS_LIST(i, j, k, u, v, w), fr_mm_s);
#endif
// If Z needs to lower, do it after moving XY // If Z needs to lower, do it after moving XY
if (destination.z > z) { destination.z = z; prepare_internal_fast_move_to_destination(z_feedrate); } if (destination.z > z) { destination.z = z; prepare_internal_fast_move_to_destination(z_feedrate); }
@ -620,25 +630,10 @@ void do_blocking_move_to(NUM_AXIS_ARGS(const_float_t), const_feedRate_t fr_mm_s/
if (current_position.z < z) { current_position.z = z; line_to_current_position(z_feedrate); } if (current_position.z < z) { current_position.z = z; line_to_current_position(z_feedrate); }
#endif #endif
current_position.set(x OPTARG(HAS_Y_AXIS, y)); line_to_current_position(xy_feedrate); current_position.set(TERN_(HAS_X_AXIS, x) OPTARG(HAS_Y_AXIS, y)); line_to_current_position(xy_feedrate);
#if HAS_I_AXIS #if SECONDARY_AXES
current_position.i = i; line_to_current_position(i_feedrate); secondary_axis_moves(SECONDARY_AXIS_LIST(i, j, k, u, v, w), fr_mm_s);
#endif
#if HAS_J_AXIS
current_position.j = j; line_to_current_position(j_feedrate);
#endif
#if HAS_K_AXIS
current_position.k = k; line_to_current_position(k_feedrate);
#endif
#if HAS_U_AXIS
current_position.u = u; line_to_current_position(u_feedrate);
#endif
#if HAS_V_AXIS
current_position.v = v; line_to_current_position(v_feedrate);
#endif
#if HAS_W_AXIS
current_position.w = w; line_to_current_position(w_feedrate);
#endif #endif
#if HAS_Z_AXIS #if HAS_Z_AXIS
@ -652,28 +647,33 @@ void do_blocking_move_to(NUM_AXIS_ARGS(const_float_t), const_feedRate_t fr_mm_s/
} }
void do_blocking_move_to(const xy_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*/) { void do_blocking_move_to(const xy_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*/) {
do_blocking_move_to(NUM_AXIS_LIST(raw.x, raw.y, current_position.z, current_position.i, current_position.j, current_position.k, do_blocking_move_to(NUM_AXIS_LIST_(raw.x, raw.y, current_position.z, current_position.i, current_position.j, current_position.k,
current_position.u, current_position.v, current_position.w), fr_mm_s); current_position.u, current_position.v, current_position.w) fr_mm_s);
} }
void do_blocking_move_to(const xyz_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*/) { void do_blocking_move_to(const xyz_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*/) {
do_blocking_move_to(NUM_AXIS_ELEM(raw), fr_mm_s); do_blocking_move_to(NUM_AXIS_ELEM_(raw) fr_mm_s);
} }
void do_blocking_move_to(const xyze_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*/) { void do_blocking_move_to(const xyze_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*/) {
do_blocking_move_to(NUM_AXIS_ELEM(raw), fr_mm_s); do_blocking_move_to(NUM_AXIS_ELEM_(raw) fr_mm_s);
} }
void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
#if HAS_X_AXIS
void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("do_blocking_move_to_x(", rx, ", ", fr_mm_s, ")");
do_blocking_move_to( do_blocking_move_to(
NUM_AXIS_LIST(rx, current_position.y, current_position.z, current_position.i, current_position.j, current_position.k, NUM_AXIS_LIST_(rx, current_position.y, current_position.z, current_position.i, current_position.j, current_position.k,
current_position.u, current_position.v, current_position.w), current_position.u, current_position.v, current_position.w)
fr_mm_s fr_mm_s
); );
} }
#endif
#if HAS_Y_AXIS #if HAS_Y_AXIS
void do_blocking_move_to_y(const_float_t ry, const_feedRate_t fr_mm_s/*=0.0*/) { void do_blocking_move_to_y(const_float_t ry, const_feedRate_t fr_mm_s/*=0.0*/) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("do_blocking_move_to_y(", ry, ", ", fr_mm_s, ")");
do_blocking_move_to( do_blocking_move_to(
NUM_AXIS_LIST(current_position.x, ry, current_position.z, current_position.i, current_position.j, current_position.k, NUM_AXIS_LIST_(current_position.x, ry, current_position.z, current_position.i, current_position.j, current_position.k,
current_position.u, current_position.v, current_position.w), current_position.u, current_position.v, current_position.w)
fr_mm_s fr_mm_s
); );
} }
@ -681,6 +681,7 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
#if HAS_Z_AXIS #if HAS_Z_AXIS
void do_blocking_move_to_z(const_float_t rz, const_feedRate_t fr_mm_s/*=0.0*/) { void do_blocking_move_to_z(const_float_t rz, const_feedRate_t fr_mm_s/*=0.0*/) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("do_blocking_move_to_z(", rz, ", ", fr_mm_s, ")");
do_blocking_move_to_xy_z(current_position, rz, fr_mm_s); do_blocking_move_to_xy_z(current_position, rz, fr_mm_s);
} }
#endif #endif
@ -691,7 +692,7 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
} }
void do_blocking_move_to_xyz_i(const xyze_pos_t &raw, const_float_t i, const_feedRate_t fr_mm_s/*=0.0f*/) { void do_blocking_move_to_xyz_i(const xyze_pos_t &raw, const_float_t i, const_feedRate_t fr_mm_s/*=0.0f*/) {
do_blocking_move_to( do_blocking_move_to(
NUM_AXIS_LIST(raw.x, raw.y, raw.z, i, raw.j, raw.k, raw.u, raw.v, raw.w), NUM_AXIS_LIST_(raw.x, raw.y, raw.z, i, raw.j, raw.k, raw.u, raw.v, raw.w)
fr_mm_s fr_mm_s
); );
} }
@ -703,7 +704,7 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
} }
void do_blocking_move_to_xyzi_j(const xyze_pos_t &raw, const_float_t j, const_feedRate_t fr_mm_s/*=0.0f*/) { void do_blocking_move_to_xyzi_j(const xyze_pos_t &raw, const_float_t j, const_feedRate_t fr_mm_s/*=0.0f*/) {
do_blocking_move_to( do_blocking_move_to(
NUM_AXIS_LIST(raw.x, raw.y, raw.z, raw.i, j, raw.k, raw.u, raw.v, raw.w), NUM_AXIS_LIST_(raw.x, raw.y, raw.z, raw.i, j, raw.k, raw.u, raw.v, raw.w)
fr_mm_s fr_mm_s
); );
} }
@ -715,7 +716,7 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
} }
void do_blocking_move_to_xyzij_k(const xyze_pos_t &raw, const_float_t k, const_feedRate_t fr_mm_s/*=0.0f*/) { void do_blocking_move_to_xyzij_k(const xyze_pos_t &raw, const_float_t k, const_feedRate_t fr_mm_s/*=0.0f*/) {
do_blocking_move_to( do_blocking_move_to(
NUM_AXIS_LIST(raw.x, raw.y, raw.z, raw.i, raw.j, k, raw.u, raw.v, raw.w), NUM_AXIS_LIST_(raw.x, raw.y, raw.z, raw.i, raw.j, k, raw.u, raw.v, raw.w)
fr_mm_s fr_mm_s
); );
} }
@ -727,7 +728,7 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
} }
void do_blocking_move_to_xyzijk_u(const xyze_pos_t &raw, const_float_t u, const_feedRate_t fr_mm_s/*=0.0f*/) { void do_blocking_move_to_xyzijk_u(const xyze_pos_t &raw, const_float_t u, const_feedRate_t fr_mm_s/*=0.0f*/) {
do_blocking_move_to( do_blocking_move_to(
NUM_AXIS_LIST(raw.x, raw.y, raw.z, raw.i, raw.j, raw.k, u, raw.v, raw.w), NUM_AXIS_LIST_(raw.x, raw.y, raw.z, raw.i, raw.j, raw.k, u, raw.v, raw.w)
fr_mm_s fr_mm_s
); );
} }
@ -739,7 +740,7 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
} }
void do_blocking_move_to_xyzijku_v(const xyze_pos_t &raw, const_float_t v, const_feedRate_t fr_mm_s/*=0.0f*/) { void do_blocking_move_to_xyzijku_v(const xyze_pos_t &raw, const_float_t v, const_feedRate_t fr_mm_s/*=0.0f*/) {
do_blocking_move_to( do_blocking_move_to(
NUM_AXIS_LIST(raw.x, raw.y, raw.z, raw.i, raw.j, raw.k, raw.u, v, raw.w), NUM_AXIS_LIST_(raw.x, raw.y, raw.z, raw.i, raw.j, raw.k, raw.u, v, raw.w)
fr_mm_s fr_mm_s
); );
} }
@ -751,7 +752,7 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
} }
void do_blocking_move_to_xyzijkuv_w(const xyze_pos_t &raw, const_float_t w, const_feedRate_t fr_mm_s/*=0.0f*/) { void do_blocking_move_to_xyzijkuv_w(const xyze_pos_t &raw, const_float_t w, const_feedRate_t fr_mm_s/*=0.0f*/) {
do_blocking_move_to( do_blocking_move_to(
NUM_AXIS_LIST(raw.x, raw.y, raw.z, raw.i, raw.j, raw.k, raw.u, raw.v, w), NUM_AXIS_LIST_(raw.x, raw.y, raw.z, raw.i, raw.j, raw.k, raw.u, raw.v, w)
fr_mm_s fr_mm_s
); );
} }
@ -759,9 +760,10 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
#if HAS_Y_AXIS #if HAS_Y_AXIS
void do_blocking_move_to_xy(const_float_t rx, const_float_t ry, const_feedRate_t fr_mm_s/*=0.0*/) { void do_blocking_move_to_xy(const_float_t rx, const_float_t ry, const_feedRate_t fr_mm_s/*=0.0*/) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("do_blocking_move_to_xy(", rx, ", ", ry, ", ", fr_mm_s, ")");
do_blocking_move_to( do_blocking_move_to(
NUM_AXIS_LIST(rx, ry, current_position.z, current_position.i, current_position.j, current_position.k, NUM_AXIS_LIST_(rx, ry, current_position.z, current_position.i, current_position.j, current_position.k,
current_position.u, current_position.v, current_position.w), current_position.u, current_position.v, current_position.w)
fr_mm_s fr_mm_s
); );
} }
@ -773,8 +775,8 @@ void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
#if HAS_Z_AXIS #if HAS_Z_AXIS
void do_blocking_move_to_xy_z(const xy_pos_t &raw, const_float_t z, const_feedRate_t fr_mm_s/*=0.0f*/) { 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( do_blocking_move_to(
NUM_AXIS_LIST(raw.x, raw.y, z, current_position.i, current_position.j, current_position.k, NUM_AXIS_LIST_(raw.x, raw.y, z, current_position.i, current_position.j, current_position.k,
current_position.u, current_position.v, current_position.w), current_position.u, current_position.v, current_position.w)
fr_mm_s fr_mm_s
); );
} }
@ -900,7 +902,7 @@ void restore_feedrate_and_scaling() {
#endif #endif
if (DEBUGGING(LEVELING)) if (DEBUGGING(LEVELING))
SERIAL_ECHOLNPGM("Axis ", AS_CHAR(AXIS_CHAR(axis)), " min:", soft_endstop.min[axis], " max:", soft_endstop.max[axis]); SERIAL_ECHOLNPGM("Axis ", C(AXIS_CHAR(axis)), " min:", soft_endstop.min[axis], " max:", soft_endstop.max[axis]);
} }
/** /**
@ -938,6 +940,7 @@ void restore_feedrate_and_scaling() {
#else #else
#if HAS_X_AXIS
if (axis_was_homed(X_AXIS)) { if (axis_was_homed(X_AXIS)) {
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_X) #if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_X)
NOLESS(target.x, soft_endstop.min.x); NOLESS(target.x, soft_endstop.min.x);
@ -946,6 +949,7 @@ void restore_feedrate_and_scaling() {
NOMORE(target.x, soft_endstop.max.x); NOMORE(target.x, soft_endstop.max.x);
#endif #endif
} }
#endif
#if HAS_Y_AXIS #if HAS_Y_AXIS
if (axis_was_homed(Y_AXIS)) { if (axis_was_homed(Y_AXIS)) {
@ -1293,13 +1297,13 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) {
void idex_set_mirrored_mode(const bool mirr) { void idex_set_mirrored_mode(const bool mirr) {
idex_mirrored_mode = mirr; idex_mirrored_mode = mirr;
stepper.set_directions(); stepper.apply_directions();
} }
void set_duplication_enabled(const bool dupe, const int8_t tool_index/*=-1*/) { void set_duplication_enabled(const bool dupe, const int8_t tool_index/*=-1*/) {
extruder_duplication_enabled = dupe; extruder_duplication_enabled = dupe;
if (tool_index >= 0) active_extruder = tool_index; if (tool_index >= 0) active_extruder = tool_index;
stepper.set_directions(); stepper.apply_directions();
} }
void idex_set_parked(const bool park/*=true*/) { void idex_set_parked(const bool park/*=true*/) {
@ -1345,7 +1349,7 @@ FORCE_INLINE void segment_idle(millis_t &next_idle_ms) {
line_to_current_position(fr_zfast); line_to_current_position(fr_zfast);
} }
} }
stepper.set_directions(); stepper.apply_directions();
idex_set_parked(false); idex_set_parked(false);
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("idex_set_parked(false)"); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("idex_set_parked(false)");
@ -1404,12 +1408,8 @@ void prepare_line_to_destination() {
#if ANY(PREVENT_COLD_EXTRUSION, PREVENT_LENGTHY_EXTRUDE) #if ANY(PREVENT_COLD_EXTRUSION, PREVENT_LENGTHY_EXTRUDE)
if (!DEBUGGING(DRYRUN) && destination.e != current_position.e) { if (!DEBUGGING(DRYRUN) && destination.e != current_position.e) {
bool ignore_e = false; bool ignore_e = thermalManager.tooColdToExtrude(active_extruder);
#if ENABLED(PREVENT_COLD_EXTRUSION)
ignore_e = thermalManager.tooColdToExtrude(active_extruder);
if (ignore_e) SERIAL_ECHO_MSG(STR_ERR_COLD_EXTRUDE_STOP); if (ignore_e) SERIAL_ECHO_MSG(STR_ERR_COLD_EXTRUDE_STOP);
#endif
#if ENABLED(PREVENT_LENGTHY_EXTRUDE) #if ENABLED(PREVENT_LENGTHY_EXTRUDE)
const float e_delta = ABS(destination.e - current_position.e) * planner.e_factor[active_extruder]; const float e_delta = ABS(destination.e - current_position.e) * planner.e_factor[active_extruder];
@ -1575,36 +1575,36 @@ void prepare_line_to_destination() {
#endif #endif
} }
#if ENABLED(SPI_ENDSTOPS)
switch (axis) { switch (axis) {
case X_AXIS: if (ENABLED(X_SPI_SENSORLESS)) endstops.tmc_spi_homing.x = true; break; #if X_SPI_SENSORLESS
#if HAS_Y_AXIS case X_AXIS: endstops.tmc_spi_homing.x = true; break;
case Y_AXIS: if (ENABLED(Y_SPI_SENSORLESS)) endstops.tmc_spi_homing.y = true; break;
#endif #endif
#if HAS_Z_AXIS #if Y_SPI_SENSORLESS
case Z_AXIS: if (ENABLED(Z_SPI_SENSORLESS)) endstops.tmc_spi_homing.z = true; break; case Y_AXIS: endstops.tmc_spi_homing.y = true; break;
#endif #endif
#if HAS_I_AXIS #if Z_SPI_SENSORLESS
case I_AXIS: if (ENABLED(I_SPI_SENSORLESS)) endstops.tmc_spi_homing.i = true; break; case Z_AXIS: endstops.tmc_spi_homing.z = true; break;
#endif #endif
#if HAS_J_AXIS #if I_SPI_SENSORLESS
case J_AXIS: if (ENABLED(J_SPI_SENSORLESS)) endstops.tmc_spi_homing.j = true; break; case I_AXIS: endstops.tmc_spi_homing.i = true; break;
#endif #endif
#if HAS_K_AXIS #if J_SPI_SENSORLESS
case K_AXIS: if (ENABLED(K_SPI_SENSORLESS)) endstops.tmc_spi_homing.k = true; break; case J_AXIS: endstops.tmc_spi_homing.j = true; break;
#endif #endif
#if HAS_U_AXIS #if K_SPI_SENSORLESS
case U_AXIS: if (ENABLED(U_SPI_SENSORLESS)) endstops.tmc_spi_homing.u = true; break; case K_AXIS: endstops.tmc_spi_homing.k = true; break;
#endif #endif
#if HAS_V_AXIS #if U_SPI_SENSORLESS
case V_AXIS: if (ENABLED(V_SPI_SENSORLESS)) endstops.tmc_spi_homing.v = true; break; case U_AXIS: endstops.tmc_spi_homing.u = true; break;
#endif #endif
#if HAS_W_AXIS #if V_SPI_SENSORLESS
case W_AXIS: if (ENABLED(W_SPI_SENSORLESS)) endstops.tmc_spi_homing.w = true; break; case V_AXIS: endstops.tmc_spi_homing.v = true; break;
#endif
#if W_SPI_SENSORLESS
case W_AXIS: endstops.tmc_spi_homing.w = true; break;
#endif #endif
default: break; default: break;
} }
#endif
TERN_(IMPROVE_HOMING_RELIABILITY, sg_guard_period = millis() + default_sg_guard_duration); TERN_(IMPROVE_HOMING_RELIABILITY, sg_guard_period = millis() + default_sg_guard_duration);
@ -1669,36 +1669,36 @@ void prepare_line_to_destination() {
#endif #endif
} }
#if ENABLED(SPI_ENDSTOPS)
switch (axis) { switch (axis) {
case X_AXIS: if (ENABLED(X_SPI_SENSORLESS)) endstops.tmc_spi_homing.x = false; break; #if X_SPI_SENSORLESS
#if HAS_Y_AXIS case X_AXIS: endstops.tmc_spi_homing.x = false; break;
case Y_AXIS: if (ENABLED(Y_SPI_SENSORLESS)) endstops.tmc_spi_homing.y = false; break;
#endif #endif
#if HAS_Z_AXIS #if Y_SPI_SENSORLESS
case Z_AXIS: if (ENABLED(Z_SPI_SENSORLESS)) endstops.tmc_spi_homing.z = false; break; case Y_AXIS: endstops.tmc_spi_homing.y = false; break;
#endif #endif
#if HAS_I_AXIS #if Z_SPI_SENSORLESS
case I_AXIS: if (ENABLED(I_SPI_SENSORLESS)) endstops.tmc_spi_homing.i = false; break; case Z_AXIS: endstops.tmc_spi_homing.z = false; break;
#endif #endif
#if HAS_J_AXIS #if I_SPI_SENSORLESS
case J_AXIS: if (ENABLED(J_SPI_SENSORLESS)) endstops.tmc_spi_homing.j = false; break; case I_AXIS: endstops.tmc_spi_homing.i = false; break;
#endif #endif
#if HAS_K_AXIS #if J_SPI_SENSORLESS
case K_AXIS: if (ENABLED(K_SPI_SENSORLESS)) endstops.tmc_spi_homing.k = false; break; case J_AXIS: endstops.tmc_spi_homing.j = false; break;
#endif #endif
#if HAS_U_AXIS #if K_SPI_SENSORLESS
case U_AXIS: if (ENABLED(U_SPI_SENSORLESS)) endstops.tmc_spi_homing.u = false; break; case K_AXIS: endstops.tmc_spi_homing.k = false; break;
#endif #endif
#if HAS_V_AXIS #if U_SPI_SENSORLESS
case V_AXIS: if (ENABLED(V_SPI_SENSORLESS)) endstops.tmc_spi_homing.v = false; break; case U_AXIS: endstops.tmc_spi_homing.u = false; break;
#endif #endif
#if HAS_W_AXIS #if V_SPI_SENSORLESS
case W_AXIS: if (ENABLED(W_SPI_SENSORLESS)) endstops.tmc_spi_homing.w = false; break; case V_AXIS: endstops.tmc_spi_homing.v = false; break;
#endif
#if W_SPI_SENSORLESS
case W_AXIS: endstops.tmc_spi_homing.w = false; break;
#endif #endif
default: break; default: break;
} }
#endif
} }
#endif // SENSORLESS_HOMING #endif // SENSORLESS_HOMING
@ -1712,7 +1712,7 @@ void prepare_line_to_destination() {
const feedRate_t home_fr_mm_s = fr_mm_s ?: homing_feedrate(axis); const feedRate_t home_fr_mm_s = fr_mm_s ?: homing_feedrate(axis);
if (DEBUGGING(LEVELING)) { if (DEBUGGING(LEVELING)) {
DEBUG_ECHOPGM("...(", AS_CHAR(AXIS_CHAR(axis)), ", ", distance, ", "); DEBUG_ECHOPGM("...(", C(AXIS_CHAR(axis)), ", ", distance, ", ");
if (fr_mm_s) if (fr_mm_s)
DEBUG_ECHO(fr_mm_s); DEBUG_ECHO(fr_mm_s);
else else
@ -1802,12 +1802,12 @@ void prepare_line_to_destination() {
* "trusted" position). * "trusted" position).
*/ */
void set_axis_never_homed(const AxisEnum axis) { void set_axis_never_homed(const AxisEnum axis) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM(">>> set_axis_never_homed(", AS_CHAR(AXIS_CHAR(axis)), ")"); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM(">>> set_axis_never_homed(", C(AXIS_CHAR(axis)), ")");
set_axis_untrusted(axis); set_axis_untrusted(axis);
set_axis_unhomed(axis); set_axis_unhomed(axis);
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< set_axis_never_homed(", AS_CHAR(AXIS_CHAR(axis)), ")"); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< set_axis_never_homed(", C(AXIS_CHAR(axis)), ")");
TERN_(I2C_POSITION_ENCODERS, I2CPEM.unhomed(axis)); TERN_(I2C_POSITION_ENCODERS, I2CPEM.unhomed(axis));
} }
@ -1916,7 +1916,7 @@ void prepare_line_to_destination() {
if (ABS(phaseDelta) * planner.mm_per_step[axis] / phasePerUStep < 0.05f) if (ABS(phaseDelta) * planner.mm_per_step[axis] / phasePerUStep < 0.05f)
SERIAL_ECHOLNPGM("Selected home phase ", home_phase[axis], SERIAL_ECHOLNPGM("Selected home phase ", home_phase[axis],
" too close to endstop trigger phase ", phaseCurrent, " too close to endstop trigger phase ", phaseCurrent,
". Pick a different phase for ", AS_CHAR(AXIS_CHAR(axis))); ". Pick a different phase for ", C(AXIS_CHAR(axis)));
// Skip to next if target position is behind current. So it only moves away from endstop. // Skip to next if target position is behind current. So it only moves away from endstop.
if (phaseDelta < 0) phaseDelta += 1024; if (phaseDelta < 0) phaseDelta += 1024;
@ -1927,7 +1927,7 @@ void prepare_line_to_destination() {
// Optional debug messages // Optional debug messages
if (DEBUGGING(LEVELING)) { if (DEBUGGING(LEVELING)) {
DEBUG_ECHOLNPGM( DEBUG_ECHOLNPGM(
"Endstop ", AS_CHAR(AXIS_CHAR(axis)), " hit at Phase:", phaseCurrent, "Endstop ", C(AXIS_CHAR(axis)), " hit at Phase:", phaseCurrent,
" Delta:", phaseDelta, " Distance:", mmDelta " Delta:", phaseDelta, " Distance:", mmDelta
); );
} }
@ -1966,7 +1966,7 @@ void prepare_line_to_destination() {
if (true MAIN_AXIS_MAP(_ANDCANT)) return; if (true MAIN_AXIS_MAP(_ANDCANT)) return;
#endif #endif
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM(">>> homeaxis(", AS_CHAR(AXIS_CHAR(axis)), ")"); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM(">>> homeaxis(", C(AXIS_CHAR(axis)), ")");
const int axis_home_dir = TERN0(DUAL_X_CARRIAGE, axis == X_AXIS) const int axis_home_dir = TERN0(DUAL_X_CARRIAGE, axis == X_AXIS)
? TOOL_X_HOME_DIR(active_extruder) : home_dir(axis); ? TOOL_X_HOME_DIR(active_extruder) : home_dir(axis);
@ -2035,12 +2035,12 @@ void prepare_line_to_destination() {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Home Fast: ", move_length, "mm"); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Home Fast: ", move_length, "mm");
do_homing_move(axis, move_length, 0.0, !use_probe_bump); do_homing_move(axis, move_length, 0.0, !use_probe_bump);
// If a second homing move is configured...
if (bump) {
#if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH)
if (axis == Z_AXIS && !bltouch.high_speed_mode) bltouch.stow(); // Intermediate STOW (in LOW SPEED MODE) if (axis == Z_AXIS && !bltouch.high_speed_mode) bltouch.stow(); // Intermediate STOW (in LOW SPEED MODE)
#endif #endif
// If a second homing move is configured...
if (bump) {
// Move away from the endstop by the axis HOMING_BUMP_MM // Move away from the endstop by the axis HOMING_BUMP_MM
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Move Away: ", -bump, "mm"); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Move Away: ", -bump, "mm");
do_homing_move(axis, -bump, TERN(HOMING_Z_WITH_PROBE, (axis == Z_AXIS ? z_probe_fast_mm_s : 0), 0), false); do_homing_move(axis, -bump, TERN(HOMING_Z_WITH_PROBE, (axis == Z_AXIS ? z_probe_fast_mm_s : 0), 0), false);
@ -2049,35 +2049,12 @@ void prepare_line_to_destination() {
// Check for a broken endstop // Check for a broken endstop
EndstopEnum es; EndstopEnum es;
switch (axis) { switch (axis) {
default: #define _ESCASE(A) case A##_AXIS: es = A##_ENDSTOP; break;
case X_AXIS: es = X_ENDSTOP; break; MAIN_AXIS_MAP(_ESCASE)
#if HAS_Y_AXIS default: break;
case Y_AXIS: es = Y_ENDSTOP; break;
#endif
#if HAS_Z_AXIS
case Z_AXIS: es = Z_ENDSTOP; break;
#endif
#if HAS_I_AXIS
case I_AXIS: es = I_ENDSTOP; break;
#endif
#if HAS_J_AXIS
case J_AXIS: es = J_ENDSTOP; break;
#endif
#if HAS_K_AXIS
case K_AXIS: es = K_ENDSTOP; break;
#endif
#if HAS_U_AXIS
case U_AXIS: es = U_ENDSTOP; break;
#endif
#if HAS_V_AXIS
case V_AXIS: es = V_ENDSTOP; break;
#endif
#if HAS_W_AXIS
case W_AXIS: es = W_ENDSTOP; break;
#endif
} }
if (TEST(endstops.state(), es)) { if (TEST(endstops.state(), es)) {
SERIAL_ECHO_MSG("Bad ", AS_CHAR(AXIS_CHAR(axis)), " Endstop?"); SERIAL_ECHO_MSG("Bad ", C(AXIS_CHAR(axis)), " Endstop?");
kill(GET_TEXT_F(MSG_KILL_HOMING_FAILED)); kill(GET_TEXT_F(MSG_KILL_HOMING_FAILED));
} }
#endif #endif
@ -2091,11 +2068,11 @@ void prepare_line_to_destination() {
const float rebump = bump * 2; const float rebump = bump * 2;
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Re-bump: ", rebump, "mm"); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Re-bump: ", rebump, "mm");
do_homing_move(axis, rebump, get_homing_bump_feedrate(axis), true); do_homing_move(axis, rebump, get_homing_bump_feedrate(axis), true);
}
#if ALL(HOMING_Z_WITH_PROBE, BLTOUCH) #if ALL(HOMING_Z_WITH_PROBE, BLTOUCH)
if (axis == Z_AXIS) bltouch.stow(); // The final STOW if (axis == Z_AXIS) bltouch.stow(); // The final STOW
#endif #endif
}
#if HAS_EXTRA_ENDSTOPS #if HAS_EXTRA_ENDSTOPS
const bool pos_dir = axis_home_dir > 0; const bool pos_dir = axis_home_dir > 0;
@ -2293,7 +2270,7 @@ void prepare_line_to_destination() {
if (axis == Z_AXIS) fwretract.current_hop = 0.0; if (axis == Z_AXIS) fwretract.current_hop = 0.0;
#endif #endif
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< homeaxis(", AS_CHAR(AXIS_CHAR(axis)), ")"); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< homeaxis(", C(AXIS_CHAR(axis)), ")");
} // homeaxis() } // homeaxis()
@ -2318,7 +2295,7 @@ void prepare_line_to_destination() {
* Callers must sync the planner position after calling this! * Callers must sync the planner position after calling this!
*/ */
void set_axis_is_at_home(const AxisEnum axis) { void set_axis_is_at_home(const AxisEnum axis) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM(">>> set_axis_is_at_home(", AS_CHAR(AXIS_CHAR(axis)), ")"); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM(">>> set_axis_is_at_home(", C(AXIS_CHAR(axis)), ")");
set_axis_trusted(axis); set_axis_trusted(axis);
set_axis_homed(axis); set_axis_homed(axis);
@ -2363,17 +2340,17 @@ void set_axis_is_at_home(const AxisEnum axis) {
if (DEBUGGING(LEVELING)) { if (DEBUGGING(LEVELING)) {
#if HAS_HOME_OFFSET #if HAS_HOME_OFFSET
DEBUG_ECHOLNPGM("> home_offset[", AS_CHAR(AXIS_CHAR(axis)), "] = ", home_offset[axis]); DEBUG_ECHOLNPGM("> home_offset[", C(AXIS_CHAR(axis)), "] = ", home_offset[axis]);
#endif #endif
DEBUG_POS("", current_position); DEBUG_POS("", current_position);
DEBUG_ECHOLNPGM("<<< set_axis_is_at_home(", AS_CHAR(AXIS_CHAR(axis)), ")"); DEBUG_ECHOLNPGM("<<< set_axis_is_at_home(", C(AXIS_CHAR(axis)), ")");
} }
} }
#if HAS_WORKSPACE_OFFSET #if HAS_WORKSPACE_OFFSET
void update_workspace_offset(const AxisEnum axis) { void update_workspace_offset(const AxisEnum axis) {
workspace_offset[axis] = home_offset[axis] + position_shift[axis]; workspace_offset[axis] = home_offset[axis] + position_shift[axis];
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Axis ", AS_CHAR(AXIS_CHAR(axis)), " home_offset = ", home_offset[axis], " position_shift = ", position_shift[axis]); if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Axis ", C(AXIS_CHAR(axis)), " home_offset = ", home_offset[axis], " position_shift = ", position_shift[axis]);
} }
#endif #endif

View File

@ -151,9 +151,9 @@ inline float home_bump_mm(const AxisEnum axis) {
extern xyz_pos_t hotend_offset[HOTENDS]; extern xyz_pos_t hotend_offset[HOTENDS];
void reset_hotend_offsets(); void reset_hotend_offsets();
#elif HOTENDS #elif HOTENDS
constexpr xyz_pos_t hotend_offset[HOTENDS] = { { 0 } }; constexpr xyz_pos_t hotend_offset[HOTENDS] = { { TERN_(HAS_X_AXIS, 0) } };
#else #else
constexpr xyz_pos_t hotend_offset[1] = { { 0 } }; constexpr xyz_pos_t hotend_offset[1] = { { TERN_(HAS_X_AXIS, 0) } };
#endif #endif
#if HAS_SOFTWARE_ENDSTOPS #if HAS_SOFTWARE_ENDSTOPS
@ -167,10 +167,12 @@ inline float home_bump_mm(const AxisEnum axis) {
amin = -100000; amax = 100000; // "No limits" amin = -100000; amax = 100000; // "No limits"
#if HAS_SOFTWARE_ENDSTOPS #if HAS_SOFTWARE_ENDSTOPS
if (enabled()) switch (axis) { if (enabled()) switch (axis) {
#if HAS_X_AXIS
case X_AXIS: case X_AXIS:
TERN_(MIN_SOFTWARE_ENDSTOP_X, amin = min.x); TERN_(MIN_SOFTWARE_ENDSTOP_X, amin = min.x);
TERN_(MAX_SOFTWARE_ENDSTOP_X, amax = max.x); TERN_(MAX_SOFTWARE_ENDSTOP_X, amax = max.x);
break; break;
#endif
#if HAS_Y_AXIS #if HAS_Y_AXIS
case Y_AXIS: case Y_AXIS:
TERN_(MIN_SOFTWARE_ENDSTOP_Y, amin = min.y); TERN_(MIN_SOFTWARE_ENDSTOP_Y, amin = min.y);
@ -344,12 +346,14 @@ inline void prepare_internal_move_to_destination(const_feedRate_t fr_mm_s=0.0f)
/** /**
* Blocking movement and shorthand functions * Blocking movement and shorthand functions
*/ */
void do_blocking_move_to(NUM_AXIS_ARGS(const_float_t), const_feedRate_t fr_mm_s=0.0f); void do_blocking_move_to(NUM_AXIS_ARGS_(const_float_t) const_feedRate_t fr_mm_s=0.0f);
void do_blocking_move_to(const xy_pos_t &raw, const_feedRate_t fr_mm_s=0.0f); void do_blocking_move_to(const 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 xyz_pos_t &raw, const_feedRate_t fr_mm_s=0.0f);
void do_blocking_move_to(const xyze_pos_t &raw, const_feedRate_t fr_mm_s=0.0f); void do_blocking_move_to(const xyze_pos_t &raw, const_feedRate_t fr_mm_s=0.0f);
void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s=0.0f); #if HAS_X_AXIS
void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s=0.0f);
#endif
#if HAS_Y_AXIS #if HAS_Y_AXIS
void do_blocking_move_to_y(const_float_t ry, const_feedRate_t fr_mm_s=0.0f); void do_blocking_move_to_y(const_float_t ry, const_feedRate_t fr_mm_s=0.0f);
#endif #endif
@ -409,12 +413,9 @@ void restore_feedrate_and_scaling();
/** /**
* Homing and Trusted Axes * Homing and Trusted Axes
*/ */
typedef IF<(NUM_AXES > 8), uint16_t, uint8_t>::type main_axes_bits_t; typedef bits_t(NUM_AXES) main_axes_bits_t;
constexpr main_axes_bits_t main_axes_mask = _BV(NUM_AXES) - 1; constexpr main_axes_bits_t main_axes_mask = _BV(NUM_AXES) - 1;
typedef IF<(NUM_AXES + EXTRUDERS > 8), uint16_t, uint8_t>::type e_axis_bits_t;
constexpr e_axis_bits_t e_axis_mask = (_BV(EXTRUDERS) - 1) << NUM_AXES;
void set_axis_is_at_home(const AxisEnum axis); void set_axis_is_at_home(const AxisEnum axis);
#if HAS_ENDSTOPS #if HAS_ENDSTOPS
@ -432,26 +433,21 @@ void set_axis_is_at_home(const AxisEnum axis);
void set_axis_never_homed(const AxisEnum axis); void set_axis_never_homed(const AxisEnum axis);
main_axes_bits_t axes_should_home(main_axes_bits_t axes_mask=main_axes_mask); main_axes_bits_t axes_should_home(main_axes_bits_t axes_mask=main_axes_mask);
bool homing_needed_error(main_axes_bits_t axes_mask=main_axes_mask); bool homing_needed_error(main_axes_bits_t axes_mask=main_axes_mask);
inline void set_axis_unhomed(const AxisEnum axis) { CBI(axes_homed, axis); }
inline void set_axis_untrusted(const AxisEnum axis) { CBI(axes_trusted, axis); }
inline void set_all_unhomed() { axes_homed = axes_trusted = 0; }
inline void set_axis_homed(const AxisEnum axis) { SBI(axes_homed, axis); }
inline void set_axis_trusted(const AxisEnum axis) { SBI(axes_trusted, axis); }
inline void set_all_homed() { axes_homed = axes_trusted = main_axes_mask; }
#else #else
constexpr main_axes_bits_t axes_homed = main_axes_mask, axes_trusted = main_axes_mask; // Zero-endstop machines are always homed and trusted constexpr main_axes_bits_t axes_homed = main_axes_mask, axes_trusted = main_axes_mask; // Zero-endstop machines are always homed and trusted
inline void homeaxis(const AxisEnum axis) {} inline void homeaxis(const AxisEnum axis) {}
inline void set_axis_never_homed(const AxisEnum) {} inline void set_axis_never_homed(const AxisEnum) {}
inline main_axes_bits_t axes_should_home(main_axes_bits_t=main_axes_mask) { return 0; } inline main_axes_bits_t axes_should_home(main_axes_bits_t=main_axes_mask) { return 0; }
inline bool homing_needed_error(main_axes_bits_t=main_axes_mask) { return false; } inline bool homing_needed_error(main_axes_bits_t=main_axes_mask) { return false; }
inline void set_axis_unhomed(const AxisEnum axis) {}
inline void set_axis_untrusted(const AxisEnum axis) {}
inline void set_all_unhomed() {}
inline void set_axis_homed(const AxisEnum axis) {}
inline void set_axis_trusted(const AxisEnum axis) {}
inline void set_all_homed() {}
#endif #endif
inline void set_axis_unhomed(const AxisEnum axis) { TERN_(HAS_ENDSTOPS, CBI(axes_homed, axis)); }
inline void set_axis_untrusted(const AxisEnum axis) { TERN_(HAS_ENDSTOPS, CBI(axes_trusted, axis)); }
inline void set_all_unhomed() { TERN_(HAS_ENDSTOPS, axes_homed = axes_trusted = 0); }
inline void set_axis_homed(const AxisEnum axis) { TERN_(HAS_ENDSTOPS, SBI(axes_homed, axis)); }
inline void set_axis_trusted(const AxisEnum axis) { TERN_(HAS_ENDSTOPS, SBI(axes_trusted, axis)); }
inline void set_all_homed() { TERN_(HAS_ENDSTOPS, axes_homed = axes_trusted = main_axes_mask); }
inline bool axis_was_homed(const AxisEnum axis) { return TEST(axes_homed, axis); } inline bool axis_was_homed(const AxisEnum axis) { return TEST(axes_homed, axis); }
inline bool axis_is_trusted(const AxisEnum axis) { return TEST(axes_trusted, axis); } inline bool axis_is_trusted(const AxisEnum axis) { return TEST(axes_trusted, axis); }
inline bool axis_should_home(const AxisEnum axis) { return (axes_should_home() & _BV(axis)) != 0; } inline bool axis_should_home(const AxisEnum axis) { return (axes_should_home() & _BV(axis)) != 0; }
@ -506,8 +502,10 @@ void home_if_needed(const bool keeplev=false);
FORCE_INLINE void toNative(xyz_pos_t&) {} FORCE_INLINE void toNative(xyz_pos_t&) {}
FORCE_INLINE void toNative(xyze_pos_t&) {} FORCE_INLINE void toNative(xyze_pos_t&) {}
#endif #endif
#define LOGICAL_X_POSITION(POS) NATIVE_TO_LOGICAL(POS, X_AXIS) #if HAS_X_AXIS
#define RAW_X_POSITION(POS) LOGICAL_TO_NATIVE(POS, X_AXIS) #define LOGICAL_X_POSITION(POS) NATIVE_TO_LOGICAL(POS, X_AXIS)
#define RAW_X_POSITION(POS) LOGICAL_TO_NATIVE(POS, X_AXIS)
#endif
#if HAS_Y_AXIS #if HAS_Y_AXIS
#define LOGICAL_Y_POSITION(POS) NATIVE_TO_LOGICAL(POS, Y_AXIS) #define LOGICAL_Y_POSITION(POS) NATIVE_TO_LOGICAL(POS, Y_AXIS)
#define RAW_Y_POSITION(POS) LOGICAL_TO_NATIVE(POS, Y_AXIS) #define RAW_Y_POSITION(POS) LOGICAL_TO_NATIVE(POS, Y_AXIS)
@ -560,9 +558,9 @@ void home_if_needed(const bool keeplev=false);
#else #else
// Return true if the given position is within the machine bounds. // Return true if the given position is within the machine bounds.
bool position_is_reachable(const_float_t rx, const_float_t ry); bool position_is_reachable(TERN_(HAS_X_AXIS, const_float_t rx) OPTARG(HAS_Y_AXIS, const_float_t ry));
inline bool position_is_reachable(const xy_pos_t &pos) { inline bool position_is_reachable(const xy_pos_t &pos) {
return position_is_reachable(pos.x, pos.y); return position_is_reachable(TERN_(HAS_X_AXIS, pos.x) OPTARG(HAS_Y_AXIS, pos.y));
} }
#endif #endif
@ -599,7 +597,7 @@ void home_if_needed(const bool keeplev=false);
float x_home_pos(const uint8_t extruder); float x_home_pos(const uint8_t extruder);
#define TOOL_X_HOME_DIR(T) ((T) ? X2_HOME_DIR : X_HOME_DIR) #define TOOL_X_HOME_DIR(T) ((T) ? 1 : -1)
void set_duplication_enabled(const bool dupe, const int8_t tool_index=-1); void set_duplication_enabled(const bool dupe, const int8_t tool_index=-1);
void idex_set_mirrored_mode(const bool mirr); void idex_set_mirrored_mode(const bool mirr);

View File

@ -112,7 +112,7 @@
// Delay for delivery of first block to the stepper ISR, if the queue contains 2 or // Delay for delivery of first block to the stepper ISR, if the queue contains 2 or
// fewer movements. The delay is measured in milliseconds, and must be less than 250ms // fewer movements. The delay is measured in milliseconds, and must be less than 250ms
#define BLOCK_DELAY_FOR_1ST_MOVE 100 #define BLOCK_DELAY_FOR_1ST_MOVE 100U
Planner planner; Planner planner;
@ -198,7 +198,9 @@ float Planner::mm_per_step[DISTINCT_AXES]; // (mm) Millimeters per step
constexpr bool Planner::leveling_active; constexpr bool Planner::leveling_active;
#endif #endif
skew_factor_t Planner::skew_factor; // Initialized by settings.load() #if ENABLED(SKEW_CORRECTION)
skew_factor_t Planner::skew_factor; // Initialized by settings.load()
#endif
#if ENABLED(AUTOTEMP) #if ENABLED(AUTOTEMP)
celsius_t Planner::autotemp_max = 250, celsius_t Planner::autotemp_max = 250,
@ -1733,7 +1735,7 @@ float Planner::triggered_position_mm(const AxisEnum axis) {
bool Planner::busy() { bool Planner::busy() {
return (has_blocks_queued() || cleaning_buffer_counter return (has_blocks_queued() || cleaning_buffer_counter
|| TERN0(EXTERNAL_CLOSED_LOOP_CONTROLLER, CLOSED_LOOP_WAITING()) || TERN0(EXTERNAL_CLOSED_LOOP_CONTROLLER, CLOSED_LOOP_WAITING())
|| TERN0(HAS_SHAPING, stepper.input_shaping_busy()) || TERN0(HAS_ZV_SHAPING, stepper.input_shaping_busy())
); );
} }
@ -2230,11 +2232,17 @@ bool Planner::_populate_block(
TERN_(HAS_EXTRUDERS, block->steps.e = esteps); TERN_(HAS_EXTRUDERS, block->steps.e = esteps);
block->step_event_count = _MAX(LOGICAL_AXIS_LIST(esteps, block->step_event_count = (
#if NUM_AXES
_MAX(LOGICAL_AXIS_LIST(esteps,
block->steps.a, block->steps.b, block->steps.c, block->steps.a, block->steps.b, block->steps.c,
block->steps.i, block->steps.j, block->steps.k, block->steps.i, block->steps.j, block->steps.k,
block->steps.u, block->steps.v, block->steps.w block->steps.u, block->steps.v, block->steps.w
)); ))
#elif HAS_EXTRUDERS
esteps
#endif
);
// Bail if this is a zero-length block // Bail if this is a zero-length block
if (block->step_event_count < MIN_STEPS_PER_SEGMENT) return false; if (block->step_event_count < MIN_STEPS_PER_SEGMENT) return false;
@ -2348,12 +2356,13 @@ bool Planner::_populate_block(
// Calculate inverse time for this move. No divide by zero due to previous checks. // Calculate inverse time for this move. No divide by zero due to previous checks.
// Example: At 120mm/s a 60mm move involving XYZ axes takes 0.5s. So this will give 2.0. // Example: At 120mm/s a 60mm move involving XYZ axes takes 0.5s. So this will give 2.0.
// Example 2: At 120°/s a 60° move involving only rotational axes takes 0.5s. So this will give 2.0. // Example 2: At 120°/s a 60° move involving only rotational axes takes 0.5s. So this will give 2.0.
float inverse_secs; float inverse_secs = inverse_millimeters * (
#if ALL(HAS_ROTATIONAL_AXES, INCH_MODE_SUPPORT) #if ALL(HAS_ROTATIONAL_AXES, INCH_MODE_SUPPORT)
inverse_secs = inverse_millimeters * (cartesian_move ? fr_mm_s : LINEAR_UNIT(fr_mm_s)); cartesian_move ? fr_mm_s : LINEAR_UNIT(fr_mm_s)
#else #else
inverse_secs = fr_mm_s * inverse_millimeters; fr_mm_s
#endif #endif
);
// Get the number of non busy movements in queue (non busy means that they can be altered) // Get the number of non busy movements in queue (non busy means that they can be altered)
const uint8_t moves_queued = nonbusy_movesplanned(); const uint8_t moves_queued = nonbusy_movesplanned();
@ -2496,8 +2505,8 @@ bool Planner::_populate_block(
#if ENABLED(LIN_ADVANCE) #if ENABLED(LIN_ADVANCE)
bool use_advance_lead = false; bool use_advance_lead = false;
#endif #endif
if (NUM_AXIS_GANG( if (true NUM_AXIS_GANG(
!block->steps.a, && !block->steps.b, && !block->steps.c, && !block->steps.a, && !block->steps.b, && !block->steps.c,
&& !block->steps.i, && !block->steps.j, && !block->steps.k, && !block->steps.i, && !block->steps.j, && !block->steps.k,
&& !block->steps.u, && !block->steps.v, && !block->steps.w) && !block->steps.u, && !block->steps.v, && !block->steps.w)
) { // Is this a retract / recover move? ) { // Is this a retract / recover move?
@ -2551,9 +2560,10 @@ bool Planner::_populate_block(
else { else {
// Scale E acceleration so that it will be possible to jump to the advance speed. // Scale E acceleration so that it will be possible to jump to the advance speed.
const uint32_t max_accel_steps_per_s2 = MAX_E_JERK(extruder) / (extruder_advance_K[E_INDEX_N(extruder)] * e_D_ratio) * steps_per_mm; const uint32_t max_accel_steps_per_s2 = MAX_E_JERK(extruder) / (extruder_advance_K[E_INDEX_N(extruder)] * e_D_ratio) * steps_per_mm;
if (TERN0(LA_DEBUG, accel > max_accel_steps_per_s2)) if (accel > max_accel_steps_per_s2) {
SERIAL_ECHOLNPGM("Acceleration limited."); accel = max_accel_steps_per_s2;
NOMORE(accel, max_accel_steps_per_s2); if (ENABLED(LA_DEBUG)) SERIAL_ECHOLNPGM("Acceleration limited.");
}
} }
} }
#endif #endif

View File

@ -286,7 +286,19 @@ typedef struct PlannerBlock {
#define HAS_POSITION_FLOAT 1 #define HAS_POSITION_FLOAT 1
#endif #endif
#define BLOCK_MOD(n) ((n)&(BLOCK_BUFFER_SIZE-1)) constexpr uint8_t block_dec_mod(const uint8_t v1, const uint8_t v2) {
return v1 >= v2 ? v1 - v2 : v1 - v2 + BLOCK_BUFFER_SIZE;
}
constexpr uint8_t block_inc_mod(const uint8_t v1, const uint8_t v2) {
return v1 + v2 < BLOCK_BUFFER_SIZE ? v1 + v2 : v1 + v2 - BLOCK_BUFFER_SIZE;
}
#if IS_POWER_OF_2(BLOCK_BUFFER_SIZE)
#define BLOCK_MOD(n) ((n)&((BLOCK_BUFFER_SIZE)-1))
#else
#define BLOCK_MOD(n) ((n)%(BLOCK_BUFFER_SIZE))
#endif
#if ENABLED(LASER_FEATURE) #if ENABLED(LASER_FEATURE)
typedef struct { typedef struct {
@ -346,7 +358,7 @@ typedef struct {
} skew_factor_t; } skew_factor_t;
#if ENABLED(DISABLE_OTHER_EXTRUDERS) #if ENABLED(DISABLE_OTHER_EXTRUDERS)
typedef IF<(BLOCK_BUFFER_SIZE > 64), uint16_t, uint8_t>::type last_move_t; typedef uvalue_t((BLOCK_BUFFER_SIZE) * 2) last_move_t;
#endif #endif
#if ENABLED(ARC_SUPPORT) #if ENABLED(ARC_SUPPORT)
@ -474,7 +486,9 @@ class Planner {
static xyze_pos_t position_cart; static xyze_pos_t position_cart;
#endif #endif
#if ENABLED(SKEW_CORRECTION)
static skew_factor_t skew_factor; static skew_factor_t skew_factor;
#endif
#if ENABLED(SD_ABORT_ON_ENDSTOP_HIT) #if ENABLED(SD_ABORT_ON_ENDSTOP_HIT)
static bool abort_on_endstop_hit; static bool abort_on_endstop_hit;
@ -736,10 +750,10 @@ class Planner {
#endif // HAS_POSITION_MODIFIERS #endif // HAS_POSITION_MODIFIERS
// Number of moves currently in the planner including the busy block, if any // Number of moves currently in the planner including the busy block, if any
FORCE_INLINE static uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_tail); } FORCE_INLINE static uint8_t movesplanned() { return block_dec_mod(block_buffer_head, block_buffer_tail); }
// Number of nonbusy moves currently in the planner // Number of nonbusy moves currently in the planner
FORCE_INLINE static uint8_t nonbusy_movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_nonbusy); } FORCE_INLINE static uint8_t nonbusy_movesplanned() { return block_dec_mod(block_buffer_head, block_buffer_nonbusy); }
// Remove all blocks from the buffer // Remove all blocks from the buffer
FORCE_INLINE static void clear_block_buffer() { block_buffer_nonbusy = block_buffer_planned = block_buffer_head = block_buffer_tail = 0; } FORCE_INLINE static void clear_block_buffer() { block_buffer_nonbusy = block_buffer_planned = block_buffer_head = block_buffer_tail = 0; }
@ -748,7 +762,7 @@ class Planner {
FORCE_INLINE static bool is_full() { return block_buffer_tail == next_block_index(block_buffer_head); } FORCE_INLINE static bool is_full() { return block_buffer_tail == next_block_index(block_buffer_head); }
// Get count of movement slots free // Get count of movement slots free
FORCE_INLINE static uint8_t moves_free() { return BLOCK_BUFFER_SIZE - 1 - movesplanned(); } FORCE_INLINE static uint8_t moves_free() { return (BLOCK_BUFFER_SIZE) - 1 - movesplanned(); }
/** /**
* Planner::get_next_free_block * Planner::get_next_free_block
@ -999,8 +1013,8 @@ class Planner {
/** /**
* Get the index of the next / previous block in the ring buffer * Get the index of the next / previous block in the ring buffer
*/ */
static constexpr uint8_t next_block_index(const uint8_t block_index) { return BLOCK_MOD(block_index + 1); } static constexpr uint8_t next_block_index(const uint8_t block_index) { return block_inc_mod(block_index, 1); }
static constexpr uint8_t prev_block_index(const uint8_t block_index) { return BLOCK_MOD(block_index - 1); } static constexpr uint8_t prev_block_index(const uint8_t block_index) { return block_dec_mod(block_index, 1); }
/** /**
* Calculate the maximum allowable speed squared at this point, in order * Calculate the maximum allowable speed squared at this point, in order

Some files were not shown because too many files have changed in this diff Show More