🧑‍💻 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
#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) \
|| AXIS_DRIVER_TYPE(A,TMC2208) || AXIS_DRIVER_TYPE(A,TMC2209) \
|| AXIS_DRIVER_TYPE(A,TMC2660) \
@ -184,10 +188,3 @@
#if ANY_AXIS_HAS(SPI)
#define HAS_TMC_SPI 1
#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
//
#if HAS_X_AXIS
#define STR_X_MIN "x_min"
#define STR_X_MAX "x_max"
#define STR_X2_MIN "x2_min"
#define STR_X2_MAX "x2_max"
#endif
#if HAS_Y_AXIS
#define STR_Y_MIN "y_min"

View File

@ -263,8 +263,12 @@
// 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 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 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_DISABLED(O,A) TERN(O,,A)
@ -434,6 +438,8 @@
extern "C++" {
// 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) {
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) { 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) { return x |= y; } \
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) { x = x | y; return x; } \
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
namespace Private {
@ -467,6 +473,39 @@
template <typename T, typename ... Args> struct first_type_of { 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.
@ -726,6 +765,19 @@
#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)
// 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
#define _MAP(_MAP_OP,A,V...) \
_MAP_OP(A) \

View File

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

View File

@ -27,7 +27,8 @@
#include "../feature/ethernet.h"
#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
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
#endif
#define SERIAL_OUT(WHAT, V...) (void)SERIAL_IMPL.WHAT(V)
#define PORT_REDIRECT(p) _PORT_REDIRECT(1,p)
#define PORT_RESTORE() _PORT_RESTORE(1)
#define SERIAL_PORTMASK(P) SerialMask::from(P)
@ -149,10 +147,8 @@ template <typename T>
void SERIAL_ECHO(T x) { SERIAL_IMPL.print(x); }
// 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); }
#define AS_CHAR(C) serial_char_t(C)
#define AS_DIGIT(C) AS_CHAR('0' + (C))
#define AS_DIGIT(n) C('0' + (n))
template <typename T>
void SERIAL_ECHOLN(T x) { SERIAL_IMPL.println(x); }

View File

@ -23,6 +23,8 @@
#include "../inc/MarlinConfigPre.h"
#include <stddef.h> // for size_t
#if ENABLED(EMERGENCY_PARSER)
#include "../feature/e_parser.h"
#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) {}
#endif
#if (GRID_MAX_POINTS_X) && (GRID_MAX_POINTS_Y)
#if GRID_MAX_POINTS
// 16x16 bit arrays
template <int W, int H>
struct FlagBits {
typename IF<(W>8), uint16_t, uint8_t>::type bits[H];
void fill() { memset(bits, 0xFF, sizeof(bits)); }
void reset() { memset(bits, 0x00, sizeof(bits)); }
void unmark(const uint8_t x, const uint8_t y) { CBI(bits[y], x); }
void mark(const uint8_t x, const uint8_t y) { SBI(bits[y], x); }
bool marked(const uint8_t x, const uint8_t y) { return TEST(bits[y], x); }
bits_t(W) flags[H];
void fill() { memset(flags, 0xFF, sizeof(flags)); }
void reset() { memset(flags, 0x00, sizeof(flags)); }
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(flags[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 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); }

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;
#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;
if (x > (GRID_MAX_POINTS_X) + 1 || y > (GRID_MAX_POINTS_Y) + 1) {
// 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,
// 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.
return 0.0;
}
@ -197,8 +197,8 @@ void LevelingBilinear::print_leveling_grid(const bed_mesh_t* _z_values/*=nullptr
);
else
return LINEAR_EXTRAPOLATION(
bed_level_virt_coord(ep + 1, y),
bed_level_virt_coord(ip + 1, y)
virt_coord(ep + 1, y),
virt_coord(ip + 1, y)
);
}
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
return LINEAR_EXTRAPOLATION(
bed_level_virt_coord(x, ep + 1),
bed_level_virt_coord(x, ip + 1)
virt_coord(x, ep + 1),
virt_coord(x, ip + 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 (
p[i-1] * -t * sq(1 - 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;
}
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];
for (uint8_t i = 0; i < 4; ++i) {
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_factor_virt = grid_spacing_virt.reciprocal();
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))
continue;
z_values_virt[x * (BILINEAR_SUBDIVISIONS) + tx][y * (BILINEAR_SUBDIVISIONS) + ty] =
bed_level_virt_2cmr(
virt_2cmr(
x + 1,
y + 1,
(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
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_g.x = cached_g.y = -99;
}

View File

@ -43,10 +43,10 @@ private:
static xy_pos_t grid_spacing_virt;
static xy_float_t grid_factor_virt;
static float bed_level_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 bed_level_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 float virt_coord(const uint8_t x, const uint8_t y);
static float virt_cmr(const float p[4], const uint8_t i, const float t);
static float virt_2cmr(const uint8_t x, const uint8_t y, const_float_t tx, const_float_t ty);
static void subdivide_mesh();
#endif
public:

View File

@ -110,7 +110,7 @@ void BDS_Leveling::process() {
}
else {
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
old_cur_z = cur_z;
@ -119,7 +119,7 @@ void BDS_Leveling::process() {
//endstops.update();
}
else
stepper.set_directions();
stepper.apply_directions();
#if ENABLED(DEBUG_OUT_BD)
SERIAL_ECHOLNPGM("BD:", tmp & 0x3FF, ", Z:", cur_z, "|", current_position.z);
@ -150,7 +150,7 @@ void BDS_Leveling::process() {
if (config_state == -6) {
//BD_I2C_SENSOR.BD_i2c_write(1019); // begin calibrate
//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("G1 Z0.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_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 order(uint8_t n) { return uint8_t(log2(n - 1)) + 1; }
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(uint8_t(n - 1))) + 1; }
constexpr uint8_t ord = order(_MAX(GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y));
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_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);
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);
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) };
}
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) {
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_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],
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 ]),

View File

@ -48,8 +48,8 @@ struct mesh_index_pair;
typedef struct {
bool C_seen;
int8_t KLS_storage_slot;
uint8_t R_repetition,
V_verbosity,
grid_count_t R_repetition;
uint8_t V_verbosity,
P_phase,
T_map_type;
float B_shim_thickness,
@ -77,7 +77,6 @@ private:
static bool G29_parse_parameters() __O0;
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 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 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) {
@ -141,26 +140,26 @@ public:
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);
}
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);
}
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);
}
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);
}
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) };
}
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) {
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.
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;
if (!invalidate_all) {
while (count--) {
@ -762,14 +762,14 @@ void unified_bed_leveling::shift_mesh_height() {
TERN_(DWIN_LCD_PROUI, DWIN_LevelingStart());
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;
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(best.pos, ExtUI::G29_START));
do {
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, ".");
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;
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);
if (param.R_repetition < 1) {
SERIAL_ECHOLNPGM("?(R)epetition count invalid (1+).\n");
@ -1613,7 +1613,7 @@ void unified_bed_leveling::smart_fill_mesh() {
probe.move_z_after_probing();
if (abort_flag || finish_incremental_LSF(&lsf_results)) {
SERIAL_ECHOPGM("Could not complete LSF!");
SERIAL_ECHOLNPGM("Could not complete LSF!");
return;
}
@ -1758,7 +1758,7 @@ void unified_bed_leveling::smart_fill_mesh() {
}
}
SERIAL_ECHOLNPGM("done");
SERIAL_ECHOLNPGM(" done.");
}
#endif // UBL_G29_P31
@ -1771,10 +1771,9 @@ void unified_bed_leveling::smart_fill_mesh() {
report_state();
if (storage_slot == -1)
SERIAL_ECHOPGM("No Mesh Loaded.");
SERIAL_ECHOLNPGM("No Mesh Loaded.");
else
SERIAL_ECHOPGM("Mesh ", storage_slot, " Loaded.");
SERIAL_EOL();
SERIAL_ECHOLNPGM("Mesh ", storage_slot, " Loaded.");
serial_delay(50);
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
@ -1819,15 +1818,14 @@ void unified_bed_leveling::smart_fill_mesh() {
SERIAL_EOL();
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_delay(50);
SERIAL_ECHOLNPGM("Meshes go from ", hex_address((void*)settings.meshes_start_index()), " to ", hex_address((void*)settings.meshes_end_index()));
serial_delay(50);
SERIAL_ECHOLNPGM("sizeof(ubl) : ", sizeof(ubl)); SERIAL_EOL();
SERIAL_ECHOLNPGM("z_value[][] size: ", sizeof(z_values)); SERIAL_EOL();
SERIAL_ECHOLNPGM("sizeof(unified_bed_leveling) : ", sizeof(unified_bed_leveling));
SERIAL_ECHOLNPGM("z_value[][] size: ", sizeof(z_values));
serial_delay(25);
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_delay(25);
#endif // UBL_DEVEL_DEBUGGING
if (!sanity_check()) {
echo_name();
@ -1857,7 +1854,8 @@ void unified_bed_leveling::smart_fill_mesh() {
print_hex_word(i);
SERIAL_ECHOPGM(": ");
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);
SERIAL_CHAR(' ');
}

View File

@ -61,7 +61,7 @@
const xyze_pos_t &start = current_position, &end = destination;
#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
if (istart == iend) {
@ -108,7 +108,7 @@
const xy_float_t dist = end - start;
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_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);
#endif
xy_int8_t icell = istart;
xy_uint8_t icell = istart;
const float ratio = dist.y / dist.x, // Allow divide by zero
c = start.y - ratio * start.x;
@ -252,7 +252,7 @@
* 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;
@ -334,16 +334,14 @@
#else // UBL_SEGMENTED
#if IS_SCARA
#define DELTA_SEGMENT_MIN_LENGTH 0.25 // SCARA minimum segment size is 0.25mm
#elif ENABLED(DELTA)
#define DELTA_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)
#define SEGMENT_MIN_LENGTH 0.25 // SCARA minimum segment size is 0.25mm
#elif IS_KINEMATIC
#define SEGMENT_MIN_LENGTH 0.10 // (mm) Still subject to DEFAULT_SEGMENTS_PER_SECOND
#else // CARTESIAN
#ifdef LEVELED_SEGMENT_LENGTH
#define DELTA_SEGMENT_MIN_LENGTH LEVELED_SEGMENT_LENGTH
#define SEGMENT_MIN_LENGTH LEVELED_SEGMENT_LENGTH
#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
@ -366,10 +364,10 @@
#if IS_KINEMATIC
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
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)
#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
NOLESS(segments, 1U); // Must have at least one segment

View File

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

View File

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

View File

@ -60,6 +60,9 @@ class ControllerFan {
#else
static const controllerFan_settings_t &settings;
#endif
#if ENABLED(FAN_SOFT_PWM)
static uint8_t soft_pwm_speed;
#endif
static bool state() { return speed > 0; }
static void init() { reset(); }
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);
};
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>
struct config_t {
static constexpr char CONTROL_CHAR = '!';
@ -98,8 +95,8 @@ namespace DirectStepping {
static constexpr int TOTAL_STEPS = SEGMENT_STEPS * SEGMENTS;
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 typename TypeSelector<(PAGE_COUNT>256), uint16_t, uint8_t>::type page_idx_t;
typedef uvalue_t(PAGE_SIZE - 1) write_byte_idx_t;
typedef uvalue_t(PAGE_COUNT - 1) page_idx_t;
};
template <uint8_t num_pages>

View File

@ -48,7 +48,7 @@ void I2CPositionEncoder::init(const uint8_t address, const AxisEnum axis) {
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();
}
@ -66,7 +66,7 @@ void I2CPositionEncoder::update() {
/*
if (trusted) { //commented out as part of the note below
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;
@ -91,7 +91,7 @@ void I2CPositionEncoder::update() {
if (millis() - lastErrorTime > I2CPE_TIME_TRUSTED) {
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
//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) {
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) {
CHECK_IDX();
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) {
CHECK_IDX();
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");
}
static void set_ec_threshold(const int8_t idx, const float newThreshold, const AxisEnum axis) {
CHECK_IDX();
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) {
CHECK_IDX();
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) {

View File

@ -67,7 +67,7 @@ public:
}
// 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); }
// A scaled reading is ready

View File

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

View File

@ -95,7 +95,62 @@ void LEDLights::setup() {
delay(500);
}
#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
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_(PCA9533, PCA9533_init());
TERN_(LED_USER_PRESET_STARTUP, set_default());

View File

@ -66,7 +66,7 @@
// 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

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*/) {
#if ENABLED(MAX7219_ERRORS)
SERIAL_ECHOPGM("??? Max7219::");
SERIAL_ECHOF(func, AS_CHAR('('));
SERIAL_ECHOF(func, C('('));
SERIAL_ECHO(v1);
if (v2 > 0) SERIAL_ECHOPGM(", ", v2);
SERIAL_CHAR(')');
@ -471,7 +471,7 @@ void Max7219::register_setup() {
constexpr millis_t pattern_delay = 4;
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() {
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
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) {
quantity16(MAX7219_DEBUG_PLANNER_QUEUE, last_depth, current_depth, &row_change_mask);
last_depth = current_depth;

View File

@ -140,7 +140,7 @@ void MeatPack::handle_output_char(const uint8_t c) {
#if ENABLED(MP_DEBUG)
if (chars_decoded < 1024) {
++chars_decoded;
DEBUG_ECHOLNPGM("RB: ", AS_CHAR(c));
DEBUG_ECHOLNPGM("RB: ", C(c));
}
#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)
#define FILAMENT_PRESENT() (READ(FIL_RUNOUT1_PIN) != FIL_RUNOUT1_STATE)
#else
#define FILAMENT_PRESENT() true
#endif
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) {
SERIAL_ECHOLNPGM("MMU starts responding\n");
SERIAL_ECHOLNPGM("\nMMU starts responding");
if (turn_off_nozzle && resume_hotend_temp) {
thermalManager.setTargetHotend(resume_hotend_temp, active_extruder);

View File

@ -46,11 +46,11 @@ struct pm_lpf_t {
class PowerMonitor {
private:
#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;
#endif
#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;
#endif

View File

@ -67,16 +67,15 @@ uint32_t PrintJobRecovery::cmd_sdpos, // = 0
PrintJobRecovery recovery;
#ifndef POWER_LOSS_PURGE_LEN
#define POWER_LOSS_PURGE_LEN 0
#endif
#if DISABLED(BACKUP_POWER_SUPPLY)
#undef POWER_LOSS_RETRACT_LEN // No retract at outage without backup power
#endif
#ifndef POWER_LOSS_RETRACT_LEN
#define POWER_LOSS_RETRACT_LEN 0
#endif
#ifndef POWER_LOSS_PURGE_LEN
#define POWER_LOSS_PURGE_LEN 0
#endif
// Allow power-loss recovery to be aborted
#define PLR_CAN_ABORT
@ -109,6 +108,7 @@ void PrintJobRecovery::changed() {
purge();
else if (IS_SD_PRINTING())
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
#if HAS_EXTRUDERS
#if HAS_HOTEND
HOTEND_LOOP() info.target_temperature[e] = thermalManager.degTargetHotend(e);
#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.
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
thermalManager.disable_all_heaters();
@ -708,7 +711,9 @@ void PrintJobRecovery::resume() {
DEBUG_ECHOLNPGM("flag.dryrun: ", AS_DIGIT(info.flag.dryrun));
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));
#endif
}
else
DEBUG_ECHOLNPGM("INVALID DATA");

View File

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

View File

@ -48,6 +48,9 @@ public:
static void add_marker(const uint32_t sdpos, const uint16_t count);
static void loop();
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;

View File

@ -144,7 +144,7 @@ class TFilamentMonitor : public FilamentMonitorBase {
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
if (runout_flags) {
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);
if (ran_out) SERIAL_ECHOPGM(" RUN OUT");
SERIAL_EOL();

View File

@ -27,7 +27,7 @@
#include "solenoid.h"
#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
static void set_solenoid(const uint8_t num, const uint8_t state) {

View File

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

View File

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

View File

@ -29,31 +29,11 @@
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
#include "../core/debug_out.h"
PGMSTR(point_name_1, TRAMMING_POINT_NAME_1);
PGMSTR(point_name_2, TRAMMING_POINT_NAME_2);
PGMSTR(point_name_3, TRAMMING_POINT_NAME_3);
#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
#define _TRAM_NAME_DEF(N) PGMSTR(point_name_##N, TRAMMING_POINT_NAME_##N);
#define _TRAM_NAME_ITEM(N) point_name_##N
REPEAT_1(_NR_TRAM_NAMES, _TRAM_NAME_DEF)
PGM_P const tramming_point_name[] PROGMEM = {
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
};
PGM_P const tramming_point_name[] PROGMEM = { REPLIST_1(_NR_TRAM_NAMES, _TRAM_NAME_ITEM) };
#ifdef ASSISTED_TRAMMING_WAIT_POSITION

View File

@ -31,43 +31,34 @@
constexpr xy_pos_t tramming_points[] = TRAMMING_POINT_XY;
#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]), \
"TRAMMING_POINT_XY point " STRINGIFY(N) " is not reachable with the default NOZZLE_TO_PROBE offset and PROBING_MARGIN.")
VALIDATE_TRAMMING_POINT(0); VALIDATE_TRAMMING_POINT(1); VALIDATE_TRAMMING_POINT(2); VALIDATE_TRAMMING_POINT(3); VALIDATE_TRAMMING_POINT(4); VALIDATE_TRAMMING_POINT(5);
extern const char 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
;
#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
#ifdef TRAMMING_POINT_NAME_9
#define _NR_TRAM_NAMES 9
#elif defined(TRAMMING_POINT_NAME_8)
#define _NR_TRAM_NAMES 8
#elif defined(TRAMMING_POINT_NAME_7)
#define _NR_TRAM_NAMES 7
#elif defined(TRAMMING_POINT_NAME_6)
#define _NR_TRAM_NAMES 6
#elif defined(TRAMMING_POINT_NAME_5)
#define _NR_TRAM_NAMES 5
#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
#endif
#endif
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[];

View File

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

View File

@ -106,11 +106,11 @@ public:
#endif
#if ENABLED(AUTO_BED_LEVELING_LINEAR)
int abl_points;
grid_count_t abl_points;
#elif ENABLED(AUTO_BED_LEVELING_3POINT)
static constexpr int abl_points = 3;
static constexpr grid_count_t abl_points = 3;
#elif ABL_USES_GRID
static constexpr int abl_points = GRID_MAX_POINTS;
static constexpr grid_count_t abl_points = GRID_MAX_POINTS;
#endif
#if ABL_USES_GRID
@ -136,7 +136,7 @@ public:
#if ENABLED(AUTO_BED_LEVELING_LINEAR)
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
mean;
#endif
@ -145,7 +145,7 @@ public:
#if ABL_USES_GRID && ANY(AUTO_BED_LEVELING_3POINT, AUTO_BED_LEVELING_BILINEAR)
constexpr xy_uint8_t G29_State::grid_points;
constexpr int G29_State::abl_points;
constexpr grid_count_t G29_State::abl_points;
#endif
/**
@ -502,20 +502,13 @@ G29_TYPE GcodeSuite::G29() {
#endif
#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
if (!abl.dryrun
&& (abl.gridSpacing != bedlevel.grid_spacing || abl.probe_position_lf != bedlevel.grid_start)
) {
// 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;
if (!abl.dryrun && (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
}
// Pre-populate local Z values from the stored mesh
TERN_(IS_KINEMATIC, COPY(abl.z_values, bedlevel.z_values));
#endif // AUTO_BED_LEVELING_BILINEAR
#endif
} // !g29_in_progress
@ -692,7 +685,7 @@ G29_TYPE GcodeSuite::G29() {
zig ^= true; // zag
// 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 X with PROBE_Y_FIRST disabled

View File

@ -104,9 +104,8 @@ void GcodeSuite::G29() {
bedlevel.reset();
mbl_probe_index = 0;
if (!ui.wait_for_move) {
queue.inject(parser.seen_test('N') ? F("G28" TERN(CAN_SET_LEVELING_AFTER_G28, "L0", "") "\nG29S2") : F("G29S2"));
TERN_(EXTENSIBLE_UI, ExtUI::onLevelingStart());
TERN_(DWIN_LCD_PROUI, DWIN_LevelingStart());
if (parser.seen_test('N'))
queue.inject(F("G28" TERN_(CAN_SET_LEVELING_AFTER_G28, "L0")));
// Position bed horizontally and Z probe vertically.
#if HAS_SAFE_BED_LEVELING
@ -142,6 +141,11 @@ void GcodeSuite::G29() {
do_blocking_move_to(safe_position);
#endif // HAS_SAFE_BED_LEVELING
queue.inject(F("G29S2"));
TERN_(EXTENSIBLE_UI, ExtUI::onLevelingStart());
TERN_(DWIN_LCD_PROUI, DWIN_LevelingStart());
return;
}
state = MeshNext;
@ -170,7 +174,7 @@ void GcodeSuite::G29() {
SET_SOFT_ENDSTOP_LOOSE(false);
}
// 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
// If G29 is left hanging without completion they won't be re-enabled!
SET_SOFT_ENDSTOP_LOOSE(true);

View File

@ -86,7 +86,7 @@
NUM_AXIS_LIST(
TERN0(X_SENSORLESS, tmc_enable_stallguard(stepperX)),
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(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) {
SERIAL_ECHOPGM(" ");
SERIAL_ECHOF(prefix, AS_CHAR(':'));
SERIAL_ECHOF(prefix, C(':'));
serial_offset(f);
}

View File

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

View File

@ -34,7 +34,6 @@
#include "../../module/probe.h"
#include "../../feature/bedlevel/bedlevel.h"
#include "../../module/temperature.h"
#include "../../module/probe.h"
#include "../../feature/probe_temp_comp.h"
#include "../../lcd/marlinui.h"
@ -108,7 +107,6 @@
};
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);
const float measured_z = probe.probe_at_point(nozpos, PROBE_PT_STOW, 0, false); // verbose=0, probe_relative=false
ptc.set_enabled(true);

View File

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

View File

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

View File

@ -52,7 +52,7 @@
is_err = true;
else {
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*/) {
report_heading_etc(forReplay, F(STR_MAX_ACCELERATION));
SERIAL_ECHOLNPGM_P(
#if NUM_AXES
SERIAL_ECHOPGM_P(
LIST_N(DOUBLE(NUM_AXES),
PSTR(" M201 X"), LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[X_AXIS]),
SP_Y_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Y_AXIS]),
@ -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_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)
for (uint8_t i = 0; i < E_STEPPERS; ++i) {
report_echo_start(forReplay);
@ -191,7 +199,8 @@ void GcodeSuite::M203() {
void GcodeSuite::M203_report(const bool forReplay/*=true*/) {
report_heading_etc(forReplay, F(STR_MAX_FEEDRATES));
SERIAL_ECHOLNPGM_P(
#if NUM_AXES
SERIAL_ECHOPGM_P(
LIST_N(DOUBLE(NUM_AXES),
PSTR(" M203 X"), LINEAR_UNIT(planner.settings.max_feedrate_mm_s[X_AXIS]),
SP_Y_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Y_AXIS]),
@ -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_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)
for (uint8_t i = 0; i < E_STEPPERS; ++i) {
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('T')) planner.settings.min_travel_feedrate_mm_s = parser.value_linear_units();
#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')) {
const float junc_dev = parser.value_linear_units();
if (WITHIN(junc_dev, 0.01f, 0.3f)) {

View File

@ -95,7 +95,9 @@ void GcodeSuite::M217() {
#if ENABLED(TOOLCHANGE_PARK)
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); }
#endif
#if HAS_Y_AXIS
if (parser.seenval('Y')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.y = constrain(v, Y_MIN_POS, Y_MAX_POS); }
#endif
@ -183,8 +185,9 @@ void GcodeSuite::M217_report(const bool forReplay/*=true*/) {
#endif
#if ENABLED(TOOLCHANGE_PARK)
{
SERIAL_ECHOPGM(" W", LINEAR_UNIT(toolchange_settings.enable_park));
#if NUM_AXES
{
SERIAL_ECHOPGM_P(
SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x)
#if HAS_Y_AXIS
@ -203,6 +206,7 @@ void GcodeSuite::M217_report(const bool forReplay/*=true*/) {
);
}
#endif
#endif
#if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
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();
if (target_extruder < 0) return;
#if HAS_X_AXIS
if (parser.seenval('X')) hotend_offset[target_extruder].x = parser.value_linear_units();
#endif
#if HAS_Y_AXIS
if (parser.seenval('Y')) hotend_offset[target_extruder].y = parser.value_linear_units();
#endif
#if HAS_Z_AXIS
if (parser.seenval('Z')) hotend_offset[target_extruder].z = parser.value_linear_units();
#endif
#if ENABLED(DELTA)
if (target_extruder == active_extruder)

View File

@ -66,6 +66,9 @@ void GcodeSuite::M281_report(const bool forReplay/*=true*/) {
#endif
#elif ENABLED(SWITCHING_NOZZLE)
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))
case Z_PROBE_SERVO_NR:
#endif

View File

@ -93,6 +93,8 @@ void GcodeSuite::M92() {
void GcodeSuite::M92_report(const bool forReplay/*=true*/, const int8_t e/*=-1*/) {
report_heading_etc(forReplay, F(STR_STEPS_PER_UNIT));
#if NUM_AXES
#define PRINT_EOL
SERIAL_ECHOPGM_P(LIST_N(DOUBLE(NUM_AXES),
PSTR(" M92 X"), LINEAR_UNIT(planner.settings.axis_steps_per_mm[X_AXIS]),
SP_Y_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Y_AXIS]),
@ -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_W_STR, W_AXIS_UNIT(planner.settings.axis_steps_per_mm[W_AXIS])
));
#endif
#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]));
#endif
SERIAL_EOL();
if (ENABLED(PRINT_EOL)) SERIAL_EOL();
#if ENABLED(DISTINCT_E_FACTORS)
for (uint8_t i = 0; i < E_STEPPERS; ++i) {

View File

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

View File

@ -48,6 +48,7 @@ inline stepper_flags_t selected_axis_bits() {
selected.bits = e_axis_mask;
}
#endif
#if NUM_AXES
selected.bits |= NUM_AXIS_GANG(
(parser.seen_test('X') << X_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(AXIS9_NAME) << W_AXIS)
);
#endif
return selected;
}

View File

@ -89,19 +89,15 @@ void GcodeSuite::M3_M4(const bool is_M4) {
#endif
auto get_s_power = [] {
float u;
if (parser.seenval('S')) {
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)
u = cutter.cpwr_to_upwr(SPEED_POWER_STARTUP);
cutter.menuPower = cutter.unitPower = u;
cutter.menuPower = cutter.unitPower = cutter.cpwr_to_upwr(SPEED_POWER_STARTUP);
// 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);
return u;
cutter.power = TERN(SPINDLE_LASER_USE_PWM, cutter.upower_to_ocr(cutter.unitPower), cutter.unitPower > 0 ? 255 : 0);
};
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)
#include "../gcode.h"
#include "../../MarlinCore.h" // for pin_is_protected
#if HAS_FAN
#include "../../module/temperature.h"
@ -38,6 +37,8 @@
#define OUTPUT_OPEN_DRAIN OUTPUT_OPEN_DRAIN
#endif
bool pin_is_protected(const pin_t pin);
void protected_pin_err() {
SERIAL_ERROR_MSG(STR_ERR_PROTECTED_PIN);
}
@ -53,6 +54,7 @@ void protected_pin_err() {
* I Flag to ignore Marlin's pin protection
*
* T<mode> Pin mode: 0=INPUT 1=OUTPUT 2=INPUT_PULLUP 3=INPUT_PULLDOWN
* 4=INPUT_ANALOG 5=OUTPUT_OPEN_DRAIN
*/
void GcodeSuite::M42() {
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;
}
DEBUG_ECHOPGM("\nActive Ext: ", active_extruder);
if (!active_extruder_parked) DEBUG_ECHOPGM(" NOT ");
DEBUG_ECHOPGM(" parked.");
DEBUG_ECHOPGM("\nactive_extruder_x_pos: ", current_position.x);
DEBUG_ECHOPGM("\ninactive_extruder_x: ", inactive_extruder_x);
DEBUG_ECHOPGM("\nextruder_duplication_enabled: ", extruder_duplication_enabled);
DEBUG_ECHOPGM("\nduplicate_extruder_x_offset: ", duplicate_extruder_x_offset);
DEBUG_ECHOPGM("\nduplicate_extruder_temp_offset: ", duplicate_extruder_temp_offset);
DEBUG_ECHOPGM("\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);
DEBUG_ECHOPGM("\nX2 Home X: ", x_home_pos(1), "\nX2_MIN_POS=", X2_MIN_POS, "\nX2_MAX_POS=", X2_MAX_POS);
DEBUG_ECHOPGM("\nX2_HOME_DIR=", X2_HOME_DIR, "\nX2_HOME_POS=", X2_HOME_POS);
DEBUG_ECHOPGM("\nDEFAULT_DUAL_X_CARRIAGE_MODE=", STRINGIFY(DEFAULT_DUAL_X_CARRIAGE_MODE));
DEBUG_ECHOPGM("\toolchange_settings.z_raise=", toolchange_settings.z_raise);
DEBUG_ECHOPGM("\nDEFAULT_DUPLICATION_X_OFFSET=", DEFAULT_DUPLICATION_X_OFFSET);
DEBUG_EOL();
if (!active_extruder_parked) DEBUG_ECHOPGM(" NOT ", F(" parked."));
DEBUG_ECHOLNPGM(
"\nactive_extruder_x_pos: ", current_position.x,
"\ninactive_extruder_x: ", inactive_extruder_x,
"\nextruder_duplication_enabled: ", extruder_duplication_enabled,
"\nduplicate_extruder_x_offset: ", duplicate_extruder_x_offset,
"\nduplicate_extruder_temp_offset: ", duplicate_extruder_temp_offset,
"\ndelayed_move_time: ", delayed_move_time,
"\nX1 Home: ", x_home_pos(0), " X1_MIN_POS=", X1_MIN_POS, " X1_MAX_POS=", X1_MAX_POS,
"\nX2 Home: ", x_home_pos(1), " X2_MIN_POS=", X2_MIN_POS, " X2_MAX_POS=", X2_MAX_POS,
"\nDEFAULT_DUAL_X_CARRIAGE_MODE=", STRINGIFY(DEFAULT_DUAL_X_CARRIAGE_MODE),
"\toolchange_settings.z_raise=", toolchange_settings.z_raise,
"\nDEFAULT_DUPLICATION_X_OFFSET=", DEFAULT_DUPLICATION_X_OFFSET
);
HOTEND_LOOP() {
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();

View File

@ -22,7 +22,7 @@
#include "../../inc/MarlinConfig.h"
#if ALL(SPI_FLASH, HAS_MEDIA, MARLIN_DEV_MODE)
#if SPI_FLASH_BACKUP
#include "../gcode.h"
#include "../../sd/cardreader.h"
@ -85,4 +85,4 @@ void GcodeSuite::M994() {
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) {
#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));
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("...(", tool_index, ")");
@ -63,8 +71,8 @@ void GcodeSuite::T(const int8_t tool_index) {
tool_change(tool_index
#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
);
}

View File

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

View File

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

View File

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

View File

@ -96,7 +96,7 @@ void GcodeSuite::M125() {
const bool show_lcd = TERN0(HAS_MARLINUI_MENU, parser.boolval('P'));
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);
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))) {
switch (i) {
#if HAS_X_AXIS
case X_AXIS:
TERN_(X_HAS_STEALTHCHOP, if (index < 0 || index == 0) TMC_SET_STEALTH(X));
TERN_(X2_HAS_STEALTHCHOP, if (index < 0 || index == 1) TMC_SET_STEALTH(X2));
break;
#endif
#if HAS_Y_AXIS
case Y_AXIS:
@ -198,13 +200,13 @@ void GcodeSuite::M569_report(const bool forReplay/*=true*/) {
if (chop_x2 || chop_y2 || chop_z2) {
say_M569(forReplay, F("I1"));
if (chop_x2) SERIAL_ECHOPGM_P(SP_X_STR);
#if HAS_Y_AXIS
if (chop_y2) SERIAL_ECHOPGM_P(SP_Y_STR);
#endif
#if HAS_Z_AXIS
if (chop_z2) SERIAL_ECHOPGM_P(SP_Z_STR);
#endif
NUM_AXIS_CODE(
if (chop_x2) SERIAL_ECHOPGM_P(SP_X_STR),
if (chop_y2) SERIAL_ECHOPGM_P(SP_Y_STR),
if (chop_z2) SERIAL_ECHOPGM_P(SP_Z_STR),
NOOP, NOOP, NOOP,
NOOP, NOOP, NOOP
);
SERIAL_EOL();
}

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_E(N) (E_STEPPERS > N && M91x_USE(E##N))
#if M91x_USE(X) || M91x_USE(X2)
#if HAS_X_AXIS && (M91x_USE(X) || M91x_USE(X2))
#define M91x_SOME_X 1
#endif
#if HAS_Y_AXIS && (M91x_USE(Y) || M91x_USE(Y2))

View File

@ -118,7 +118,7 @@ void GcodeSuite::M919() {
// Get the chopper timing for the specified axis and index
switch (i) {
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;
#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
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.x << REL_X),
| (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
#endif
#if HAS_EXTRUDERS
#if HAS_HOTEND
case 104: M104(); break; // M104: Set hot end temperature
case 109: M109(); break; // M109: Wait for hotend temperature to reach target
#endif
@ -934,7 +934,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 575: M575(); break; // M575: Set serial baudrate
#endif
#if HAS_SHAPING
#if HAS_ZV_SHAPING
case 593: M593(); break; // M593: Set Input Shaping parameters
#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
#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 994: M994(); break; // M994: Load a Backup from SD to SPI Flash
#endif
@ -1121,7 +1121,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
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)

View File

@ -300,6 +300,7 @@
* M913 - Set HYBRID_THRESHOLD speed. (Requires HYBRID_THRESHOLD)
* 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)
* M936 - OTA update firmware. (Requires OTA_FIRMWARE_UPDATE)
* M951 - Set Magnetic Parking Extruder parameters. (Requires MAGNETIC_PARKING_EXTRUDER)
* M3426 - Read MCP3426 ADC over I2C. (Requires HAS_MCP3426_ADC)
* M7219 - Control Max7219 Matrix LEDs. (Requires MAX7219_GCODE)
@ -344,14 +345,20 @@ enum AxisRelative : uint8_t {
#if HAS_EXTRUDERS
, E_MODE_ABS, E_MODE_REL
#endif
, NUM_REL_MODES
};
typedef bits_t(NUM_REL_MODES) relative_t;
extern const char G28_STR[];
class GcodeSuite {
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) {
#if HAS_EXTRUDERS
@ -713,7 +720,7 @@ private:
static void M102_report(const bool forReplay=true);
#endif
#if HAS_EXTRUDERS
#if HAS_HOTEND
static void M104_M109(const bool isM109);
FORCE_INLINE static void M104() { M104_M109(false); }
FORCE_INLINE static void M109() { M104_M109(true); }
@ -1081,7 +1088,7 @@ private:
static void M575();
#endif
#if HAS_SHAPING
#if HAS_ZV_SHAPING
static void M593();
static void M593_report(const bool forReplay=true);
#endif

View File

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

View File

@ -30,10 +30,24 @@
#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() {
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);
// Limits the tone duration to 0-5 seconds.

View File

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

View File

@ -189,7 +189,13 @@ void GCodeParser::parse(char *p) {
#endif
// 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
// A '?' signifies an unknown command
@ -333,7 +339,7 @@ void GCodeParser::parse(char *p) {
#if ENABLED(DEBUG_GCODE_PARSER)
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)");
}
#endif

View File

@ -288,6 +288,17 @@ public:
// Bool is true with no value or non-zero
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
#if ENABLED(INCH_MODE_SUPPORT)
@ -307,14 +318,7 @@ public:
}
static float axis_unit_factor(const AxisEnum axis) {
if (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)
) return 1.0f;
if (axis_is_rotational(axis)) return 1.0f;
#if HAS_EXTRUDERS
if (axis >= E_AXIS && volumetric_enabled) return volumetric_unit_factor;
#endif
@ -327,12 +331,12 @@ public:
#else
static 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_linear_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 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 linear_value_to_mm(const_float_t v) { return v; }
static constexpr float axis_value_to_mm(const AxisEnum, const float v) { return v; }
static constexpr float per_axis_value(const AxisEnum, const float v) { return v; }
#endif
@ -402,7 +406,7 @@ public:
#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_diff() { return value_int(); }

View File

@ -37,14 +37,6 @@ GCodeQueue queue;
#include "../MarlinCore.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)
#include "../feature/binary_stream.h"
#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); }
#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) {
PORT_REDIRECT(SERIAL_PORTMASK(serial_ind)); // Reply to the serial port that sent the command
SERIAL_ERROR_START();

View File

@ -201,6 +201,12 @@ public:
*/
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
*/

View File

@ -29,9 +29,19 @@
/**
* 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() {
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')) {
const int v = parser.value_long();
card.setSortFolders(v < 0 ? -1 : v > 0 ? 1 : 0);

View File

@ -28,7 +28,7 @@
#include "../../inc/MarlinConfigPre.h"
#if HAS_EXTRUDERS
#if HAS_HOTEND
#include "../gcode.h"
#include "../../module/temperature.h"
@ -45,10 +45,6 @@
#endif
#endif
#if ENABLED(SINGLENOZZLE_STANDBY_TEMP)
#include "../../module/tool_change.h"
#endif
/**
* M104: Set Hotend Temperature target and return immediately
* 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);
}
#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
TERN_(PRINTJOB_TIMER_AUTOSTART, thermalManager.auto_job_check_timer(isM190, !isM190));
if (isM190)
if (isM190) {
thermalManager.wait_for_bed(no_wait_for_cooling);
else
}
else {
ui.set_status_reset_fn([]{
const celsius_t c = thermalManager.degTargetBed();
return c < 30 || thermalManager.degBedNear(c);
});
}
}
#endif // HAS_HEATED_BED

View File

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

View File

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

View File

@ -38,7 +38,7 @@ void GcodeSuite::M149() {
void GcodeSuite::M149_report(const bool forReplay/*=true*/) {
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());
}

View File

@ -72,13 +72,13 @@ void ESDiagClass::Draw() {
DWINUI::Draw_Button(BTN_Continue, 86, 250);
DWINUI::cursor.y = 80;
#define ES_LABEL(S) draw_es_label(F(STR_##S))
#if HAS_X_MIN
#if USE_X_MIN
ES_LABEL(X_MIN);
#endif
#if HAS_Y_MIN
#if USE_Y_MIN
ES_LABEL(Y_MIN);
#endif
#if HAS_Z_MIN
#if USE_Z_MIN
ES_LABEL(Z_MIN);
#endif
#if HAS_FILAMENT_SENSOR
@ -90,13 +90,13 @@ void ESDiagClass::Draw() {
void ESDiagClass::Update() {
DWINUI::cursor.y = 80;
#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);
#endif
#if HAS_Y_MIN
#if USE_Y_MIN
ES_REPORT(Y_MIN);
#endif
#if HAS_Z_MIN
#if USE_Z_MIN
ES_REPORT(Z_MIN);
#endif
#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
* so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2
*/
#ifndef SPI_CLOCK_MAX
#if SPI_DEVICE == 1
#define SPI_CLOCK_MAX SPI_CLOCK_DIV4
#else
#define SPI_CLOCK_MAX SPI_CLOCK_DIV2
#endif
#endif
uint8_t clock;
switch (spiRate) {
case SPI_FULL_SPEED: clock = SPI_CLOCK_MAX; break;

View File

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

View File

@ -20,7 +20,7 @@
*
*/
#include "../inc/MarlinConfigPre.h"
#include "../inc/MarlinConfig.h"
#if NEED_HEX_PRINT
@ -41,28 +41,26 @@ char* hex_byte(const uint8_t b) {
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 + 3] = hex_nybble(w >> 8);
_hex[byte_start + 4] = hex_nybble(w >> 4);
_hex[byte_start + 5] = hex_nybble(w);
}
char* hex_word(const uint16_t w) {
_hex_word(w);
char* _hex_word(const uint16_t w) {
__hex_word(w);
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[3] = hex_nybble(l >> 24);
_hex[4] = hex_nybble(l >> 20);
_hex[5] = hex_nybble(l >> 16);
_hex_word((uint16_t)(l & 0xFFFF));
__hex_word((uint16_t)(l & 0xFFFF));
return &_hex[2];
}
#endif
char* hex_address(const void * const w) {
#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_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");
for (int B = 24; B >= 8; B -= 8) {
print_hex_byte(w >> B);
SERIAL_CHAR(delimiter);
if (delimiter) SERIAL_CHAR(delimiter);
}
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);
}
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_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_byte(const uint8_t b);
void print_hex_word(const uint16_t 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 "../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 };
#define DIGIT(n) ('0' + (n))
#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
// Format uint8_t (0-100) as rj string with __3% / _23% / 123% format
const char* pcttostrpctrj(const uint8_t i) {
conv[4] = RJDIGIT(i, 100);
conv[5] = RJDIGIT(i, 10);
@ -48,7 +59,7 @@ const char* ui8tostr4pctrj(const uint8_t 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) {
conv[5] = RJDIGIT(i, 100);
conv[6] = RJDIGIT(i, 10);
@ -63,7 +74,7 @@ const char* ui8tostr2(const uint8_t i) {
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) {
int xx = x;
conv[5] = MINUSOR(xx, RJDIGIT(xx, 100));
@ -211,7 +222,7 @@ const char* ftostr41ns(const_float_t f) {
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) {
if (f <= -10 || f >= 100) return ftostr52(f); // -23.45 / 123.45
long i = INTFLOAT(f, 2);
@ -223,7 +234,7 @@ const char* ftostr42_52(const_float_t f) {
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) {
long i = INTFLOAT(f, 2);
conv[2] = MINUSOR(i, DIGIMOD(i, 10000));
@ -235,7 +246,7 @@ const char* ftostr52(const_float_t f) {
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) {
if (f <= -10 || f >= 100) return ftostr63(f); // -23.456 / 123.456
long i = INTFLOAT(f, 3);
@ -248,7 +259,7 @@ const char* ftostr53_63(const_float_t f) {
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) {
long i = INTFLOAT(f, 3);
conv[1] = MINUSOR(i, DIGIMOD(i, 100000));
@ -407,17 +418,17 @@ const char* ftostr52sp(const_float_t f) {
conv[3] = RJDIGIT(i, 1000);
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[6] = DIGIMOD(i, 10);
conv[7] = DIGIT(dig);
}
else {
if ((dig = (i / 10) % 10)) { // first digit after decimal point?
if ((dig = (i / 10) % 10)) { // First digit after decimal point?
conv[5] = '.';
conv[6] = DIGIT(dig);
}
else // nothing after decimal point
else // Nothing after decimal point
conv[5] = conv[6] = ' ';
conv[7] = ' ';
}

View File

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

View File

@ -51,44 +51,44 @@
*/
enum EndstopEnum : char {
// Common XYZ (ABC) endstops. Defined according to USE_[XYZ](MIN|MAX)_PLUG settings.
_ES_ITEM(HAS_X_MIN, X_MIN)
_ES_ITEM(HAS_X_MAX, X_MAX)
_ES_ITEM(HAS_Y_MIN, Y_MIN)
_ES_ITEM(HAS_Y_MAX, Y_MAX)
_ES_ITEM(HAS_Z_MIN, Z_MIN)
_ES_ITEM(HAS_Z_MAX, Z_MAX)
_ES_ITEM(HAS_I_MIN, I_MIN)
_ES_ITEM(HAS_I_MAX, I_MAX)
_ES_ITEM(HAS_J_MIN, J_MIN)
_ES_ITEM(HAS_J_MAX, J_MAX)
_ES_ITEM(HAS_K_MIN, K_MIN)
_ES_ITEM(HAS_K_MAX, K_MAX)
_ES_ITEM(HAS_U_MIN, U_MIN)
_ES_ITEM(HAS_U_MAX, U_MAX)
_ES_ITEM(HAS_V_MIN, V_MIN)
_ES_ITEM(HAS_V_MAX, V_MAX)
_ES_ITEM(HAS_W_MIN, W_MIN)
_ES_ITEM(HAS_W_MAX, W_MAX)
_ES_ITEM(USE_X_MIN, X_MIN)
_ES_ITEM(USE_X_MAX, X_MAX)
_ES_ITEM(USE_Y_MIN, Y_MIN)
_ES_ITEM(USE_Y_MAX, Y_MAX)
_ES_ITEM(USE_Z_MIN, Z_MIN)
_ES_ITEM(USE_Z_MAX, Z_MAX)
_ES_ITEM(USE_I_MIN, I_MIN)
_ES_ITEM(USE_I_MAX, I_MAX)
_ES_ITEM(USE_J_MIN, J_MIN)
_ES_ITEM(USE_J_MAX, J_MAX)
_ES_ITEM(USE_K_MIN, K_MIN)
_ES_ITEM(USE_K_MAX, K_MAX)
_ES_ITEM(USE_U_MIN, U_MIN)
_ES_ITEM(USE_U_MAX, U_MAX)
_ES_ITEM(USE_V_MIN, V_MIN)
_ES_ITEM(USE_V_MAX, V_MAX)
_ES_ITEM(USE_W_MIN, W_MIN)
_ES_ITEM(USE_W_MAX, W_MAX)
// Extra Endstops for XYZ
#if ENABLED(X_DUAL_ENDSTOPS)
_ES_ITEM(HAS_X_MIN, X2_MIN)
_ES_ITEM(HAS_X_MAX, X2_MAX)
_ES_ITEM(USE_X_MIN, X2_MIN)
_ES_ITEM(USE_X_MAX, X2_MAX)
#endif
#if ENABLED(Y_DUAL_ENDSTOPS)
_ES_ITEM(HAS_Y_MIN, Y2_MIN)
_ES_ITEM(HAS_Y_MAX, Y2_MAX)
_ES_ITEM(USE_Y_MIN, Y2_MIN)
_ES_ITEM(USE_Y_MAX, Y2_MAX)
#endif
#if ENABLED(Z_MULTI_ENDSTOPS)
_ES_ITEM(HAS_Z_MIN, Z2_MIN)
_ES_ITEM(HAS_Z_MAX, Z2_MAX)
_ES_ITEM(USE_Z_MIN, Z2_MIN)
_ES_ITEM(USE_Z_MAX, Z2_MAX)
#if NUM_Z_STEPPERS >= 3
_ES_ITEM(HAS_Z_MIN, Z3_MIN)
_ES_ITEM(HAS_Z_MAX, Z3_MAX)
_ES_ITEM(USE_Z_MIN, Z3_MIN)
_ES_ITEM(USE_Z_MAX, Z3_MAX)
#endif
#if NUM_Z_STEPPERS >= 4
_ES_ITEM(HAS_Z_MIN, Z4_MIN)
_ES_ITEM(HAS_Z_MAX, Z4_MAX)
_ES_ITEM(USE_Z_MIN, Z4_MIN)
_ES_ITEM(USE_Z_MAX, Z4_MAX)
#endif
#endif
@ -101,28 +101,28 @@ enum EndstopEnum : char {
NUM_ENDSTOP_STATES
// 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)
#if ENABLED(X_DUAL_ENDSTOPS)
, X2_ENDSTOP = TERN(X_HOME_TO_MAX, X2_MAX, X2_MIN)
#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)
#if ENABLED(Y_DUAL_ENDSTOPS)
, Y2_ENDSTOP = TERN(Y_HOME_TO_MAX, Y2_MAX, Y2_MIN)
#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))
#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)
#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)
#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)
#endif
};
@ -133,7 +133,7 @@ enum EndstopEnum : char {
class Endstops {
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)
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
inline void report_logical_position(const xyze_pos_t &rpos) {
const xyze_pos_t lpos = rpos.asLogical();
#if NUM_AXES
SERIAL_ECHOPGM_P(
LIST_N(DOUBLE(NUM_AXES),
X_LBL, lpos.x,
@ -203,10 +204,11 @@ inline void report_logical_position(const xyze_pos_t &rpos) {
SP_V_LBL, lpos.v,
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.
@ -354,7 +356,7 @@ void report_current_position_projected() {
#else // CARTESIAN
// Return true if the given position is within the machine bounds.
bool position_is_reachable(const_float_t rx, const_float_t ry) {
bool position_is_reachable(TERN_(HAS_X_AXIS, const_float_t rx) OPTARG(HAS_Y_AXIS, const_float_t ry)) {
if (TERN0(HAS_Y_AXIS, !COORDINATE_OKAY(ry, Y_MIN_POS - fslop, Y_MAX_POS + fslop))) return false;
#if ENABLED(DUAL_X_CARRIAGE)
if (active_extruder)
@ -362,7 +364,8 @@ void report_current_position_projected() {
else
return COORDINATE_OKAY(rx, X1_MIN_POS - fslop, X1_MAX_POS + fslop);
#else
return COORDINATE_OKAY(rx, X_MIN_POS - fslop, X_MAX_POS + fslop);
if (TERN0(HAS_X_AXIS, !COORDINATE_OKAY(rx, X_MIN_POS - fslop, X_MAX_POS + fslop))) return false;
return true;
#endif
}
@ -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*/
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;
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))
TERN(IS_KINEMATIC, prepare_fast_move_to_destination(), NOOP);
else
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...]]]) 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.
* - Before returning, wait for the planner buffer to empty.
*/
void do_blocking_move_to(NUM_AXIS_ARGS(const_float_t), const_feedRate_t fr_mm_s/*=0.0f*/) {
void do_blocking_move_to(NUM_AXIS_ARGS_(const_float_t) const_feedRate_t fr_mm_s/*=0.0f*/) {
DEBUG_SECTION(log_move, "do_blocking_move_to", DEBUGGING(LEVELING));
#if NUM_AXES
if (DEBUGGING(LEVELING)) DEBUG_XYZ("> ", NUM_AXIS_ARGS());
#endif
const feedRate_t xy_feedrate = fr_mm_s ?: feedRate_t(XY_PROBE_FEEDRATE_MM_S);
#if HAS_Z_AXIS
const feedRate_t z_feedrate = fr_mm_s ?: homing_feedrate(Z_AXIS);
#endif
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)
// 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 SECONDARY_AXES
secondary_axis_moves(SECONDARY_AXIS_LIST(i, j, k, u, v, w), fr_mm_s);
#endif
#elif IS_SCARA
// 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);
#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 (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); }
#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
current_position.i = i; line_to_current_position(i_feedrate);
#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);
#if SECONDARY_AXES
secondary_axis_moves(SECONDARY_AXIS_LIST(i, j, k, u, v, w), fr_mm_s);
#endif
#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*/) {
do_blocking_move_to(NUM_AXIS_LIST(raw.x, raw.y, current_position.z, current_position.i, current_position.j, current_position.k,
current_position.u, current_position.v, current_position.w), fr_mm_s);
do_blocking_move_to(NUM_AXIS_LIST_(raw.x, raw.y, current_position.z, current_position.i, current_position.j, current_position.k,
current_position.u, current_position.v, current_position.w) fr_mm_s);
}
void do_blocking_move_to(const xyz_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*/) {
do_blocking_move_to(NUM_AXIS_ELEM(raw), fr_mm_s);
do_blocking_move_to(NUM_AXIS_ELEM_(raw) fr_mm_s);
}
void do_blocking_move_to(const xyze_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*/) {
do_blocking_move_to(NUM_AXIS_ELEM(raw), fr_mm_s);
do_blocking_move_to(NUM_AXIS_ELEM_(raw) fr_mm_s);
}
#if HAS_X_AXIS
void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s/*=0.0*/) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("do_blocking_move_to_x(", rx, ", ", fr_mm_s, ")");
do_blocking_move_to(
NUM_AXIS_LIST(rx, current_position.y, current_position.z, current_position.i, current_position.j, current_position.k,
current_position.u, current_position.v, current_position.w),
NUM_AXIS_LIST_(rx, current_position.y, current_position.z, current_position.i, current_position.j, current_position.k,
current_position.u, current_position.v, current_position.w)
fr_mm_s
);
}
#endif
#if HAS_Y_AXIS
void do_blocking_move_to_y(const_float_t ry, const_feedRate_t fr_mm_s/*=0.0*/) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("do_blocking_move_to_y(", ry, ", ", fr_mm_s, ")");
do_blocking_move_to(
NUM_AXIS_LIST(current_position.x, ry, current_position.z, current_position.i, current_position.j, current_position.k,
current_position.u, current_position.v, current_position.w),
NUM_AXIS_LIST_(current_position.x, ry, current_position.z, current_position.i, current_position.j, current_position.k,
current_position.u, current_position.v, current_position.w)
fr_mm_s
);
}
@ -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
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);
}
#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*/) {
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
);
}
@ -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*/) {
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
);
}
@ -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*/) {
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
);
}
@ -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*/) {
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
);
}
@ -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*/) {
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
);
}
@ -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*/) {
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
);
}
@ -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
void do_blocking_move_to_xy(const_float_t rx, const_float_t ry, const_feedRate_t fr_mm_s/*=0.0*/) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("do_blocking_move_to_xy(", rx, ", ", ry, ", ", fr_mm_s, ")");
do_blocking_move_to(
NUM_AXIS_LIST(rx, ry, current_position.z, current_position.i, current_position.j, current_position.k,
current_position.u, current_position.v, current_position.w),
NUM_AXIS_LIST_(rx, ry, current_position.z, current_position.i, current_position.j, current_position.k,
current_position.u, current_position.v, current_position.w)
fr_mm_s
);
}
@ -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
void do_blocking_move_to_xy_z(const xy_pos_t &raw, const_float_t z, const_feedRate_t fr_mm_s/*=0.0f*/) {
do_blocking_move_to(
NUM_AXIS_LIST(raw.x, raw.y, z, current_position.i, current_position.j, current_position.k,
current_position.u, current_position.v, current_position.w),
NUM_AXIS_LIST_(raw.x, raw.y, z, current_position.i, current_position.j, current_position.k,
current_position.u, current_position.v, current_position.w)
fr_mm_s
);
}
@ -900,7 +902,7 @@ void restore_feedrate_and_scaling() {
#endif
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
#if HAS_X_AXIS
if (axis_was_homed(X_AXIS)) {
#if !HAS_SOFTWARE_ENDSTOPS || ENABLED(MIN_SOFTWARE_ENDSTOP_X)
NOLESS(target.x, soft_endstop.min.x);
@ -946,6 +949,7 @@ void restore_feedrate_and_scaling() {
NOMORE(target.x, soft_endstop.max.x);
#endif
}
#endif
#if HAS_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) {
idex_mirrored_mode = mirr;
stepper.set_directions();
stepper.apply_directions();
}
void set_duplication_enabled(const bool dupe, const int8_t tool_index/*=-1*/) {
extruder_duplication_enabled = dupe;
if (tool_index >= 0) active_extruder = tool_index;
stepper.set_directions();
stepper.apply_directions();
}
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);
}
}
stepper.set_directions();
stepper.apply_directions();
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 (!DEBUGGING(DRYRUN) && destination.e != current_position.e) {
bool ignore_e = false;
#if ENABLED(PREVENT_COLD_EXTRUSION)
ignore_e = thermalManager.tooColdToExtrude(active_extruder);
bool ignore_e = thermalManager.tooColdToExtrude(active_extruder);
if (ignore_e) SERIAL_ECHO_MSG(STR_ERR_COLD_EXTRUDE_STOP);
#endif
#if ENABLED(PREVENT_LENGTHY_EXTRUDE)
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
}
#if ENABLED(SPI_ENDSTOPS)
switch (axis) {
case X_AXIS: if (ENABLED(X_SPI_SENSORLESS)) endstops.tmc_spi_homing.x = true; break;
#if HAS_Y_AXIS
case Y_AXIS: if (ENABLED(Y_SPI_SENSORLESS)) endstops.tmc_spi_homing.y = true; break;
#if X_SPI_SENSORLESS
case X_AXIS: endstops.tmc_spi_homing.x = true; break;
#endif
#if HAS_Z_AXIS
case Z_AXIS: if (ENABLED(Z_SPI_SENSORLESS)) endstops.tmc_spi_homing.z = true; break;
#if Y_SPI_SENSORLESS
case Y_AXIS: endstops.tmc_spi_homing.y = true; break;
#endif
#if HAS_I_AXIS
case I_AXIS: if (ENABLED(I_SPI_SENSORLESS)) endstops.tmc_spi_homing.i = true; break;
#if Z_SPI_SENSORLESS
case Z_AXIS: endstops.tmc_spi_homing.z = true; break;
#endif
#if HAS_J_AXIS
case J_AXIS: if (ENABLED(J_SPI_SENSORLESS)) endstops.tmc_spi_homing.j = true; break;
#if I_SPI_SENSORLESS
case I_AXIS: endstops.tmc_spi_homing.i = true; break;
#endif
#if HAS_K_AXIS
case K_AXIS: if (ENABLED(K_SPI_SENSORLESS)) endstops.tmc_spi_homing.k = true; break;
#if J_SPI_SENSORLESS
case J_AXIS: endstops.tmc_spi_homing.j = true; break;
#endif
#if HAS_U_AXIS
case U_AXIS: if (ENABLED(U_SPI_SENSORLESS)) endstops.tmc_spi_homing.u = true; break;
#if K_SPI_SENSORLESS
case K_AXIS: endstops.tmc_spi_homing.k = true; break;
#endif
#if HAS_V_AXIS
case V_AXIS: if (ENABLED(V_SPI_SENSORLESS)) endstops.tmc_spi_homing.v = true; break;
#if U_SPI_SENSORLESS
case U_AXIS: endstops.tmc_spi_homing.u = true; break;
#endif
#if HAS_W_AXIS
case W_AXIS: if (ENABLED(W_SPI_SENSORLESS)) endstops.tmc_spi_homing.w = true; break;
#if V_SPI_SENSORLESS
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
default: break;
}
#endif
TERN_(IMPROVE_HOMING_RELIABILITY, sg_guard_period = millis() + default_sg_guard_duration);
@ -1669,36 +1669,36 @@ void prepare_line_to_destination() {
#endif
}
#if ENABLED(SPI_ENDSTOPS)
switch (axis) {
case X_AXIS: if (ENABLED(X_SPI_SENSORLESS)) endstops.tmc_spi_homing.x = false; break;
#if HAS_Y_AXIS
case Y_AXIS: if (ENABLED(Y_SPI_SENSORLESS)) endstops.tmc_spi_homing.y = false; break;
#if X_SPI_SENSORLESS
case X_AXIS: endstops.tmc_spi_homing.x = false; break;
#endif
#if HAS_Z_AXIS
case Z_AXIS: if (ENABLED(Z_SPI_SENSORLESS)) endstops.tmc_spi_homing.z = false; break;
#if Y_SPI_SENSORLESS
case Y_AXIS: endstops.tmc_spi_homing.y = false; break;
#endif
#if HAS_I_AXIS
case I_AXIS: if (ENABLED(I_SPI_SENSORLESS)) endstops.tmc_spi_homing.i = false; break;
#if Z_SPI_SENSORLESS
case Z_AXIS: endstops.tmc_spi_homing.z = false; break;
#endif
#if HAS_J_AXIS
case J_AXIS: if (ENABLED(J_SPI_SENSORLESS)) endstops.tmc_spi_homing.j = false; break;
#if I_SPI_SENSORLESS
case I_AXIS: endstops.tmc_spi_homing.i = false; break;
#endif
#if HAS_K_AXIS
case K_AXIS: if (ENABLED(K_SPI_SENSORLESS)) endstops.tmc_spi_homing.k = false; break;
#if J_SPI_SENSORLESS
case J_AXIS: endstops.tmc_spi_homing.j = false; break;
#endif
#if HAS_U_AXIS
case U_AXIS: if (ENABLED(U_SPI_SENSORLESS)) endstops.tmc_spi_homing.u = false; break;
#if K_SPI_SENSORLESS
case K_AXIS: endstops.tmc_spi_homing.k = false; break;
#endif
#if HAS_V_AXIS
case V_AXIS: if (ENABLED(V_SPI_SENSORLESS)) endstops.tmc_spi_homing.v = false; break;
#if U_SPI_SENSORLESS
case U_AXIS: endstops.tmc_spi_homing.u = false; break;
#endif
#if HAS_W_AXIS
case W_AXIS: if (ENABLED(W_SPI_SENSORLESS)) endstops.tmc_spi_homing.w = false; break;
#if V_SPI_SENSORLESS
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
default: break;
}
#endif
}
#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);
if (DEBUGGING(LEVELING)) {
DEBUG_ECHOPGM("...(", AS_CHAR(AXIS_CHAR(axis)), ", ", distance, ", ");
DEBUG_ECHOPGM("...(", C(AXIS_CHAR(axis)), ", ", distance, ", ");
if (fr_mm_s)
DEBUG_ECHO(fr_mm_s);
else
@ -1802,12 +1802,12 @@ void prepare_line_to_destination() {
* "trusted" position).
*/
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_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));
}
@ -1916,7 +1916,7 @@ void prepare_line_to_destination() {
if (ABS(phaseDelta) * planner.mm_per_step[axis] / phasePerUStep < 0.05f)
SERIAL_ECHOLNPGM("Selected home phase ", home_phase[axis],
" 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.
if (phaseDelta < 0) phaseDelta += 1024;
@ -1927,7 +1927,7 @@ void prepare_line_to_destination() {
// Optional debug messages
if (DEBUGGING(LEVELING)) {
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
);
}
@ -1966,7 +1966,7 @@ void prepare_line_to_destination() {
if (true MAIN_AXIS_MAP(_ANDCANT)) return;
#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)
? 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");
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 (axis == Z_AXIS && !bltouch.high_speed_mode) bltouch.stow(); // Intermediate STOW (in LOW SPEED MODE)
#endif
// If a second homing move is configured...
if (bump) {
// Move away from the endstop by the axis HOMING_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);
@ -2049,35 +2049,12 @@ void prepare_line_to_destination() {
// Check for a broken endstop
EndstopEnum es;
switch (axis) {
default:
case X_AXIS: es = X_ENDSTOP; break;
#if HAS_Y_AXIS
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
#define _ESCASE(A) case A##_AXIS: es = A##_ENDSTOP; break;
MAIN_AXIS_MAP(_ESCASE)
default: break;
}
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));
}
#endif
@ -2091,11 +2068,11 @@ void prepare_line_to_destination() {
const float rebump = bump * 2;
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Re-bump: ", rebump, "mm");
do_homing_move(axis, rebump, get_homing_bump_feedrate(axis), true);
}
#if ALL(HOMING_Z_WITH_PROBE, BLTOUCH)
if (axis == Z_AXIS) bltouch.stow(); // The final STOW
#endif
}
#if HAS_EXTRA_ENDSTOPS
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;
#endif
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< homeaxis(", AS_CHAR(AXIS_CHAR(axis)), ")");
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< homeaxis(", C(AXIS_CHAR(axis)), ")");
} // homeaxis()
@ -2318,7 +2295,7 @@ void prepare_line_to_destination() {
* Callers must sync the planner position after calling this!
*/
void set_axis_is_at_home(const AxisEnum axis) {
if (DEBUGGING(LEVELING)) DEBUG_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_homed(axis);
@ -2363,17 +2340,17 @@ void set_axis_is_at_home(const AxisEnum axis) {
if (DEBUGGING(LEVELING)) {
#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
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
void update_workspace_offset(const AxisEnum 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

View File

@ -151,9 +151,9 @@ inline float home_bump_mm(const AxisEnum axis) {
extern xyz_pos_t hotend_offset[HOTENDS];
void reset_hotend_offsets();
#elif HOTENDS
constexpr xyz_pos_t hotend_offset[HOTENDS] = { { 0 } };
constexpr xyz_pos_t hotend_offset[HOTENDS] = { { TERN_(HAS_X_AXIS, 0) } };
#else
constexpr xyz_pos_t hotend_offset[1] = { { 0 } };
constexpr xyz_pos_t hotend_offset[1] = { { TERN_(HAS_X_AXIS, 0) } };
#endif
#if HAS_SOFTWARE_ENDSTOPS
@ -167,10 +167,12 @@ inline float home_bump_mm(const AxisEnum axis) {
amin = -100000; amax = 100000; // "No limits"
#if HAS_SOFTWARE_ENDSTOPS
if (enabled()) switch (axis) {
#if HAS_X_AXIS
case X_AXIS:
TERN_(MIN_SOFTWARE_ENDSTOP_X, amin = min.x);
TERN_(MAX_SOFTWARE_ENDSTOP_X, amax = max.x);
break;
#endif
#if HAS_Y_AXIS
case Y_AXIS:
TERN_(MIN_SOFTWARE_ENDSTOP_Y, amin = min.y);
@ -344,12 +346,14 @@ inline void prepare_internal_move_to_destination(const_feedRate_t fr_mm_s=0.0f)
/**
* Blocking movement and shorthand functions
*/
void do_blocking_move_to(NUM_AXIS_ARGS(const_float_t), const_feedRate_t fr_mm_s=0.0f);
void do_blocking_move_to(NUM_AXIS_ARGS_(const_float_t) const_feedRate_t fr_mm_s=0.0f);
void do_blocking_move_to(const xy_pos_t &raw, const_feedRate_t fr_mm_s=0.0f);
void do_blocking_move_to(const xyz_pos_t &raw, const_feedRate_t fr_mm_s=0.0f);
void do_blocking_move_to(const xyze_pos_t &raw, const_feedRate_t fr_mm_s=0.0f);
#if HAS_X_AXIS
void do_blocking_move_to_x(const_float_t rx, const_feedRate_t fr_mm_s=0.0f);
#endif
#if HAS_Y_AXIS
void do_blocking_move_to_y(const_float_t ry, const_feedRate_t fr_mm_s=0.0f);
#endif
@ -409,12 +413,9 @@ void restore_feedrate_and_scaling();
/**
* 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;
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);
#if HAS_ENDSTOPS
@ -432,26 +433,21 @@ void set_axis_is_at_home(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);
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
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 set_axis_never_homed(const AxisEnum) {}
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 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
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_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; }
@ -506,8 +502,10 @@ void home_if_needed(const bool keeplev=false);
FORCE_INLINE void toNative(xyz_pos_t&) {}
FORCE_INLINE void toNative(xyze_pos_t&) {}
#endif
#if HAS_X_AXIS
#define LOGICAL_X_POSITION(POS) NATIVE_TO_LOGICAL(POS, X_AXIS)
#define RAW_X_POSITION(POS) LOGICAL_TO_NATIVE(POS, X_AXIS)
#endif
#if HAS_Y_AXIS
#define LOGICAL_Y_POSITION(POS) NATIVE_TO_LOGICAL(POS, Y_AXIS)
#define RAW_Y_POSITION(POS) LOGICAL_TO_NATIVE(POS, Y_AXIS)
@ -560,9 +558,9 @@ void home_if_needed(const bool keeplev=false);
#else
// Return true if the given position is within the machine bounds.
bool position_is_reachable(const_float_t rx, const_float_t ry);
bool position_is_reachable(TERN_(HAS_X_AXIS, const_float_t rx) OPTARG(HAS_Y_AXIS, const_float_t ry));
inline bool position_is_reachable(const xy_pos_t &pos) {
return position_is_reachable(pos.x, pos.y);
return position_is_reachable(TERN_(HAS_X_AXIS, pos.x) OPTARG(HAS_Y_AXIS, pos.y));
}
#endif
@ -599,7 +597,7 @@ void home_if_needed(const bool keeplev=false);
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 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
// 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;
@ -198,7 +198,9 @@ float Planner::mm_per_step[DISTINCT_AXES]; // (mm) Millimeters per step
constexpr bool Planner::leveling_active;
#endif
#if ENABLED(SKEW_CORRECTION)
skew_factor_t Planner::skew_factor; // Initialized by settings.load()
#endif
#if ENABLED(AUTOTEMP)
celsius_t Planner::autotemp_max = 250,
@ -1733,7 +1735,7 @@ float Planner::triggered_position_mm(const AxisEnum axis) {
bool Planner::busy() {
return (has_blocks_queued() || cleaning_buffer_counter
|| 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);
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.i, block->steps.j, block->steps.k,
block->steps.u, block->steps.v, block->steps.w
));
))
#elif HAS_EXTRUDERS
esteps
#endif
);
// Bail if this is a zero-length block
if (block->step_event_count < MIN_STEPS_PER_SEGMENT) return false;
@ -2348,12 +2356,13 @@ bool Planner::_populate_block(
// 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 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)
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
inverse_secs = fr_mm_s * inverse_millimeters;
fr_mm_s
#endif
);
// Get the number of non busy movements in queue (non busy means that they can be altered)
const uint8_t moves_queued = nonbusy_movesplanned();
@ -2496,8 +2505,8 @@ bool Planner::_populate_block(
#if ENABLED(LIN_ADVANCE)
bool use_advance_lead = false;
#endif
if (NUM_AXIS_GANG(
!block->steps.a, && !block->steps.b, && !block->steps.c,
if (true NUM_AXIS_GANG(
&& !block->steps.a, && !block->steps.b, && !block->steps.c,
&& !block->steps.i, && !block->steps.j, && !block->steps.k,
&& !block->steps.u, && !block->steps.v, && !block->steps.w)
) { // Is this a retract / recover move?
@ -2551,9 +2560,10 @@ bool Planner::_populate_block(
else {
// 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;
if (TERN0(LA_DEBUG, accel > max_accel_steps_per_s2))
SERIAL_ECHOLNPGM("Acceleration limited.");
NOMORE(accel, max_accel_steps_per_s2);
if (accel > max_accel_steps_per_s2) {
accel = max_accel_steps_per_s2;
if (ENABLED(LA_DEBUG)) SERIAL_ECHOLNPGM("Acceleration limited.");
}
}
}
#endif

View File

@ -286,7 +286,19 @@ typedef struct PlannerBlock {
#define HAS_POSITION_FLOAT 1
#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)
typedef struct {
@ -346,7 +358,7 @@ typedef struct {
} skew_factor_t;
#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
#if ENABLED(ARC_SUPPORT)
@ -474,7 +486,9 @@ class Planner {
static xyze_pos_t position_cart;
#endif
#if ENABLED(SKEW_CORRECTION)
static skew_factor_t skew_factor;
#endif
#if ENABLED(SD_ABORT_ON_ENDSTOP_HIT)
static bool abort_on_endstop_hit;
@ -736,10 +750,10 @@ class Planner {
#endif // HAS_POSITION_MODIFIERS
// 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
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
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); }
// 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
@ -999,8 +1013,8 @@ class Planner {
/**
* 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 prev_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_dec_mod(block_index, 1); }
/**
* 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