Merge upstream changes from Marlin 2.1.2.2

This commit is contained in:
Stefan Kalscheuer
2024-02-13 20:32:22 +01:00
parent e466309bfb
commit 752476dc8f
1367 changed files with 41601 additions and 31124 deletions

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
@@ -707,7 +707,7 @@ void GcodeSuite::G26() {
#error "A_CNT must be a positive value. Please change A_INT."
#endif
float trig_table[A_CNT];
LOOP_L_N(i, A_CNT)
for (uint8_t i = 0; i < A_CNT; ++i)
trig_table[i] = INTERSECTION_CIRCLE_RADIUS * cos(RADIANS(i * A_INT));
#endif // !ARC_SUPPORT

View File

@@ -57,8 +57,9 @@
* 41 - Counter-Clockwise M4
* 50 - Clockwise M5
* 51 - Counter-Clockwise M5
**/
*/
void GcodeSuite::G35() {
DEBUG_SECTION(log_G35, "G35", DEBUGGING(LEVELING));
if (DEBUGGING(LEVELING)) log_machine_info();
@@ -82,9 +83,7 @@ void GcodeSuite::G35() {
set_bed_leveling_enabled(false);
#endif
#if ENABLED(CNC_WORKSPACE_PLANES)
workspace_plane = PLANE_XY;
#endif
TERN_(CNC_WORKSPACE_PLANES, workspace_plane = PLANE_XY);
// Always home with tool 0 active
#if HAS_MULTI_HOTEND
@@ -101,7 +100,7 @@ void GcodeSuite::G35() {
bool err_break = false;
// Probe all positions
LOOP_L_N(i, G35_PROBE_COUNT) {
for (uint8_t i = 0; i < G35_PROBE_COUNT; ++i) {
// In BLTOUCH HS mode, the probe travels in a deployed state.
// Users of G35 might have a badly misaligned bed, so raise Z by the
@@ -134,7 +133,7 @@ void GcodeSuite::G35() {
const float threads_factor[] = { 0.5, 0.7, 0.8 };
// Calculate adjusts
LOOP_S_L_N(i, 1, G35_PROBE_COUNT) {
for (uint8_t i = 1; i < G35_PROBE_COUNT; ++i) {
const float diff = z_measured[0] - z_measured[i],
adjust = ABS(diff) < 0.001f ? 0 : diff / threads_factor[(screw_thread - 30) / 10];
@@ -158,7 +157,7 @@ void GcodeSuite::G35() {
if (old_tool_index != 0) tool_change(old_tool_index, DISABLED(PARKING_EXTRUDER)); // Fetch previous toolhead if not PARKING_EXTRUDER
#endif
#if BOTH(HAS_LEVELING, RESTORE_LEVELING_AFTER_G35)
#if ALL(HAS_LEVELING, RESTORE_LEVELING_AFTER_G35)
set_bed_leveling_enabled(leveling_was_active);
#endif

View File

@@ -101,16 +101,16 @@ public:
uint8_t tool_index;
#endif
#if EITHER(PROBE_MANUALLY, AUTO_BED_LEVELING_LINEAR)
#if ANY(PROBE_MANUALLY, AUTO_BED_LEVELING_LINEAR)
int abl_probe_index;
#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,16 +136,16 @@ 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
eqnBVector[GRID_MAX_POINTS], // "B" vector of Z points
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
#endif
};
#if ABL_USES_GRID && EITHER(AUTO_BED_LEVELING_3POINT, AUTO_BED_LEVELING_BILINEAR)
#if ABL_USES_GRID && ANY(AUTO_BED_LEVELING_3POINT, AUTO_BED_LEVELING_BILINEAR)
constexpr xy_uint8_t G29_State::grid_points;
constexpr int G29_State::abl_points;
constexpr grid_count_t G29_State::abl_points;
#endif
/**
@@ -226,6 +226,7 @@ public:
* There's no extra effect if you have a fixed Z probe.
*/
G29_TYPE GcodeSuite::G29() {
DEBUG_SECTION(log_G29, "G29", DEBUGGING(LEVELING));
// Leveling state is persistent when done manually with multiple G29 commands
@@ -235,7 +236,7 @@ G29_TYPE GcodeSuite::G29() {
reset_stepper_timeout();
// Q = Query leveling and G29 state
const bool seenQ = EITHER(DEBUG_LEVELING_FEATURE, PROBE_MANUALLY) && parser.seen_test('Q');
const bool seenQ = ANY(DEBUG_LEVELING_FEATURE, PROBE_MANUALLY) && parser.seen_test('Q');
// G29 Q is also available if debugging
#if ENABLED(DEBUG_LEVELING_FEATURE)
@@ -286,7 +287,7 @@ G29_TYPE GcodeSuite::G29() {
if (active_extruder != 0) tool_change(0, true);
#endif
#if EITHER(PROBE_MANUALLY, AUTO_BED_LEVELING_LINEAR)
#if ANY(PROBE_MANUALLY, AUTO_BED_LEVELING_LINEAR)
abl.abl_probe_index = -1;
#endif
@@ -443,7 +444,7 @@ G29_TYPE GcodeSuite::G29() {
#if ENABLED(PREHEAT_BEFORE_LEVELING)
if (!abl.dryrun) probe.preheat_for_probing(LEVELING_NOZZLE_TEMP,
#if BOTH(DWIN_LCD_PROUI, HAS_HEATED_BED)
#if ALL(DWIN_LCD_PROUI, HAS_HEATED_BED)
HMI_data.BedLevT
#else
LEVELING_BED_TEMP
@@ -501,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
@@ -556,7 +550,7 @@ G29_TYPE GcodeSuite::G29() {
}
else {
#if EITHER(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT)
#if ANY(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_3POINT)
const uint16_t index = abl.abl_probe_index - 1;
#endif
@@ -691,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
@@ -742,7 +736,7 @@ G29_TYPE GcodeSuite::G29() {
// Probe at 3 arbitrary points
LOOP_L_N(i, 3) {
for (uint8_t i = 0; i < 3; ++i) {
if (abl.verbose_level) SERIAL_ECHOLNPGM("Probing point ", i + 1, "/3.");
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT(MSG_PROBING_POINT), int(i + 1)));
@@ -853,7 +847,7 @@ G29_TYPE GcodeSuite::G29() {
auto print_topo_map = [&](FSTR_P const title, const bool get_min) {
SERIAL_ECHOF(title);
for (int8_t yy = abl.grid_points.y - 1; yy >= 0; yy--) {
LOOP_L_N(xx, abl.grid_points.x) {
for (uint8_t xx = 0; xx < abl.grid_points.x; ++xx) {
const int ind = abl.indexIntoAB[xx][yy];
xyz_float_t tmp = { abl.eqnAMatrix[ind + 0 * abl.abl_points],
abl.eqnAMatrix[ind + 1 * abl.abl_points], 0 };

View File

@@ -56,8 +56,8 @@ void GcodeSuite::M421() {
const float zval = parser.value_linear_units();
uint8_t sx = ix >= 0 ? ix : 0, ex = ix >= 0 ? ix : GRID_MAX_POINTS_X - 1,
sy = iy >= 0 ? iy : 0, ey = iy >= 0 ? iy : GRID_MAX_POINTS_Y - 1;
LOOP_S_LE_N(x, sx, ex) {
LOOP_S_LE_N(y, sy, ey) {
for (uint8_t x = sx; x <= ex; ++x) {
for (uint8_t y = sy; y <= ey; ++y) {
bedlevel.z_values[x][y] = zval + (hasQ ? bedlevel.z_values[x][y] : 0);
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(x, y, bedlevel.z_values[x][y]));
}

View File

@@ -64,6 +64,7 @@ inline void echo_not_entered(const char c) { SERIAL_CHAR(c); SERIAL_ECHOLNPGM("
* S5 Reset and disable mesh
*/
void GcodeSuite::G29() {
DEBUG_SECTION(log_G29, "G29", true);
// G29 Q is also available if debugging
@@ -103,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
@@ -141,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;
@@ -169,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

@@ -66,7 +66,7 @@ void GcodeSuite::M421() {
else if (!WITHIN(ij.x, 0, GRID_MAX_POINTS_X - 1) || !WITHIN(ij.y, 0, GRID_MAX_POINTS_Y - 1))
SERIAL_ERROR_MSG(STR_ERR_MESH_XY);
else {
float &zval = bedlevel.z_values[ij.x][ij.y]; // Altering this Mesh Point
float &zval = bedlevel.z_values[ij.x][ij.y]; // Altering this Mesh Point
zval = hasN ? NAN : parser.value_linear_units() + (hasQ ? zval : 0); // N=NAN, Z=NEWVAL, or Q=ADDVAL
TERN_(EXTENSIBLE_UI, ExtUI::onMeshUpdate(ij.x, ij.y, zval)); // Ping ExtUI in case it's showing the mesh
TERN_(DWIN_LCD_PROUI, DWIN_MeshUpdate(ij.x, ij.y, zval));

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))
@@ -424,20 +424,10 @@ void GcodeSuite::G28() {
if (seenR && z_homing_height == 0) {
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("R0 = No Z raise");
}
else {
bool with_probe = ENABLED(HOMING_Z_WITH_PROBE);
// Raise above the current Z (which should be synced in the planner)
// The "height" for Z is a coordinate. But if Z is not trusted/homed make it relative.
if (seenR || !TERN(HOME_AFTER_DEACTIVATE, axis_is_trusted, axis_was_homed)(Z_AXIS)) {
z_homing_height += current_position.z;
with_probe = false;
}
if (may_skate) {
// Apply Z clearance before doing any lateral motion
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Raise Z before homing:");
do_z_clearance(z_homing_height, with_probe);
}
else if (z_homing_height && may_skate) {
// Raise Z before homing any other axes and z is not already high enough (never lower z)
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Raise Z before homing:");
do_z_clearance(z_homing_height);
}
// Init BLTouch ahead of any lateral motion, even if not homing with the probe
@@ -478,7 +468,7 @@ void GcodeSuite::G28() {
#endif
}
#if BOTH(FOAMCUTTER_XYUV, HAS_I_AXIS)
#if ALL(FOAMCUTTER_XYUV, HAS_I_AXIS)
// Home I (after X)
if (doI) homeaxis(I_AXIS);
#endif
@@ -489,7 +479,7 @@ void GcodeSuite::G28() {
homeaxis(Y_AXIS);
#endif
#if BOTH(FOAMCUTTER_XYUV, HAS_J_AXIS)
#if ALL(FOAMCUTTER_XYUV, HAS_J_AXIS)
// Home J (after Y)
if (doJ) homeaxis(J_AXIS);
#endif
@@ -503,7 +493,7 @@ void GcodeSuite::G28() {
// Home Z last if homing towards the bed
#if HAS_Z_AXIS && DISABLED(HOME_Z_FIRST)
if (doZ) {
#if EITHER(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
#if ANY(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
stepper.set_all_z_lock(false);
stepper.set_separate_multi_axis(false);
#endif

View File

@@ -97,12 +97,12 @@ 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);
}
/**
* - Print the delta settings
* - Print the delta settings
*/
static void print_calibration_settings(const bool end_stops, const bool tower_angles) {
SERIAL_ECHOPGM(".Height:", delta_height);
@@ -128,7 +128,7 @@ static void print_calibration_settings(const bool end_stops, const bool tower_an
}
/**
* - Print the probe results
* - Print the probe results
*/
static void print_calibration_results(const float z_pt[NPP + 1], const bool tower_points, const bool opposite_points) {
SERIAL_ECHOPGM(". ");
@@ -152,7 +152,7 @@ static void print_calibration_results(const float z_pt[NPP + 1], const bool towe
}
/**
* - Calculate the standard deviation from the zero plane
* - Calculate the standard deviation from the zero plane
*/
static float std_dev_points(float z_pt[NPP + 1], const bool _0p_cal, const bool _1p_cal, const bool _4p_cal, const bool _4p_opp) {
if (!_0p_cal) {
@@ -170,7 +170,7 @@ static float std_dev_points(float z_pt[NPP + 1], const bool _0p_cal, const bool
}
/**
* - Probe a point
* - Probe a point
*/
static float calibration_probe(const xy_pos_t &xy, const bool stow, const bool probe_at_offset) {
#if HAS_BED_PROBE
@@ -182,7 +182,7 @@ static float calibration_probe(const xy_pos_t &xy, const bool stow, const bool p
}
/**
* - Probe a grid
* - Probe a grid
*/
static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_points, const float dcr, const bool towers_set, const bool stow_after_each, const bool probe_at_offset) {
const bool _0p_calibration = probe_points == 0,
@@ -464,8 +464,8 @@ void GcodeSuite::G33() {
SERIAL_ECHOLNPGM("G33 Auto Calibrate");
// Report settings
PGM_P const checkingac = PSTR("Checking... AC");
SERIAL_ECHOPGM_P(checkingac);
FSTR_P const checkingac = F("Checking... AC");
SERIAL_ECHOF(checkingac);
SERIAL_ECHOPGM(" at radius:", dcr);
if (verbose_level == 0) SERIAL_ECHOPGM(" (DRY-RUN)");
SERIAL_EOL();

View File

@@ -39,6 +39,23 @@
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
#include "../../core/debug_out.h"
/**
* G34 - Align the ends of the X gantry. See https://youtu.be/3jAFQdTk8iw
*
* - The carriage moves to GANTRY_CALIBRATION_SAFE_POSITION, also called the “pounce” position.
* - If possible, the Z stepper current is reduced to the value specified by 'S'
* (or GANTRY_CALIBRATION_CURRENT) to prevent damage to steppers and other parts.
* The reduced current should be just high enough to move the Z axis when not blocked.
* - The Z axis is jogged past the Z limit, only as far as the specified Z distance
* (or GANTRY_CALIBRATION_EXTRA_HEIGHT) at the GANTRY_CALIBRATION_FEEDRATE.
* - The Z axis is moved back to the working area (also at GANTRY_CALIBRATION_FEEDRATE).
* - Stepper current is restored back to normal.
* - The machine is re-homed, according to GANTRY_CALIBRATION_COMMANDS_POST.
*
* Parameters:
* [S<mA>] - Current value to use for the raise move. (Default: GANTRY_CALIBRATION_CURRENT)
* [Z<linear>] - Extra distance past Z_MAX_POS to move the Z axis. (Default: GANTRY_CALIBRATION_EXTRA_HEIGHT)
*/
void GcodeSuite::G34() {
// Home before the alignment procedure

View File

@@ -22,7 +22,7 @@
#include "../../inc/MarlinConfigPre.h"
#if EITHER(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
#if ANY(Z_MULTI_ENDSTOPS, Z_STEPPER_AUTO_ALIGN)
#include "../../feature/z_stepper_align.h"
@@ -79,6 +79,7 @@
* R Flag to recalculate points based on current probe offsets
*/
void GcodeSuite::G34() {
DEBUG_SECTION(log_G34, "G34", DEBUGGING(LEVELING));
if (DEBUGGING(LEVELING)) log_machine_info();
@@ -108,6 +109,7 @@ void GcodeSuite::G34() {
}
#if ENABLED(Z_STEPPER_AUTO_ALIGN)
do { // break out on error
const int8_t z_auto_align_iterations = parser.intval('I', Z_STEPPER_ALIGN_ITERATIONS);
@@ -217,7 +219,7 @@ void GcodeSuite::G34() {
float z_measured_max = -100000.0f;
// Probe all positions (one per Z-Stepper)
LOOP_L_N(i, NUM_Z_STEPPERS) {
for (uint8_t i = 0; i < NUM_Z_STEPPERS; ++i) {
// iteration odd/even --> downward / upward stepper sequence
const uint8_t iprobe = (iteration & 1) ? NUM_Z_STEPPERS - 1 - i : i;
@@ -242,7 +244,7 @@ void GcodeSuite::G34() {
// Add height to each value, to provide a more useful target height for
// the next iteration of probing. This allows adjustments to be made away from the bed.
z_measured[iprobe] = z_probed_height + Z_CLEARANCE_BETWEEN_PROBES;
z_measured[iprobe] = z_probed_height + (Z_CLEARANCE_BETWEEN_PROBES);
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> Z", iprobe + 1, " measured position is ", z_measured[iprobe]);
@@ -272,14 +274,14 @@ void GcodeSuite::G34() {
// This allows the actual adjustment logic to be shared by both algorithms.
linear_fit_data lfd;
incremental_LSF_reset(&lfd);
LOOP_L_N(i, NUM_Z_STEPPERS) {
for (uint8_t i = 0; i < NUM_Z_STEPPERS; ++i) {
SERIAL_ECHOLNPGM("PROBEPT_", i, ": ", z_measured[i]);
incremental_LSF(&lfd, z_stepper_align.xy[i], z_measured[i]);
}
finish_incremental_LSF(&lfd);
z_measured_min = 100000.0f;
LOOP_L_N(i, NUM_Z_STEPPERS) {
for (uint8_t i = 0; i < NUM_Z_STEPPERS; ++i) {
z_measured[i] = -(lfd.A * z_stepper_align.stepper_xy[i].x + lfd.B * z_stepper_align.stepper_xy[i].y + lfd.D);
z_measured_min = _MIN(z_measured_min, z_measured[i]);
}
@@ -347,12 +349,12 @@ void GcodeSuite::G34() {
// Calculate mean value as a reference
float z_measured_mean = 0.0f;
LOOP_L_N(zstepper, NUM_Z_STEPPERS) z_measured_mean += z_measured[zstepper];
for (uint8_t zstepper = 0; zstepper < NUM_Z_STEPPERS; ++zstepper) z_measured_mean += z_measured[zstepper];
z_measured_mean /= NUM_Z_STEPPERS;
// Calculate the sum of the absolute deviations from the mean value
float z_align_level_indicator = 0.0f;
LOOP_L_N(zstepper, NUM_Z_STEPPERS)
for (uint8_t zstepper = 0; zstepper < NUM_Z_STEPPERS; ++zstepper)
z_align_level_indicator += ABS(z_measured[zstepper] - z_measured_mean);
// If it's getting worse, stop and throw an error
@@ -367,7 +369,7 @@ void GcodeSuite::G34() {
bool success_break = true;
// Correct the individual stepper offsets
LOOP_L_N(zstepper, NUM_Z_STEPPERS) {
for (uint8_t zstepper = 0; zstepper < NUM_Z_STEPPERS; ++zstepper) {
// Calculate current stepper move
float z_align_move = z_measured[zstepper] - z_measured_min;
const float z_align_abs = ABS(z_align_move);
@@ -444,14 +446,14 @@ void GcodeSuite::G34() {
// Use the probed height from the last iteration to determine the Z height.
// z_measured_min is used, because all steppers are aligned to z_measured_min.
// Ideally, this would be equal to the 'z_probe * 0.5f' which was added earlier.
current_position.z -= z_measured_min - (float)Z_CLEARANCE_BETWEEN_PROBES;
current_position.z -= z_measured_min - float(Z_CLEARANCE_BETWEEN_PROBES);
sync_plan_position();
#endif
// Restore the active tool after homing
TERN_(HAS_MULTI_HOTEND, tool_change(old_tool_index, DISABLED(PARKING_EXTRUDER))); // Fetch previous tool for parking extruder
#if BOTH(HAS_LEVELING, RESTORE_LEVELING_AFTER_G34)
#if ALL(HAS_LEVELING, RESTORE_LEVELING_AFTER_G34)
set_bed_leveling_enabled(leveling_was_active);
#endif
@@ -546,7 +548,7 @@ void GcodeSuite::M422() {
void GcodeSuite::M422_report(const bool forReplay/*=true*/) {
report_heading(forReplay, F(STR_Z_AUTO_ALIGN));
LOOP_L_N(i, NUM_Z_STEPPERS) {
for (uint8_t i = 0; i < NUM_Z_STEPPERS; ++i) {
report_echo_start(forReplay);
SERIAL_ECHOLNPGM_P(
PSTR(" M422 S"), i + 1,
@@ -555,7 +557,7 @@ void GcodeSuite::M422_report(const bool forReplay/*=true*/) {
);
}
#if HAS_Z_STEPPER_ALIGN_STEPPER_XY
LOOP_L_N(i, NUM_Z_STEPPERS) {
for (uint8_t i = 0; i < NUM_Z_STEPPERS; ++i) {
report_echo_start(forReplay);
SERIAL_ECHOLNPGM_P(
PSTR(" M422 W"), i + 1,

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 BOTH(CALIBRATION_MEASURE_LEFT, CALIBRATION_MEASURE_RIGHT)
#if ALL(HAS_X_AXIS, CALIBRATION_MEASURE_LEFT, CALIBRATION_MEASURE_RIGHT)
#define HAS_X_CENTER 1
#endif
#if ALL(HAS_Y_AXIS, CALIBRATION_MEASURE_FRONT, CALIBRATION_MEASURE_BACK)
@@ -171,7 +174,7 @@ inline void park_above_object(measurements_t &m, const float uncertainty) {
#if HAS_HOTEND_OFFSET
inline void normalize_hotend_offsets() {
LOOP_S_L_N(e, 1, HOTENDS)
for (uint8_t e = 1; e < HOTENDS; ++e)
hotend_offset[e] -= hotend_offset[0];
hotend_offset[0].reset();
}
@@ -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,14 +398,16 @@ 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 ENABLED(CALIBRATION_MEASURE_LEFT)
SERIAL_ECHOLNPGM(" Left: ", m.obj_side[LEFT]);
#endif
#if ENABLED(CALIBRATION_MEASURE_RIGHT)
SERIAL_ECHOLNPGM(" Right: ", m.obj_side[RIGHT]);
#if HAS_X_AXIS
#if ENABLED(CALIBRATION_MEASURE_LEFT)
SERIAL_ECHOLNPGM(" Left: ", m.obj_side[LEFT]);
#endif
#if ENABLED(CALIBRATION_MEASURE_RIGHT)
SERIAL_ECHOLNPGM(" Right: ", m.obj_side[RIGHT]);
#endif
#endif
#if HAS_Y_AXIS
#if ENABLED(CALIBRATION_MEASURE_FRONT)
@@ -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)
@@ -616,7 +621,7 @@ inline void probe_sides(measurements_t &m, const float uncertainty) {
// This function requires normalize_hotend_offsets() to be called
//
inline void report_hotend_offsets() {
LOOP_S_L_N(e, 1, HOTENDS)
for (uint8_t e = 1; e < HOTENDS; ++e)
SERIAL_ECHOLNPGM_P(PSTR("T"), e, PSTR(" Hotend Offset X"), hotend_offset[e].x, SP_Y_STR, hotend_offset[e].y, SP_Z_STR, hotend_offset[e].z);
}
#endif

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"
@@ -82,7 +81,7 @@
* - `P` - Run probe temperature calibration.
*/
#if BOTH(PTC_PROBE, PTC_BED)
#if ALL(PTC_PROBE, PTC_BED)
static void say_waiting_for() { SERIAL_ECHOPGM("Waiting for "); }
static void say_waiting_for_probe_heating() { say_waiting_for(); SERIAL_ECHOLNPGM("probe heating."); }
@@ -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);
@@ -258,7 +256,7 @@
say_waiting_for_probe_heating();
SERIAL_ECHOLNPGM(" Bed:", target_bed, " Probe:", target_probe);
const millis_t probe_timeout_ms = millis() + SEC_TO_MS(900UL);
const millis_t probe_timeout_ms = millis() + MIN_TO_MS(15);
while (thermalManager.degProbe() < target_probe) {
if (report_temps(next_temp_report, probe_timeout_ms)) {
SERIAL_ECHOLNPGM("!Probe heating timed out.");

View File

@@ -60,7 +60,7 @@
#define TEST_BYTE ((char) 0xE5)
#if EITHER(__AVR__, IS_32BIT_TEENSY)
#if ANY(__AVR__, IS_32BIT_TEENSY)
extern char __bss_end;
char *end_bss = &__bss_end,
@@ -163,14 +163,14 @@ inline int32_t count_test_bytes(const char * const start_free_memory) {
while (start_free_memory < end_free_memory) {
print_hex_address(start_free_memory); // Print the address
SERIAL_CHAR(':');
LOOP_L_N(i, 16) { // and 16 data bytes
for (uint8_t i = 0; i < 16; ++i) { // and 16 data bytes
if (i == 8) SERIAL_CHAR('-');
print_hex_byte(start_free_memory[i]);
SERIAL_CHAR(' ');
}
serial_delay(25);
SERIAL_CHAR('|'); // Point out non test bytes
LOOP_L_N(i, 16) {
for (uint8_t i = 0; i < 16; ++i) {
char ccc = (char)start_free_memory[i]; // cast to char before automatically casting to char on assignment, in case the compiler is broken
ccc = (ccc == TEST_BYTE) ? ' ' : '?';
SERIAL_CHAR(ccc);

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,17 +112,19 @@ void GcodeSuite::M425_report(const bool forReplay/*=true*/) {
#ifdef BACKLASH_SMOOTHING_MM
, PSTR(" S"), LINEAR_UNIT(backlash.get_smoothing_mm())
#endif
, LIST_N(DOUBLE(NUM_AXES),
SP_X_STR, LINEAR_UNIT(backlash.get_distance_mm(X_AXIS)),
SP_Y_STR, LINEAR_UNIT(backlash.get_distance_mm(Y_AXIS)),
SP_Z_STR, LINEAR_UNIT(backlash.get_distance_mm(Z_AXIS)),
SP_I_STR, I_AXIS_UNIT(backlash.get_distance_mm(I_AXIS)),
SP_J_STR, J_AXIS_UNIT(backlash.get_distance_mm(J_AXIS)),
SP_K_STR, K_AXIS_UNIT(backlash.get_distance_mm(K_AXIS)),
SP_U_STR, U_AXIS_UNIT(backlash.get_distance_mm(U_AXIS)),
SP_V_STR, V_AXIS_UNIT(backlash.get_distance_mm(V_AXIS)),
SP_W_STR, W_AXIS_UNIT(backlash.get_distance_mm(W_AXIS))
)
#if NUM_AXES
, LIST_N(DOUBLE(NUM_AXES),
SP_X_STR, LINEAR_UNIT(backlash.get_distance_mm(X_AXIS)),
SP_Y_STR, LINEAR_UNIT(backlash.get_distance_mm(Y_AXIS)),
SP_Z_STR, LINEAR_UNIT(backlash.get_distance_mm(Z_AXIS)),
SP_I_STR, I_AXIS_UNIT(backlash.get_distance_mm(I_AXIS)),
SP_J_STR, J_AXIS_UNIT(backlash.get_distance_mm(J_AXIS)),
SP_K_STR, K_AXIS_UNIT(backlash.get_distance_mm(K_AXIS)),
SP_U_STR, U_AXIS_UNIT(backlash.get_distance_mm(U_AXIS)),
SP_V_STR, V_AXIS_UNIT(backlash.get_distance_mm(V_AXIS)),
SP_W_STR, W_AXIS_UNIT(backlash.get_distance_mm(W_AXIS))
)
#endif
);
}

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...");
@@ -148,7 +148,7 @@ void GcodeSuite::M48() {
float sample_sum = 0.0;
LOOP_L_N(n, n_samples) {
for (uint8_t n = 0; n < n_samples; ++n) {
#if HAS_STATUS_MESSAGE
// Display M48 progress in the status bar
ui.status_printf(0, F(S_FMT ": %d/%d"), GET_TEXT(MSG_M48_POINT), int(n + 1), int(n_samples));
@@ -175,7 +175,7 @@ void GcodeSuite::M48() {
}
// Move from leg to leg in rapid succession
LOOP_L_N(l, n_legs - 1) {
for (uint8_t l = 0; l < n_legs - 1; ++l) {
// Move some distance around the perimeter
float delta_angle;
@@ -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);
@@ -243,7 +243,7 @@ void GcodeSuite::M48() {
// Calculate the standard deviation so far.
// The value after the last sample will be the final output.
float dev_sum = 0.0;
LOOP_LE_N(j, n) dev_sum += sq(sample_set[j] - mean);
for (uint8_t j = 0; j <= n; ++j) dev_sum += sq(sample_set[j] - mean);
sigma = SQRT(dev_sum / (n + 1));
if (verbose_level > 1) {

View File

@@ -22,7 +22,7 @@
#include "../../inc/MarlinConfig.h"
#if ENABLED(DELTA) || HAS_EXTRA_ENDSTOPS
#if ANY(DELTA, HAS_EXTRA_ENDSTOPS)
#include "../gcode.h"
@@ -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,24 +143,32 @@ void GcodeSuite::M201() {
void GcodeSuite::M201_report(const bool forReplay/*=true*/) {
report_heading_etc(forReplay, F(STR_MAX_ACCELERATION));
SERIAL_ECHOLNPGM_P(
LIST_N(DOUBLE(NUM_AXES),
PSTR(" M201 X"), LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[X_AXIS]),
SP_Y_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Y_AXIS]),
SP_Z_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Z_AXIS]),
SP_I_STR, I_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[I_AXIS]),
SP_J_STR, J_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[J_AXIS]),
SP_K_STR, K_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[K_AXIS]),
SP_U_STR, U_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[U_AXIS]),
SP_V_STR, V_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[V_AXIS]),
SP_W_STR, W_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[W_AXIS])
)
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
, SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_acceleration_mm_per_s2[E_AXIS])
#endif
);
#if NUM_AXES
SERIAL_ECHOPGM_P(
LIST_N(DOUBLE(NUM_AXES),
PSTR(" M201 X"), LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[X_AXIS]),
SP_Y_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Y_AXIS]),
SP_Z_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Z_AXIS]),
SP_I_STR, I_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[I_AXIS]),
SP_J_STR, J_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[J_AXIS]),
SP_K_STR, K_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[K_AXIS]),
SP_U_STR, U_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[U_AXIS]),
SP_V_STR, V_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[V_AXIS]),
SP_W_STR, W_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[W_AXIS])
)
);
#endif
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
SERIAL_ECHOPGM_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_acceleration_mm_per_s2[E_AXIS]));
#endif
#if NUM_AXES || (HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS))
SERIAL_EOL();
#endif
#if ENABLED(DISTINCT_E_FACTORS)
LOOP_L_N(i, E_STEPPERS) {
for (uint8_t i = 0; i < E_STEPPERS; ++i) {
report_echo_start(forReplay);
SERIAL_ECHOLNPGM_P(
PSTR(" M201 T"), i
@@ -191,24 +199,32 @@ void GcodeSuite::M203() {
void GcodeSuite::M203_report(const bool forReplay/*=true*/) {
report_heading_etc(forReplay, F(STR_MAX_FEEDRATES));
SERIAL_ECHOLNPGM_P(
LIST_N(DOUBLE(NUM_AXES),
PSTR(" M203 X"), LINEAR_UNIT(planner.settings.max_feedrate_mm_s[X_AXIS]),
SP_Y_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Y_AXIS]),
SP_Z_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Z_AXIS]),
SP_I_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[I_AXIS]),
SP_J_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[J_AXIS]),
SP_K_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[K_AXIS]),
SP_U_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[U_AXIS]),
SP_V_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[V_AXIS]),
SP_W_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[W_AXIS])
)
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
, SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_feedrate_mm_s[E_AXIS])
#endif
);
#if NUM_AXES
SERIAL_ECHOPGM_P(
LIST_N(DOUBLE(NUM_AXES),
PSTR(" M203 X"), LINEAR_UNIT(planner.settings.max_feedrate_mm_s[X_AXIS]),
SP_Y_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Y_AXIS]),
SP_Z_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Z_AXIS]),
SP_I_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[I_AXIS]),
SP_J_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[J_AXIS]),
SP_K_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[K_AXIS]),
SP_U_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[U_AXIS]),
SP_V_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[V_AXIS]),
SP_W_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[W_AXIS])
)
);
#endif
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
SERIAL_ECHOPGM_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_feedrate_mm_s[E_AXIS]));
#endif
#if NUM_AXES || (HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS))
SERIAL_EOL();
#endif
#if ENABLED(DISTINCT_E_FACTORS)
LOOP_L_N(i, E_STEPPERS) {
for (uint8_t i = 0; i < E_STEPPERS; ++i) {
if (!forReplay) SERIAL_ECHO_START();
SERIAL_ECHOLNPGM_P(
PSTR(" M203 T"), i
@@ -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 (parser.seenval('X')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.x = constrain(v, X_MIN_POS, X_MAX_POS); }
#if HAS_X_AXIS
if (parser.seenval('X')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.x = constrain(v, X_MIN_POS, X_MAX_POS); }
#endif
#if HAS_Y_AXIS
if (parser.seenval('Y')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.y = constrain(v, Y_MIN_POS, Y_MAX_POS); }
#endif
@@ -183,25 +185,27 @@ void GcodeSuite::M217_report(const bool forReplay/*=true*/) {
#endif
#if ENABLED(TOOLCHANGE_PARK)
{
SERIAL_ECHOPGM(" W", LINEAR_UNIT(toolchange_settings.enable_park));
SERIAL_ECHOPGM_P(
SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x)
#if HAS_Y_AXIS
, SP_Y_STR, LINEAR_UNIT(toolchange_settings.change_point.y)
#endif
#if SECONDARY_AXES >= 1
, LIST_N(DOUBLE(SECONDARY_AXES)
, SP_I_STR, I_AXIS_UNIT(toolchange_settings.change_point.i)
, SP_J_STR, J_AXIS_UNIT(toolchange_settings.change_point.j)
, SP_K_STR, K_AXIS_UNIT(toolchange_settings.change_point.k)
, SP_C_STR, U_AXIS_UNIT(toolchange_settings.change_point.u)
, PSTR(" H"), V_AXIS_UNIT(toolchange_settings.change_point.v)
, PSTR(" O"), W_AXIS_UNIT(toolchange_settings.change_point.w)
)
#endif
);
}
#if NUM_AXES
{
SERIAL_ECHOPGM_P(
SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x)
#if HAS_Y_AXIS
, SP_Y_STR, LINEAR_UNIT(toolchange_settings.change_point.y)
#endif
#if SECONDARY_AXES >= 1
, LIST_N(DOUBLE(SECONDARY_AXES)
, SP_I_STR, I_AXIS_UNIT(toolchange_settings.change_point.i)
, SP_J_STR, J_AXIS_UNIT(toolchange_settings.change_point.j)
, SP_K_STR, K_AXIS_UNIT(toolchange_settings.change_point.k)
, SP_C_STR, U_AXIS_UNIT(toolchange_settings.change_point.u)
, PSTR(" H"), V_AXIS_UNIT(toolchange_settings.change_point.v)
, PSTR(" O"), W_AXIS_UNIT(toolchange_settings.change_point.w)
)
#endif
);
}
#endif
#endif
#if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)

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 (parser.seenval('X')) hotend_offset[target_extruder].x = parser.value_linear_units();
if (parser.seenval('Y')) hotend_offset[target_extruder].y = parser.value_linear_units();
if (parser.seenval('Z')) hotend_offset[target_extruder].z = parser.value_linear_units();
#if HAS_X_AXIS
if (parser.seenval('X')) hotend_offset[target_extruder].x = parser.value_linear_units();
#endif
#if HAS_Y_AXIS
if (parser.seenval('Y')) hotend_offset[target_extruder].y = parser.value_linear_units();
#endif
#if HAS_Z_AXIS
if (parser.seenval('Z')) hotend_offset[target_extruder].z = parser.value_linear_units();
#endif
#if ENABLED(DELTA)
if (target_extruder == active_extruder)
@@ -58,7 +64,7 @@ void GcodeSuite::M218() {
void GcodeSuite::M218_report(const bool forReplay/*=true*/) {
report_heading_etc(forReplay, F(STR_HOTEND_OFFSETS));
LOOP_S_L_N(e, 1, HOTENDS) {
for (uint8_t e = 1; e < HOTENDS; ++e) {
report_echo_start(forReplay);
SERIAL_ECHOPGM_P(
PSTR(" M218 T"), e,

View File

@@ -56,7 +56,7 @@ void GcodeSuite::M281() {
void GcodeSuite::M281_report(const bool forReplay/*=true*/) {
report_heading_etc(forReplay, F(STR_SERVO_ANGLES));
LOOP_L_N(i, NUM_SERVOS) {
for (uint8_t i = 0; i < NUM_SERVOS; ++i) {
switch (i) {
default: break;
#if ENABLED(SWITCHING_EXTRUDER)
@@ -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

@@ -69,7 +69,7 @@ void GcodeSuite::M305() {
SERIAL_ECHO_MSG("!Invalid Steinhart-Hart C coeff. (-0.01 < C < +0.01)");
} // If not setting then report parameters
else if (t_index < 0) { // ...all user thermistors
LOOP_L_N(i, USER_THERMISTORS)
for (uint8_t i = 0; i < USER_THERMISTORS; ++i)
thermalManager.M305_report(i);
}
else // ...one user thermistor

View File

@@ -25,7 +25,7 @@
#if ENABLED(PINS_DEBUGGING)
#include "../gcode.h"
#include "../../MarlinCore.h" // for pin_is_protected
#include "../../MarlinCore.h" // for pin_is_protected, wait_for_user
#include "../../pins/pinsDebug.h"
#include "../../module/endstops.h"
@@ -61,7 +61,7 @@ inline void toggle_pins() {
end = PARSED_PIN_INDEX('L', NUM_DIGITAL_PINS - 1),
wait = parser.intval('W', 500);
LOOP_S_LE_N(i, start, end) {
for (uint8_t i = start; i <= end; ++i) {
pin_t pin = GET_PIN_MAP_PIN_M43(i);
if (!VALID_PIN(pin)) continue;
if (M43_NEVER_TOUCH(i) || (!ignore_protection && pin_is_protected(pin))) {
@@ -195,31 +195,30 @@ inline void servo_probe_test() {
if (!blt) {
// DEPLOY and STOW 4 times and see if the signal follows
// Then it is a mechanical switch
uint8_t i = 0;
SERIAL_ECHOLNPGM(". Deploy & stow 4 times");
do {
for (uint8_t i = 0; i < 4; ++i) {
servo[probe_index].move(servo_angles[Z_PROBE_SERVO_NR][0]); // Deploy
safe_delay(500);
deploy_state = READ(PROBE_TEST_PIN);
servo[probe_index].move(servo_angles[Z_PROBE_SERVO_NR][1]); // Stow
safe_delay(500);
stow_state = READ(PROBE_TEST_PIN);
} while (++i < 4);
}
if (probe_inverting != deploy_state) SERIAL_ECHOLNPGM("WARNING: INVERTING setting probably backwards.");
if (deploy_state != stow_state) {
SERIAL_ECHOLNPGM("= Mechanical Switch detected");
if (deploy_state) {
SERIAL_ECHOLNPGM(" DEPLOYED state: HIGH (logic 1)",
" STOWED (triggered) state: LOW (logic 0)");
SERIAL_ECHOLNPGM(". DEPLOYED state: HIGH (logic 1)\n"
". STOWED (triggered) state: LOW (logic 0)");
}
else {
SERIAL_ECHOLNPGM(" DEPLOYED state: LOW (logic 0)",
" STOWED (triggered) state: HIGH (logic 1)");
SERIAL_ECHOLNPGM(". DEPLOYED state: LOW (logic 0)\n"
". STOWED (triggered) state: HIGH (logic 1)");
}
#if ENABLED(BLTOUCH)
SERIAL_ECHOLNPGM("FAIL: BLTOUCH enabled - Set up this device as a Servo Probe with INVERTING set to 'true'.");
SERIAL_ECHOLNPGM("FAIL: Can't enable BLTOUCH. Check your settings.");
#endif
return;
}
@@ -336,7 +335,7 @@ void GcodeSuite::M43() {
const uint8_t pin_count = last_pin - first_pin + 1;
uint8_t pin_state[pin_count];
bool can_watch = false;
LOOP_S_LE_N(i, first_pin, last_pin) {
for (uint8_t i = first_pin; i <= last_pin; ++i) {
pin_t pin = GET_PIN_MAP_PIN_M43(i);
if (!VALID_PIN(pin)) continue;
if (M43_NEVER_TOUCH(i) || (!ignore_protection && pin_is_protected(pin))) continue;
@@ -379,7 +378,7 @@ void GcodeSuite::M43() {
#endif
for (;;) {
LOOP_S_LE_N(i, first_pin, last_pin) {
for (uint8_t i = first_pin; i <= last_pin; ++i) {
const pin_t pin = GET_PIN_MAP_PIN_M43(i);
if (!VALID_PIN(pin)) continue;
if (M43_NEVER_TOUCH(i) || (!ignore_protection && pin_is_protected(pin))) continue;
@@ -408,7 +407,7 @@ void GcodeSuite::M43() {
}
else {
// Report current state of selected pin(s)
LOOP_S_LE_N(i, first_pin, last_pin) {
for (uint8_t i = first_pin; i <= last_pin; ++i) {
const pin_t pin = GET_PIN_MAP_PIN_M43(i);
if (VALID_PIN(pin)) report_pin_state_extended(pin, ignore_protection, true);
}

View File

@@ -54,7 +54,7 @@
// b3 b2 b1 b0 ~b0 ... lo bits, NOT last bit
//
void M672_send(uint8_t b) { // bit rate requirement: 1kHz +/- 30%
LOOP_L_N(bits, 14) {
for (uint8_t bits = 0; bits < 14; ++bits) {
switch (bits) {
default: { OUT_WRITE(SMART_EFFECTOR_MOD_PIN, !!(b & 0x80)); b <<= 1; break; } // send bit, shift next into place
case 7:

View File

@@ -37,6 +37,7 @@
* H<microsteps> - Specify micro-steps to use. Best guess if not supplied.
* L<linear> - Desired layer height in current units. Nearest good heights are shown.
*/
void GcodeSuite::M92() {
const int8_t target_extruder = get_target_extruder_from_command();
@@ -92,24 +93,30 @@ void GcodeSuite::M92() {
void GcodeSuite::M92_report(const bool forReplay/*=true*/, const int8_t e/*=-1*/) {
report_heading_etc(forReplay, F(STR_STEPS_PER_UNIT));
SERIAL_ECHOPGM_P(LIST_N(DOUBLE(NUM_AXES),
PSTR(" M92 X"), LINEAR_UNIT(planner.settings.axis_steps_per_mm[X_AXIS]),
SP_Y_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Y_AXIS]),
SP_Z_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Z_AXIS]),
SP_I_STR, I_AXIS_UNIT(planner.settings.axis_steps_per_mm[I_AXIS]),
SP_J_STR, J_AXIS_UNIT(planner.settings.axis_steps_per_mm[J_AXIS]),
SP_K_STR, K_AXIS_UNIT(planner.settings.axis_steps_per_mm[K_AXIS]),
SP_U_STR, U_AXIS_UNIT(planner.settings.axis_steps_per_mm[U_AXIS]),
SP_V_STR, V_AXIS_UNIT(planner.settings.axis_steps_per_mm[V_AXIS]),
SP_W_STR, W_AXIS_UNIT(planner.settings.axis_steps_per_mm[W_AXIS])
));
#if NUM_AXES
#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]),
SP_Z_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Z_AXIS]),
SP_I_STR, I_AXIS_UNIT(planner.settings.axis_steps_per_mm[I_AXIS]),
SP_J_STR, J_AXIS_UNIT(planner.settings.axis_steps_per_mm[J_AXIS]),
SP_K_STR, K_AXIS_UNIT(planner.settings.axis_steps_per_mm[K_AXIS]),
SP_U_STR, U_AXIS_UNIT(planner.settings.axis_steps_per_mm[U_AXIS]),
SP_V_STR, V_AXIS_UNIT(planner.settings.axis_steps_per_mm[V_AXIS]),
SP_W_STR, W_AXIS_UNIT(planner.settings.axis_steps_per_mm[W_AXIS])
));
#endif
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
#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)
LOOP_L_N(i, E_STEPPERS) {
for (uint8_t i = 0; i < E_STEPPERS; ++i) {
if (e >= 0 && i != e) continue;
report_echo_start(forReplay);
SERIAL_ECHOLNPGM_P(

View File

@@ -46,7 +46,7 @@ void GcodeSuite::M111() {
SERIAL_ECHOPGM(STR_DEBUG_PREFIX);
if (marlin_debug_flags) {
uint8_t comma = 0;
LOOP_L_N(i, COUNT(debug_strings)) {
for (uint8_t i = 0; i < COUNT(debug_strings); ++i) {
if (TEST(marlin_debug_flags, i)) {
if (comma++) SERIAL_CHAR(',');
SERIAL_ECHOPGM_P((PGM_P)pgm_read_ptr(&debug_strings[i]));
@@ -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,17 +48,19 @@ inline stepper_flags_t selected_axis_bits() {
selected.bits = e_axis_mask;
}
#endif
selected.bits |= NUM_AXIS_GANG(
(parser.seen_test('X') << X_AXIS),
| (parser.seen_test('Y') << Y_AXIS),
| (parser.seen_test('Z') << Z_AXIS),
| (parser.seen_test(AXIS4_NAME) << I_AXIS),
| (parser.seen_test(AXIS5_NAME) << J_AXIS),
| (parser.seen_test(AXIS6_NAME) << K_AXIS),
| (parser.seen_test(AXIS7_NAME) << U_AXIS),
| (parser.seen_test(AXIS8_NAME) << V_AXIS),
| (parser.seen_test(AXIS9_NAME) << W_AXIS)
);
#if NUM_AXES
selected.bits |= NUM_AXIS_GANG(
(parser.seen_test('X') << X_AXIS),
| (parser.seen_test('Y') << Y_AXIS),
| (parser.seen_test('Z') << Z_AXIS),
| (parser.seen_test(AXIS4_NAME) << I_AXIS),
| (parser.seen_test(AXIS5_NAME) << J_AXIS),
| (parser.seen_test(AXIS6_NAME) << K_AXIS),
| (parser.seen_test(AXIS7_NAME) << U_AXIS),
| (parser.seen_test(AXIS8_NAME) << V_AXIS),
| (parser.seen_test(AXIS9_NAME) << W_AXIS)
);
#endif
return selected;
}
@@ -71,7 +73,7 @@ void do_enable(const stepper_flags_t to_enable) {
if (!shall_enable) return; // All specified axes already enabled?
ena_mask_t also_enabled = 0; // Track steppers enabled due to overlap
ena_mask_t also_enabled = 0; // Track steppers enabled due to overlap
// Enable all flagged axes
LOOP_NUM_AXES(a) {
@@ -212,7 +214,7 @@ void try_to_disable(const stepper_flags_t to_disable) {
void GcodeSuite::M18_M84() {
if (parser.seenval('S')) {
reset_stepper_timeout();
#if HAS_DISABLE_INACTIVE_AXIS
#if HAS_DISABLE_IDLE_AXES
const millis_t ms = parser.value_millis_from_seconds();
#if LASER_SAFETY_TIMEOUT_MS > 0
if (ms && ms <= LASER_SAFETY_TIMEOUT_MS) {

View File

@@ -32,21 +32,18 @@
* Laser:
* M3 - Laser ON/Power (Ramped power)
* M4 - Laser ON/Power (Ramped power)
* M5 - Set power output to 0 (leaving inline mode unchanged).
*
* M3I - Enable continuous inline power to be processed by the planner, with power
* calculated and set in the planner blocks, processed inline during stepping.
* Within inline mode M3 S-Values will set the power for the next moves e.g. G1 X10 Y10 powers on with the last S-Value.
* In inline mode M3 S-Values will set the power for the next moves.
* (e.g., G1 X10 Y10 powers on with the last S-Value.)
* M3I must be set before using planner-synced M3 inline S-Values (LASER_POWER_SYNC).
*
* M4I - Set dynamic mode which calculates laser power OCR based on the current feedrate.
*
* M5I - Clear inline mode and set power to 0.
*
* Spindle:
* M3 - Spindle ON (Clockwise)
* M4 - Spindle ON (Counter-clockwise)
* M5 - Spindle OFF
*
* Parameters:
* S<power> - Set power. S0 will turn the spindle/laser off.
@@ -92,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
@@ -138,6 +131,13 @@ void GcodeSuite::M3_M4(const bool is_M4) {
/**
* M5 - Cutter OFF (when moves are complete)
*
* Laser:
* M5 - Set power output to 0 (leaving inline mode unchanged).
* M5I - Clear inline mode and set power to 0.
*
* Spindle:
* M5 - Spindle OFF
*/
void GcodeSuite::M5() {
planner.synchronize();

View File

@@ -22,7 +22,7 @@
#include "../../inc/MarlinConfig.h"
#if EITHER(EXT_SOLENOID, MANUAL_SOLENOID_CONTROL)
#if ANY(EXT_SOLENOID, MANUAL_SOLENOID_CONTROL)
#include "../gcode.h"
#include "../../feature/solenoid.h"

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,12 +37,14 @@
#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);
}
/**
* M42: Change pin status via GCode
* M42: Change pin status via G-Code
*
* P<pin> Pin number (LED if omitted)
* For LPC1768 specify pin P1_02 as M42 P102,
@@ -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));
@@ -86,30 +88,8 @@ void GcodeSuite::M42() {
#if HAS_FAN
switch (pin) {
#if HAS_FAN0
case FAN0_PIN: thermalManager.fan_speed[0] = pin_status; return;
#endif
#if HAS_FAN1
case FAN1_PIN: thermalManager.fan_speed[1] = pin_status; return;
#endif
#if HAS_FAN2
case FAN2_PIN: thermalManager.fan_speed[2] = pin_status; return;
#endif
#if HAS_FAN3
case FAN3_PIN: thermalManager.fan_speed[3] = pin_status; return;
#endif
#if HAS_FAN4
case FAN4_PIN: thermalManager.fan_speed[4] = pin_status; return;
#endif
#if HAS_FAN5
case FAN5_PIN: thermalManager.fan_speed[5] = pin_status; return;
#endif
#if HAS_FAN6
case FAN6_PIN: thermalManager.fan_speed[6] = pin_status; return;
#endif
#if HAS_FAN7
case FAN7_PIN: thermalManager.fan_speed[7] = pin_status; return;
#endif
#define _CASE(N) case FAN##N##_PIN: thermalManager.fan_speed[N] = pin_status; return;
REPEAT(FAN_COUNT, _CASE)
}
#endif
@@ -119,7 +99,7 @@ void GcodeSuite::M42() {
}
// An OUTPUT_OPEN_DRAIN should not be changed to normal OUTPUT (STM32)
// Use M42 Px M1/5 S0/1 to set the output type and then set value
// Use M42 Px T1/5 S0/1 to set the output type and then set value
#ifndef OUTPUT_OPEN_DRAIN
pinMode(pin, OUTPUT);
#endif

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

@@ -37,7 +37,7 @@
}
#endif
#if EITHER(COOLANT_FLOOD, AIR_ASSIST)
#if ANY(COOLANT_FLOOD, AIR_ASSIST)
#if ENABLED(AIR_ASSIST)
#include "../../feature/spindle_laser.h"

View File

@@ -91,7 +91,7 @@ void GcodeSuite::M81() {
print_job_timer.stop();
#if BOTH(HAS_FAN, PROBING_FANS_OFF)
#if ALL(HAS_FAN, PROBING_FANS_OFF)
thermalManager.fans_paused = false;
ZERO(thermalManager.saved_fan_speed);
#endif

View File

@@ -22,7 +22,7 @@
#include "../../inc/MarlinConfig.h"
#if ALL(SPI_FLASH, SDSUPPORT, 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 && SDSUPPORT && MARLIN_DEV_MODE
#endif // SPI_FLASH_BACKUP

View File

@@ -23,7 +23,7 @@
#include "../gcode.h"
#include "../../module/tool_change.h"
#if EITHER(HAS_MULTI_EXTRUDER, DEBUG_LEVELING_FEATURE)
#if ANY(HAS_MULTI_EXTRUDER, DEBUG_LEVELING_FEATURE)
#include "../../module/motion.h"
#endif
@@ -41,13 +41,21 @@
* S1 Don't move the tool in XY after change
*
* For PRUSA_MMU2(S) and EXTENDABLE_EMU_MMU2(S)
* T[n] Gcode to extrude at least 38.10 mm at feedrate 19.02 mm/s must follow immediately to load to extruder wheels.
* T? Gcode to extrude shouldn't have to follow. Load to extruder wheels is done automatically.
* T[n] G-code to extrude at least 38.10 mm at feedrate 19.02 mm/s must follow immediately to load to extruder wheels.
* T? G-code to extrude shouldn't have to follow. Load to extruder wheels is done automatically.
* Tx Same as T?, but nozzle doesn't have to be preheated. Tc requires a preheated nozzle to finish filament load.
* Tc Load to nozzle after filament was prepared by Tc and nozzle is already heated.
*/
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

@@ -120,8 +120,7 @@ void GcodeSuite::M900() {
EXTRUDER_LOOP() {
const bool slot = TEST(lin_adv_slot, e);
SERIAL_ECHOLNPGM("Advance T", e, " S", slot, " K", planner.extruder_advance_K[e],
"(S", !slot, " K", other_extruder_advance_K[e], ")");
SERIAL_EOL();
"(S", !slot, " K", other_extruder_advance_K[e], ")");
}
#endif

View File

@@ -84,7 +84,7 @@
inline void spin_photo_pin() {
static constexpr uint32_t sequence[] = PHOTO_PULSES_US;
LOOP_L_N(i, COUNT(sequence))
for (uint8_t i = 0; i < COUNT(sequence); ++i)
pulse_photo_pin(sequence[i], !(i & 1));
}
@@ -111,7 +111,7 @@
* B - Y offset to the return position
* F - Override the XY movement feedrate
* R - Retract/recover length (current units)
* S - Retract/recover feedrate (mm/m)
* S - Retract/recover feedrate (mm/min)
* X - Move to X before triggering the shutter
* Y - Move to Y before triggering the shutter
* Z - Raise Z by a distance before triggering the shutter

View File

@@ -51,7 +51,7 @@ void GcodeSuite::M907() {
if (!parser.seen("BS" STR_AXES_LOGICAL))
return M907_report();
if (parser.seenval('S')) LOOP_L_N(i, MOTOR_CURRENT_COUNT) stepper.set_digipot_current(i, parser.value_int());
if (parser.seenval('S')) for (uint8_t i = 0; i < MOTOR_CURRENT_COUNT; ++i) stepper.set_digipot_current(i, parser.value_int());
LOOP_LOGICAL_AXES(i) if (parser.seenval(IAXIS_CHAR(i))) stepper.set_digipot_current(i, parser.value_int()); // X Y Z (I J K U V W) E (map to drivers according to DIGIPOT_CHANNELS. Default with NUM_AXES 3: map X Y Z E to X Y Z E0)
// Additional extruders use B,C.
// TODO: Change these parameters because 'E' is used and D should be reserved for debugging. B<index>?
@@ -82,7 +82,7 @@ void GcodeSuite::M907() {
#endif
)) return M907_report();
if (parser.seenval('S')) LOOP_L_N(a, MOTOR_CURRENT_COUNT) stepper.set_digipot_current(a, parser.value_int());
if (parser.seenval('S')) for (uint8_t a = 0; a < MOTOR_CURRENT_COUNT; ++a) stepper.set_digipot_current(a, parser.value_int());
#if HAS_X_Y_XY_I_J_K_U_V_W
if (NUM_AXIS_GANG(
@@ -104,7 +104,7 @@ void GcodeSuite::M907() {
#if HAS_MOTOR_CURRENT_I2C
// this one uses actual amps in floating point
if (parser.seenval('S')) LOOP_L_N(q, DIGIPOT_I2C_NUM_CHANNELS) digipot_i2c.set_current(q, parser.value_float());
if (parser.seenval('S')) for (uint8_t q = 0; q < DIGIPOT_I2C_NUM_CHANNELS; ++q) digipot_i2c.set_current(q, parser.value_float());
LOOP_LOGICAL_AXES(i) if (parser.seenval(IAXIS_CHAR(i))) digipot_i2c.set_current(i, parser.value_float()); // X Y Z (I J K U V W) E (map to drivers according to pots adresses. Default with NUM_AXES 3 X Y Z E: map to X Y Z E0)
// Additional extruders use B,C,D.
// TODO: Change these parameters because 'E' is used and because 'D' should be reserved for debugging. B<index>?

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

@@ -79,7 +79,7 @@ void GcodeSuite::M7219() {
}
if (parser.seen('P')) {
LOOP_L_N(r, MAX7219_LINES) {
for (uint8_t r = 0; r < MAX7219_LINES; ++r) {
SERIAL_ECHOPGM("led_line[");
if (r < 10) SERIAL_CHAR(' ');
SERIAL_ECHO(r);

View File

@@ -76,7 +76,7 @@ void GcodeSuite::M164() {
* I[factor] Mix factor for extruder stepper 6
*/
void GcodeSuite::M165() {
// Get mixing parameters from the GCode
// Get mixing parameters from the G-Code
// The total "must" be 1.0 (but it will be normalized)
// If no mix factors are given, the old mix is preserved
const char mixing_codes[] = { LIST_N(MIXING_STEPPERS, 'A', 'B', 'C', 'D', 'H', 'I') };

View File

@@ -46,7 +46,7 @@ void MAC_report() {
if (ethernet.hardware_enabled) {
Ethernet.MACAddress(mac);
SERIAL_ECHOPGM(" MAC: ");
LOOP_L_N(i, 6) {
for (uint8_t i = 0; i < 6; ++i) {
if (mac[i] < 16) SERIAL_CHAR('0');
SERIAL_PRINT(mac[i], PrintBase::Hex);
if (i < 5) SERIAL_CHAR(':');
@@ -59,7 +59,7 @@ void MAC_report() {
// otherwise show the stored values
void ip_report(const uint16_t cmd, FSTR_P const post, const IPAddress &ipo) {
SERIAL_CHAR('M'); SERIAL_ECHO(cmd); SERIAL_CHAR(' ');
LOOP_L_N(i, 4) {
for (uint8_t i = 0; i < 4; ++i) {
SERIAL_ECHO(ipo[i]);
if (i < 3) SERIAL_CHAR('.');
}

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(
LIST_N(DOUBLE(NUM_AXES),
SP_X_LBL, pos.x, SP_Y_LBL, pos.y, SP_Z_LBL, pos.z,
SP_I_LBL, pos.i, SP_J_LBL, pos.j, SP_K_LBL, pos.k,
SP_U_LBL, pos.u, SP_V_LBL, pos.v, SP_W_LBL, pos.w
)
#if HAS_EXTRUDERS
, SP_E_LBL, pos.e
#endif
);
#if NUM_AXES
DEBUG_ECHOPGM_P(
LIST_N(DOUBLE(NUM_AXES),
SP_X_LBL, pos.x, SP_Y_LBL, pos.y, SP_Z_LBL, pos.z,
SP_I_LBL, pos.i, SP_J_LBL, pos.j, SP_K_LBL, pos.k,
SP_U_LBL, pos.u, SP_V_LBL, pos.v, SP_W_LBL, pos.w
)
);
#endif
#if HAS_EXTRUDERS
DEBUG_ECHOPGM_P(SP_E_LBL, pos.e);
#endif
DEBUG_EOL();
}
#endif
}

View File

@@ -71,7 +71,7 @@ void GcodeSuite::G61() {
if (!TEST(saved_slots[slot >> 3], slot & 0x07)) return;
// Apply any given feedrate over 0.0
feedRate_t saved_feedrate = feedrate_mm_s;
REMEMBER(saved, feedrate_mm_s);
const float fr = parser.linearval('F');
if (fr > 0.0) feedrate_mm_s = MMM_TO_MMS(fr);
@@ -101,8 +101,6 @@ void GcodeSuite::G61() {
}
#endif
}
feedrate_mm_s = saved_feedrate;
}
#endif // SAVED_POSITIONS

View File

@@ -88,7 +88,7 @@ void GcodeSuite::M125() {
park_point += hotend_offset[active_extruder];
#endif
const bool sd_printing = TERN0(SDSUPPORT, IS_SD_PRINTING());
const bool sd_printing = TERN0(HAS_MEDIA, IS_SD_PRINTING());
ui.pause_show_message(PAUSE_MESSAGE_PARKING, PAUSE_MODE_PAUSE_PRINT);
@@ -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) || BOTH(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

@@ -199,7 +199,7 @@ void GcodeSuite::M702() {
#if HAS_PRUSA_MMU2
mmu2.unload();
#else
#if BOTH(HAS_MULTI_EXTRUDER, FILAMENT_UNLOAD_ALL_EXTRUDERS)
#if ALL(HAS_MULTI_EXTRUDER, FILAMENT_UNLOAD_ALL_EXTRUDERS)
if (!parser.seenval('T')) {
HOTEND_LOOP() {
if (e != active_extruder) tool_change(e);

View File

@@ -30,6 +30,14 @@
/**
* M122: Debug TMC drivers
*
* I - Flag to re-initialize stepper drivers with current settings.
* X, Y, Z, E - Flags to only report the specified axes.
*
* With TMC_DEBUG:
* V - Report raw register data. Refer to the datasheet to decipher the report.
* S - Flag to enable/disable continuous debug reporting.
* P<ms> - Interval between continuous debug reports, in milliseconds.
*/
void GcodeSuite::M122() {
xyze_bool_t print_axis = ARRAY_N_1(LOGICAL_AXES, false);

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

View File

@@ -328,7 +328,6 @@ void GcodeSuite::M906_report(const bool forReplay/*=true*/) {
say_M906(forReplay);
SERIAL_ECHOLNPGM(" T7 E", stepperE7.getMilliamps());
#endif
SERIAL_EOL();
}
#endif // HAS_TRINAMIC_CONFIG

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

@@ -75,13 +75,13 @@ GcodeSuite gcode;
millis_t GcodeSuite::previous_move_ms = 0,
GcodeSuite::max_inactive_time = 0;
#if HAS_DISABLE_INACTIVE_AXIS
millis_t GcodeSuite::stepper_inactive_time = SEC_TO_MS(DEFAULT_STEPPER_DEACTIVE_TIME);
#if HAS_DISABLE_IDLE_AXES
millis_t GcodeSuite::stepper_inactive_time = SEC_TO_MS(DEFAULT_STEPPER_TIMEOUT_SEC);
#endif
// 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),
@@ -94,7 +94,7 @@ axis_bits_t GcodeSuite::axis_relative = 0 LOGICAL_AXIS_GANG(
| (ar_init.w << REL_W)
);
#if EITHER(HAS_AUTO_REPORTING, HOST_KEEPALIVE_FEATURE)
#if ANY(HAS_AUTO_REPORTING, HOST_KEEPALIVE_FEATURE)
bool GcodeSuite::autoreport_paused; // = false
#endif
@@ -166,7 +166,7 @@ int8_t GcodeSuite::get_target_e_stepper_from_command(const int8_t dval/*=-1*/) {
}
/**
* Set XYZ...E destination and feedrate from the current GCode command
* Set XYZ...E destination and feedrate from the current G-Code command
*
* - Set destination from included axis codes
* - Set to current for missing axis codes
@@ -216,13 +216,13 @@ void GcodeSuite::get_destination_from_command() {
TERN_(LASER_FEATURE, cutter.feedrate_mm_m = MMS_TO_MMM(feedrate_mm_s));
}
#if BOTH(PRINTCOUNTER, HAS_EXTRUDERS)
#if ALL(PRINTCOUNTER, HAS_EXTRUDERS)
if (!DEBUGGING(DRYRUN) && !skip_move)
print_job_timer.incFilamentUsed(destination.e - current_position.e);
#endif
// Get ABCDHI mixing factors
#if BOTH(MIXING_EXTRUDER, DIRECT_MIXING_IN_G1)
#if ALL(MIXING_EXTRUDER, DIRECT_MIXING_IN_G1)
M165();
#endif
@@ -454,7 +454,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 61: G61(); break; // G61: Apply/restore saved coordinates.
#endif
#if BOTH(PTC_PROBE, PTC_BED)
#if ALL(PTC_PROBE, PTC_BED)
case 76: G76(); break; // G76: Calibrate first layer compensation values
#endif
@@ -472,7 +472,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
#endif
#if ENABLED(DEBUG_GCODE_PARSER)
case 800: parser.debug(); break; // G800: GCode Parser Test for G
case 800: parser.debug(); break; // G800: G-Code Parser Test for G
#endif
default: parser.unknown_command_warning(); break;
@@ -496,11 +496,11 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 7: M7(); break; // M7: Coolant Mist ON
#endif
#if EITHER(AIR_ASSIST, COOLANT_FLOOD)
#if ANY(AIR_ASSIST, COOLANT_FLOOD)
case 8: M8(); break; // M8: Air Assist / Coolant Flood ON
#endif
#if EITHER(AIR_ASSIST, COOLANT_CONTROL)
#if ANY(AIR_ASSIST, COOLANT_CONTROL)
case 9: M9(); break; // M9: Air Assist / Coolant OFF
#endif
@@ -519,7 +519,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 17: M17(); break; // M17: Enable all stepper motors
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
case 20: M20(); break; // M20: List SD card
case 21: M21(); break; // M21: Init SD card
case 22: M22(); break; // M22: Release SD card
@@ -540,12 +540,12 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 33: M33(); break; // M33: Get the long full path to a file or folder
#endif
#if BOTH(SDCARD_SORT_ALPHA, SDSORT_GCODE)
#if ALL(SDCARD_SORT_ALPHA, SDSORT_GCODE)
case 34: M34(); break; // M34: Set SD card sorting options
#endif
case 928: M928(); break; // M928: Start SD write
#endif // SDSUPPORT
#endif // HAS_MEDIA
case 31: M31(); break; // M31: Report time since the start of SD print or last M109
@@ -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
@@ -640,7 +640,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 154: M154(); break; // M154: Set position auto-report interval
#endif
#if BOTH(AUTO_REPORT_TEMPERATURES, HAS_TEMP_SENSOR)
#if ALL(AUTO_REPORT_TEMPERATURES, HAS_TEMP_SENSOR)
case 155: M155(); break; // M155: Set temperature auto-report interval
#endif
@@ -671,6 +671,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 82: M82(); break; // M82: Set E axis normal mode (same as other axes)
case 83: M83(); break; // M83: Set E axis relative mode
#endif
case 18: case 84: M18_M84(); break; // M18/M84: Disable Steppers / Set Timeout
case 85: M85(); break; // M85: Set inactivity stepper shutdown timeout
case 92: M92(); break; // M92: Set the steps-per-unit for one or more axes
@@ -836,7 +837,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 364: if (M364()) return; break; // M364: SCARA Psi pos3 (90 deg to Theta)
#endif
#if EITHER(EXT_SOLENOID, MANUAL_SOLENOID_CONTROL)
#if ANY(EXT_SOLENOID, MANUAL_SOLENOID_CONTROL)
case 380: M380(); break; // M380: Activate solenoid on active (or specified) extruder
case 381: M381(); break; // M381: Disable all solenoids or, if MANUAL_SOLENOID_CONTROL, active (or specified) solenoid
#endif
@@ -915,7 +916,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
#endif
#endif
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
case 524: M524(); break; // M524: Abort the current SD print job
#endif
@@ -933,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
@@ -950,7 +951,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 665: M665(); break; // M665: Set Kinematics parameters
#endif
#if ENABLED(DELTA) || HAS_EXTRA_ENDSTOPS
#if ANY(DELTA, HAS_EXTRA_ENDSTOPS)
case 666: M666(); break; // M666: Set delta or multiple endstop adjustment
#endif
@@ -991,7 +992,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
#if ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_PWM, HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC)
case 907: M907(); break; // M907: Set digital trimpot motor current using axis codes.
#if EITHER(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_DAC)
#if ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_DAC)
case 908: M908(); break; // M908: Control digital trimpot directly.
#if HAS_MOTOR_CURRENT_DAC
case 909: M909(); break; // M909: Print digipot/DAC current value
@@ -1029,7 +1030,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
#endif
#if ENABLED(DEBUG_GCODE_PARSER)
case 800: parser.debug(); break; // M800: GCode Parser Test for M
case 800: parser.debug(); break; // M800: G-Code Parser Test for M
#endif
#if ENABLED(GCODE_REPEAT_MARKERS)
@@ -1057,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, SDSUPPORT, 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
@@ -1077,7 +1078,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 1000: M1000(); break; // M1000: [INTERNAL] Resume from power-loss
#endif
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
case 1001: M1001(); break; // M1001: [INTERNAL] Handle SD completion
#endif
@@ -1124,7 +1125,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
@@ -403,7 +410,7 @@ public:
}
FORCE_INLINE static void reset_stepper_timeout(const millis_t ms=millis()) { previous_move_ms = ms; }
#if HAS_DISABLE_INACTIVE_AXIS
#if HAS_DISABLE_IDLE_AXES
static millis_t stepper_inactive_time;
FORCE_INLINE static bool stepper_inactive_timeout(const millis_t ms=millis()) {
return ELAPSED(ms, previous_move_ms + stepper_inactive_time);
@@ -435,7 +442,7 @@ public:
process_subcommands_now(keep_leveling ? FPSTR(G28_STR) : TERN(CAN_SET_LEVELING_AFTER_G28, F("G28L0"), FPSTR(G28_STR)));
}
#if EITHER(HAS_AUTO_REPORTING, HOST_KEEPALIVE_FEATURE)
#if ANY(HAS_AUTO_REPORTING, HOST_KEEPALIVE_FEATURE)
static bool autoreport_paused;
static bool set_autoreport_paused(const bool p) {
const bool was = autoreport_paused;
@@ -454,7 +461,7 @@ public:
*/
enum MarlinBusyState : char {
NOT_BUSY, // Not in a handler
IN_HANDLER, // Processing a GCode
IN_HANDLER, // Processing a G-Code
IN_PROCESS, // Known to be blocking command input (as in G29)
PAUSED_FOR_USER, // Blocking pending any input
PAUSED_FOR_INPUT // Blocking pending text input (concept)
@@ -582,7 +589,7 @@ private:
static void G59();
#endif
#if BOTH(PTC_PROBE, PTC_BED)
#if ALL(PTC_PROBE, PTC_BED)
static void G76();
#endif
@@ -614,11 +621,11 @@ private:
static void M7();
#endif
#if EITHER(AIR_ASSIST, COOLANT_FLOOD)
#if ANY(AIR_ASSIST, COOLANT_FLOOD)
static void M8();
#endif
#if EITHER(AIR_ASSIST, COOLANT_CONTROL)
#if ANY(AIR_ASSIST, COOLANT_CONTROL)
static void M9();
#endif
@@ -639,7 +646,7 @@ private:
static void M18_M84();
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
static void M20();
static void M21();
static void M22();
@@ -655,14 +662,14 @@ private:
static void M31();
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
#if HAS_MEDIA_SUBCALLS
static void M32();
#endif
#if ENABLED(LONG_FILENAME_HOST_SUPPORT)
static void M33();
#endif
#if BOTH(SDCARD_SORT_ALPHA, SDSORT_GCODE)
#if ALL(SDCARD_SORT_ALPHA, SDSORT_GCODE)
static void M34();
#endif
#endif
@@ -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); }
@@ -811,7 +818,7 @@ private:
static void M154();
#endif
#if BOTH(AUTO_REPORT_TEMPERATURES, HAS_TEMP_SENSOR)
#if ALL(AUTO_REPORT_TEMPERATURES, HAS_TEMP_SENSOR)
static void M155();
#endif
@@ -979,7 +986,7 @@ private:
static bool M364();
#endif
#if EITHER(EXT_SOLENOID, MANUAL_SOLENOID_CONTROL)
#if ANY(EXT_SOLENOID, MANUAL_SOLENOID_CONTROL)
static void M380();
static void M381();
#endif
@@ -1055,7 +1062,7 @@ private:
#endif
#endif
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
static void M524();
#endif
@@ -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
@@ -1101,7 +1108,7 @@ private:
static void M665_report(const bool forReplay=true);
#endif
#if EITHER(DELTA, HAS_EXTRA_ENDSTOPS)
#if ANY(DELTA, HAS_EXTRA_ENDSTOPS)
static void M666();
static void M666_report(const bool forReplay=true);
#endif
@@ -1188,7 +1195,7 @@ private:
static void M910();
#endif
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
static void M928();
#endif
@@ -1200,7 +1207,7 @@ private:
static void M995();
#endif
#if BOTH(SPI_FLASH, SDSUPPORT)
#if ALL(SPI_FLASH, HAS_MEDIA)
static void M993();
static void M994();
#endif
@@ -1222,7 +1229,7 @@ private:
static void M423_report(const bool forReplay=true);
#endif
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
static void M1001();
#endif

View File

@@ -199,7 +199,7 @@ void GcodeSuite::D(const int16_t dcode) {
SERIAL_ECHOLNPGM("FAILURE: Watchdog did not trigger board reset.");
} break;
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
case 101: { // D101 Test SD Write
card.openFileWrite("test.gco");
@@ -250,7 +250,7 @@ void GcodeSuite::D(const int16_t dcode) {
card.closefile();
} break;
#endif // SDSUPPORT
#endif // HAS_MEDIA
#if ENABLED(POSTMORTEM_DEBUGGING)

View File

@@ -88,28 +88,28 @@ void GcodeSuite::G92() {
case 0:
LOOP_LOGICAL_AXES(i) {
if (parser.seenval(AXIS_CHAR(i))) {
const float l = parser.value_axis_units((AxisEnum)i), // Given axis coordinate value, converted to millimeters
const float l = parser.value_axis_units((AxisEnum)i), // Given axis coordinate value, converted to millimeters
v = TERN0(HAS_EXTRUDERS, i == E_AXIS) ? l : LOGICAL_TO_NATIVE(l, i), // Axis position in NATIVE space (applying the existing offset)
d = v - current_position[i]; // How much is the current axis position altered by?
d = v - current_position[i]; // How much is the current axis position altered by?
if (!NEAR_ZERO(d)) {
#if HAS_POSITION_SHIFT && NONE(IS_SCARA, POLARGRAPH) // When using workspaces...
#if HAS_POSITION_SHIFT && NONE(IS_SCARA, POLARGRAPH) // When using workspaces...
if (TERN1(HAS_EXTRUDERS, i != E_AXIS)) {
position_shift[i] += d; // ...most axes offset the workspace...
position_shift[i] += d; // ...most axes offset the workspace...
update_workspace_offset((AxisEnum)i);
}
else {
#if HAS_EXTRUDERS
sync_E = true;
current_position.e = v; // ...but E is set directly
current_position.e = v; // ...but E is set directly
#endif
}
#else // Without workspaces...
#else // Without workspaces...
if (TERN1(HAS_EXTRUDERS, i != E_AXIS))
sync_XYZE = true;
else {
TERN_(HAS_EXTRUDERS, sync_E = true);
}
current_position[i] = v; // ...set Current Position directly (like Marlin 1.0)
current_position[i] = v; // ...set Current Position directly (like Marlin 1.0)
#endif
}
}

View File

@@ -33,9 +33,7 @@
/**
* M206: Set Additional Homing Offset (X Y Z). SCARA aliases T=X, P=Y
*
* *** @thinkyhead: I recommend deprecating M206 for SCARA in favor of M665.
* *** M206 for SCARA will remain enabled in 1.1.x for compatibility.
* *** In the 2.0 release, it will simply be disabled by default.
* *** TODO: Deprecate M206 for SCARA in favor of M665.
*/
void GcodeSuite::M206() {
if (!parser.seen_any()) return M206_report();
@@ -91,7 +89,7 @@ void GcodeSuite::M428() {
diff[i] = -current_position[i];
if (!WITHIN(diff[i], -20, 20)) {
SERIAL_ERROR_MSG(STR_ERR_M428_TOO_FAR);
LCD_ALERTMESSAGE_F("Err: Too far!");
LCD_ALERTMESSAGE(MSG_ERR_M428_TOO_FAR);
ERR_BUZZ();
return;
}

View File

@@ -30,7 +30,7 @@
void report_all_axis_pos(const xyze_pos_t &pos, const uint8_t n=LOGICAL_AXES, const uint8_t precision=3) {
char str[12];
LOOP_L_N(a, n) {
for (uint8_t a = 0; a < n; ++a) {
SERIAL_ECHOPGM_P((PGM_P)pgm_read_ptr(&SP_AXIS_LBL[a]));
if (pos[a] >= 0) SERIAL_CHAR(' ');
SERIAL_ECHO(dtostrf(pos[a], 1, precision, str));
@@ -128,9 +128,7 @@ void GcodeSuite::M114() {
#if ENABLED(M114_DETAIL)
if (parser.seen_test('D')) {
#if DISABLED(M114_LEGACY)
planner.synchronize();
#endif
IF_DISABLED(M114_LEGACY, planner.synchronize());
report_current_position();
report_current_position_detail();
return;
@@ -143,9 +141,7 @@ void GcodeSuite::M114() {
#endif
#endif
#if ENABLED(M114_REALTIME)
if (parser.seen_test('R')) { report_real_position(); return; }
#endif
TERN_(M114_REALTIME, if (parser.seen_test('R')) return report_real_position());
TERN_(M114_LEGACY, planner.synchronize());
report_current_position_projected();

View File

@@ -39,30 +39,27 @@
//#define MINIMAL_CAP_LINES // Don't even mention the disabled capabilities
#if ENABLED(EXTENDED_CAPABILITIES_REPORT)
#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");
}
#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);
inline void cap_line(FSTR_P const name, const bool ena=true) {
#if ENABLED(MINIMAL_CAP_LINES)
if (ena) SERIAL_ECHOLNPGM("Cap:", name, ":1");
#else
SERIAL_ECHOPGM("Cap:", name);
SERIAL_CHAR(':', '0' + ena);
SERIAL_EOL();
}
#endif
#endif
}
#endif
/**
* M115: Capabilities string and extended capabilities report
* If a capability is not reported, hosts should assume
* the capability is not present.
*
* NOTE: Always make sure to add new capabilities to the RepRap Wiki
* at https://reprap.org/wiki/Firmware_Capabilities_Protocol
*/
void GcodeSuite::M115() {
SERIAL_ECHOPGM("FIRMWARE_NAME:Marlin"
" " DETAILED_BUILD_VERSION " (" __DATE__ " " __TIME__ ")"
" SOURCE_CODE_URL:" SOURCE_CODE_URL
@@ -85,7 +82,7 @@ void GcodeSuite::M115() {
// Although this code should work on all STM32 based boards
SERIAL_ECHOPGM(" UUID:");
uint32_t *uid_address = (uint32_t*)UID_BASE;
LOOP_L_N(i, 3) {
for (uint8_t i = 0; i < 3; ++i) {
const uint32_t UID = uint32_t(READ_REG(*(uid_address)));
uid_address += 4U;
for (int B = 24; B >= 0; B -= 8) print_hex_byte(UID >> B);
@@ -100,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));
@@ -124,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));
@@ -153,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)
@@ -168,10 +165,10 @@ void GcodeSuite::M115() {
cap_line(F("PROMPT_SUPPORT"), ENABLED(HOST_PROMPT_SUPPORT));
// SDCARD (M20, M23, M24, etc.)
cap_line(F("SDCARD"), ENABLED(SDSUPPORT));
cap_line(F("SDCARD"), ENABLED(HAS_MEDIA));
// MULTI_VOLUME (M21 S/M21 U)
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
cap_line(F("MULTI_VOLUME"), ENABLED(MULTI_VOLUME));
#endif
@@ -179,7 +176,7 @@ void GcodeSuite::M115() {
cap_line(F("REPEAT"), ENABLED(GCODE_REPEAT_MARKERS));
// SD_WRITE (M928, M28, M29)
cap_line(F("SD_WRITE"), ENABLED(SDSUPPORT) && DISABLED(SDCARD_READONLY));
cap_line(F("SD_WRITE"), ENABLED(HAS_MEDIA) && DISABLED(SDCARD_READONLY));
// AUTOREPORT_SD_STATUS (M27 extension)
cap_line(F("AUTOREPORT_SD_STATUS"), ENABLED(AUTO_REPORT_SD_STATUS));
@@ -232,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:{"
@@ -249,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);
@@ -70,7 +70,7 @@ void GcodeSuite::M360() {
config_line(F("InputBuffer"), MAX_CMD_SIZE);
config_line(F("PrintlineCache"), BUFSIZE);
config_line(F("MixingExtruder"), ENABLED(MIXING_EXTRUDER));
config_line(F("SDCard"), ENABLED(SDSUPPORT));
config_line(F("SDCard"), ENABLED(HAS_MEDIA));
config_line(F("Fan"), ENABLED(HAS_FAN));
config_line(F("LCD"), ENABLED(HAS_DISPLAY));
config_line(F("SoftwarePowerSwitch"), 1);

View File

@@ -62,7 +62,7 @@ void GcodeSuite::M145() {
void GcodeSuite::M145_report(const bool forReplay/*=true*/) {
report_heading(forReplay, F(STR_MATERIAL_HEATUP));
LOOP_L_N(i, PREHEAT_COUNT) {
for (uint8_t i = 0; i < PREHEAT_COUNT; ++i) {
report_echo_start(forReplay);
SERIAL_ECHOLNPGM_P(
PSTR(" M145 S"), i

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

@@ -25,7 +25,7 @@
#include "../../MarlinCore.h"
#if BOTH(FWRETRACT, FWRETRACT_AUTORETRACT)
#if ALL(FWRETRACT, FWRETRACT_AUTORETRACT)
#include "../../feature/fwretract.h"
#endif
@@ -87,7 +87,7 @@ void GcodeSuite::G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move/*=false*/)) {
}
#endif
#if BOTH(FWRETRACT, FWRETRACT_AUTORETRACT)
#if ALL(FWRETRACT, FWRETRACT_AUTORETRACT)
if (MIN_AUTORETRACT <= MAX_AUTORETRACT) {
// When M209 Autoretract is enabled, convert E-only moves to firmware retract/recover moves

View File

@@ -298,7 +298,7 @@ void plan_arc(
// d) allows the print head to stop in the remining length of the curve within all configured maximum accelerations.
// The last has to be calculated every time through the loop.
const float limiting_accel = _MIN(planner.settings.max_acceleration_mm_per_s2[axis_p], planner.settings.max_acceleration_mm_per_s2[axis_q]),
limiting_speed = _MIN(planner.settings.max_feedrate_mm_s[axis_p], planner.settings.max_acceleration_mm_per_s2[axis_q]),
limiting_speed = _MIN(planner.settings.max_feedrate_mm_s[axis_p], planner.settings.max_feedrate_mm_s[axis_q]),
limiting_speed_sqr = _MIN(sq(limiting_speed), limiting_accel * radius, sq(scaled_fr_mm_s));
float arc_mm_remaining = flat_mm;

View File

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

View File

@@ -21,7 +21,7 @@
*/
/**
* parser.cpp - Parser for a GCode line, providing a parameter interface.
* parser.cpp - Parser for a G-Code line, providing a parameter interface.
*/
#include "parser.h"
@@ -66,7 +66,7 @@ uint16_t GCodeParser::codenum;
char *GCodeParser::command_args; // start of parameters
#endif
// Create a global instance of the GCode parser singleton
// Create a global instance of the G-Code parser singleton
GCodeParser parser;
/**
@@ -108,7 +108,7 @@ void GCodeParser::reset() {
/**
* Populate the command line state (command_letter, codenum, subcode, and string_arg)
* by parsing a single line of GCode. 58 bytes of SRAM are used to speed up seen/value.
* by parsing a single line of G-Code. 58 bytes of SRAM are used to speed up seen/value.
*/
void GCodeParser::parse(char *p) {
@@ -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
@@ -229,11 +235,11 @@ void GCodeParser::parse(char *p) {
}
#endif
} break;
} break;
#if ENABLED(GCODE_MOTION_MODES)
#if EITHER(BEZIER_CURVE_SUPPORT, ARC_SUPPORT)
#if ANY(BEZIER_CURVE_SUPPORT, ARC_SUPPORT)
case 'I' ... 'J': case 'P':
if (TERN1(BEZIER_CURVE_SUPPORT, motion_mode_codenum != 5)
&& TERN1(ARC_P_CIRCLES, !WITHIN(motion_mode_codenum, 2, 3))
@@ -311,7 +317,7 @@ void GCodeParser::parse(char *p) {
#endif
#if ENABLED(FASTER_GCODE_PARSER)
// Arguments MUST be uppercase for fast GCode parsing
// Arguments MUST be uppercase for fast G-Code parsing
#define PARAM_OK(P) WITHIN((P), 'A', 'Z')
#else
#define PARAM_OK(P) true
@@ -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

@@ -22,8 +22,8 @@
#pragma once
/**
* parser.h - Parser for a GCode line, providing a parameter interface.
* Codes like M149 control the way the GCode parser behaves,
* parser.h - Parser for a G-Code line, providing a parameter interface.
* Codes like M149 control the way the G-Code parser behaves,
* so settings for these codes are located in this class.
*/
@@ -43,7 +43,7 @@
#endif
/**
* GCode parser
* G-Code parser
*
* - Parse a single G-code line for its letter, code, subcode, and parameters
* - FASTER_GCODE_PARSER:
@@ -68,7 +68,7 @@ private:
public:
// Global states for GCode-level units features
// Global states for G-Code-level units features
static bool volumetric_enabled;
@@ -233,7 +233,7 @@ public:
FORCE_INLINE static char* unescape_string(char* &src) { return src; }
#endif
// Populate all fields by parsing a single line of GCode
// Populate all fields by parsing a single line of G-Code
// This uses 54 bytes of SRAM to speed up seen/value
static void parse(char * p);
@@ -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

@@ -39,7 +39,7 @@
#endif
/**
* G30: Do a single Z probe at the current XY
* G30: Do a single Z probe at the given XY (default: current)
*
* Parameters:
*
@@ -76,7 +76,7 @@ void GcodeSuite::G30() {
TERN_(HAS_PTC, ptc.set_enabled(true));
if (!isnan(measured_z)) {
SERIAL_ECHOLNPGM("Bed X: ", pos.asLogical().x, " Y: ", pos.asLogical().y, " Z: ", measured_z);
#if EITHER(DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI)
#if ANY(DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI)
char msg[31], str_1[6], str_2[6], str_3[6];
sprintf_P(msg, PSTR("X:%s, Y:%s, Z:%s"),
dtostrf(pos.x, 1, 1, str_1),

View File

@@ -105,6 +105,7 @@ inline bool G38_run_probe() {
* G38.5 - Probe away from workpiece, stop on contact break
*/
void GcodeSuite::G38(const int8_t subcode) {
// Get X Y Z E F
get_destination_from_command();

View File

@@ -62,7 +62,9 @@ void GcodeSuite::M401() {
*/
void GcodeSuite::M402() {
probe.stow();
probe.move_z_after_probing();
#ifdef Z_AFTER_PROBING
do_z_clearance(Z_AFTER_PROBING);
#endif
report_current_position();
}

View File

@@ -88,7 +88,7 @@ void GcodeSuite::M423() {
void GcodeSuite::M423_report(const bool forReplay/*=true*/) {
report_heading(forReplay, F("X-Twist Correction"));
SERIAL_ECHOLNPGM(" M423 A", xatc.start, " I", xatc.spacing);
LOOP_L_N(x, XATC_MAX_POINTS) {
for (uint8_t x = 0; x < XATC_MAX_POINTS; ++x) {
const float z = xatc.z_offset[x];
SERIAL_ECHOPGM(" M423 X", x, " Z");
serial_offset(isnan(z) ? 0 : z);

View File

@@ -46,7 +46,7 @@ void mpe_settings_init() {
mpe_settings.parking_xpos[0] = pex[0]; // M951 L
mpe_settings.parking_xpos[1] = pex[1]; // M951 R
mpe_settings.grab_distance = PARKING_EXTRUDER_GRAB_DISTANCE; // M951 I
TERN_(HAS_HOME_OFFSET, set_home_offset(X_AXIS, mpe_settings.grab_distance * -1));
TERN_(HAS_HOME_OFFSET, set_home_offset(X_AXIS, -mpe_settings.grab_distance));
mpe_settings.slow_feedrate = MMM_TO_MMS(MPE_SLOW_SPEED); // M951 J
mpe_settings.fast_feedrate = MMM_TO_MMS(MPE_FAST_SPEED); // M951 H
mpe_settings.travel_distance = MPE_TRAVEL_DISTANCE; // M951 D
@@ -59,7 +59,7 @@ void GcodeSuite::M951() {
if (parser.seenval('R')) mpe_settings.parking_xpos[1] = parser.value_linear_units();
if (parser.seenval('I')) {
mpe_settings.grab_distance = parser.value_linear_units();
TERN_(HAS_HOME_OFFSET, set_home_offset(X_AXIS, mpe_settings.grab_distance * -1));
TERN_(HAS_HOME_OFFSET, set_home_offset(X_AXIS, -mpe_settings.grab_distance));
}
if (parser.seenval('J')) mpe_settings.slow_feedrate = MMM_TO_MMS(parser.value_linear_units());
if (parser.seenval('H')) mpe_settings.fast_feedrate = MMM_TO_MMS(parser.value_linear_units());

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
@@ -99,7 +91,11 @@ PGM_P GCodeQueue::injected_commands_P; // = nullptr
*/
char GCodeQueue::injected_commands[64]; // = { 0 }
void GCodeQueue::RingBuffer::commit_command(bool skip_ok
/**
* Commit the accumulated G-code command to the ring buffer,
* also setting its origin info.
*/
void GCodeQueue::RingBuffer::commit_command(const bool skip_ok
OPTARG(HAS_MULTI_SERIAL, serial_index_t serial_ind/*=-1*/)
) {
commands[index_w].skip_ok = skip_ok;
@@ -113,7 +109,7 @@ void GCodeQueue::RingBuffer::commit_command(bool skip_ok
* Return true if the command was successfully added.
* Return false for a full buffer, or if the 'command' is a comment.
*/
bool GCodeQueue::RingBuffer::enqueue(const char *cmd, bool skip_ok/*=true*/
bool GCodeQueue::RingBuffer::enqueue(const char *cmd, const bool skip_ok/*=true*/
OPTARG(HAS_MULTI_SERIAL, serial_index_t serial_ind/*=-1*/)
) {
if (*cmd == ';' || length >= BUFSIZE) return false;
@@ -294,7 +290,7 @@ static bool serial_data_available(serial_index_t index) {
#if NO_TIMEOUTS > 0
// Multiserial already handles dispatch to/from multiple ports
static bool any_serial_data_available() {
LOOP_L_N(p, NUM_SERIAL)
for (uint8_t p = 0; p < NUM_SERIAL; ++p)
if (serial_data_available(p))
return true;
return false;
@@ -303,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();
@@ -423,7 +437,7 @@ void GCodeQueue::get_serial_commands() {
// Unless a serial port has data, this will exit on next iteration
hadData = false;
LOOP_L_N(p, NUM_SERIAL) {
for (uint8_t p = 0; p < NUM_SERIAL; ++p) {
// Check if the queue is full and exit if it is.
if (ring_buffer.full()) return;
@@ -494,7 +508,7 @@ void GCodeQueue::get_serial_commands() {
serial.last_N = gcode_N;
}
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
// Pronterface "M29" and "M29 " has no line number
else if (card.flag.saving && !is_M29(command)) {
gcode_line_error(F(STR_ERR_NO_CHECKSUM), p);
@@ -544,7 +558,7 @@ void GCodeQueue::get_serial_commands() {
} // queue has space, serial has data
}
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
/**
* Get lines from the SD Card until the command buffer is full
@@ -597,7 +611,7 @@ void GCodeQueue::get_serial_commands() {
}
}
#endif // SDSUPPORT
#endif // HAS_MEDIA
/**
* Add to the circular command queue the next command from:
@@ -610,7 +624,7 @@ void GCodeQueue::get_available_commands() {
get_serial_commands();
TERN_(SDSUPPORT, get_sdcard_commands());
TERN_(HAS_MEDIA, get_sdcard_commands());
}
/**
@@ -649,7 +663,7 @@ void GCodeQueue::advance() {
}
#endif
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
if (card.flag.saving) {
char * const cmd = ring_buffer.peek_next_command_string();
@@ -685,7 +699,7 @@ void GCodeQueue::advance() {
gcode.process_next_command();
#endif // SDSUPPORT
#endif // HAS_MEDIA
// The queue may be reset by a command handler or by code invoked by idle() within a handler
ring_buffer.advance_pos(ring_buffer.index_r, -1);
@@ -695,8 +709,8 @@ void GCodeQueue::advance() {
void GCodeQueue::report_buffer_statistics() {
SERIAL_ECHOLNPGM("D576"
" P:", planner.moves_free(), " ", -planner_buffer_underruns, " (", max_planner_buffer_empty_duration, ")"
" B:", BUFSIZE - ring_buffer.length, " ", -command_buffer_underruns, " (", max_command_buffer_empty_duration, ")"
" P:", planner.moves_free(), " ", planner_buffer_underruns, " (", max_planner_buffer_empty_duration, ")"
" B:", BUFSIZE - ring_buffer.length, " ", command_buffer_underruns, " (", max_command_buffer_empty_duration, ")"
);
command_buffer_underruns = planner_buffer_underruns = 0;
max_command_buffer_empty_duration = max_planner_buffer_empty_duration = 0;

View File

@@ -35,7 +35,7 @@ public:
*/
struct SerialState {
/**
* GCode line number handling. Hosts may include line numbers when sending
* G-Code line number handling. Hosts may include line numbers when sending
* commands to Marlin, and lines will be checked for sequentiality.
* M110 N<int> sets the current line number.
*/
@@ -48,7 +48,7 @@ public:
static SerialState serial_state[NUM_SERIAL]; //!< Serial states for each serial port
/**
* GCode Command Queue
* G-Code Command Queue
* A simple (circular) ring buffer of BUFSIZE command strings.
*
* Commands are copied into this buffer by the command injectors
@@ -79,12 +79,12 @@ public:
void advance_pos(uint8_t &p, const int inc) { if (++p >= BUFSIZE) p = 0; length += inc; }
void commit_command(bool skip_ok
OPTARG(HAS_MULTI_SERIAL, serial_index_t serial_ind = serial_index_t())
void commit_command(const bool skip_ok
OPTARG(HAS_MULTI_SERIAL, serial_index_t serial_ind=serial_index_t())
);
bool enqueue(const char *cmd, bool skip_ok = true
OPTARG(HAS_MULTI_SERIAL, serial_index_t serial_ind = serial_index_t())
bool enqueue(const char *cmd, const bool skip_ok=true
OPTARG(HAS_MULTI_SERIAL, serial_index_t serial_ind=serial_index_t())
);
void ok_to_send();
@@ -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
*/
@@ -250,7 +256,7 @@ private:
static void get_serial_commands();
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
static void get_sdcard_commands();
#endif

View File

@@ -22,7 +22,7 @@
#include "../../inc/MarlinConfig.h"
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
#include "../gcode.h"
#include "../../module/planner.h"
@@ -34,7 +34,7 @@
#include "../queue.h"
#endif
#if EITHER(SET_PROGRESS_MANUALLY, SD_REPRINT_LAST_SELECTED_FILE)
#if ANY(SET_PROGRESS_MANUALLY, SD_REPRINT_LAST_SELECTED_FILE)
#include "../../lcd/marlinui.h"
#endif
@@ -49,8 +49,6 @@
#if ENABLED(EXTENSIBLE_UI)
#include "../../lcd/extui/ui_api.h"
#elif ENABLED(DWIN_LCD_PROUI)
#include "../../lcd/e3v2/proui/dwin.h"
#endif
#if ENABLED(HOST_ACTION_COMMANDS)
@@ -114,4 +112,4 @@ void GcodeSuite::M1001() {
TERN_(SD_REPRINT_LAST_SELECTED_FILE, ui.reselect_last_file());
}
#endif // SDSUPPORT
#endif // HAS_MEDIA

View File

@@ -22,7 +22,7 @@
#include "../../inc/MarlinConfig.h"
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
#include "../gcode.h"
#include "../../sd/cardreader.h"
@@ -51,4 +51,4 @@ void GcodeSuite::M20() {
SERIAL_ECHO_MSG(STR_NO_MEDIA);
}
#endif // SDSUPPORT
#endif // HAS_MEDIA

View File

@@ -22,7 +22,7 @@
#include "../../inc/MarlinConfig.h"
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
#include "../gcode.h"
#include "../../sd/cardreader.h"
@@ -52,4 +52,4 @@ void GcodeSuite::M22() {
if (!IS_SD_PRINTING()) card.release();
}
#endif // SDSUPPORT
#endif // HAS_MEDIA

View File

@@ -22,7 +22,7 @@
#include "../../inc/MarlinConfig.h"
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
#include "../gcode.h"
#include "../../sd/cardreader.h"
@@ -41,4 +41,4 @@ void GcodeSuite::M23() {
TERN_(SET_PROGRESS_PERCENT, ui.set_progress(0));
}
#endif // SDSUPPORT
#endif // HAS_MEDIA

View File

@@ -22,7 +22,7 @@
#include "../../inc/MarlinConfig.h"
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
#include "../gcode.h"
#include "../../sd/cardreader.h"
@@ -70,7 +70,7 @@ void GcodeSuite::M24() {
#endif
if (card.isFileOpen()) {
card.startOrResumeFilePrinting(); // SD card will now be read for commands
card.startOrResumeFilePrinting(); // SD card will now be read for commands
startOrResumeJob(); // Start (or resume) the print job timer
TERN_(POWER_LOSS_RECOVERY, recovery.prepare());
}
@@ -101,9 +101,7 @@ void GcodeSuite::M25() {
#else
// Set initial pause flag to prevent more commands from landing in the queue while we try to pause
#if ENABLED(SDSUPPORT)
if (IS_SD_PRINTING()) card.pauseSDPrint();
#endif
if (IS_SD_PRINTING()) card.pauseSDPrint();
#if ENABLED(POWER_LOSS_RECOVERY) && DISABLED(DGUS_LCD_UI_MKS)
if (recovery.enabled) recovery.save(true);
@@ -125,4 +123,4 @@ void GcodeSuite::M25() {
#endif
}
#endif // SDSUPPORT
#endif // HAS_MEDIA

View File

@@ -22,7 +22,7 @@
#include "../../inc/MarlinConfig.h"
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
#include "../gcode.h"
#include "../../sd/cardreader.h"
@@ -35,4 +35,4 @@ void GcodeSuite::M26() {
card.setIndex(parser.value_long());
}
#endif // SDSUPPORT
#endif // HAS_MEDIA

View File

@@ -22,7 +22,7 @@
#include "../../inc/MarlinConfig.h"
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
#include "../gcode.h"
#include "../../sd/cardreader.h"
@@ -49,4 +49,4 @@ void GcodeSuite::M27() {
card.report_status();
}
#endif // SDSUPPORT
#endif // HAS_MEDIA

View File

@@ -22,7 +22,7 @@
#include "../../inc/MarlinConfig.h"
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
#include "../gcode.h"
#include "../../sd/cardreader.h"
@@ -69,4 +69,4 @@ void GcodeSuite::M29() {
card.flag.saving = false;
}
#endif // SDSUPPORT
#endif // HAS_MEDIA

View File

@@ -22,7 +22,7 @@
#include "../../inc/MarlinConfig.h"
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
#include "../gcode.h"
#include "../../sd/cardreader.h"
@@ -37,4 +37,4 @@ void GcodeSuite::M30() {
}
}
#endif // SDSUPPORT
#endif // HAS_MEDIA

View File

@@ -22,16 +22,26 @@
#include "../../inc/MarlinConfig.h"
#if BOTH(SDCARD_SORT_ALPHA, SDSORT_GCODE)
#if ALL(SDCARD_SORT_ALPHA, SDSORT_GCODE)
#include "../gcode.h"
#include "../../sd/cardreader.h"
/**
* 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

@@ -22,7 +22,7 @@
#include "../../inc/MarlinConfig.h"
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
#include "../gcode.h"
#include "../../sd/cardreader.h"
@@ -51,4 +51,4 @@ void GcodeSuite::M524() {
}
#endif // SDSUPPORT
#endif // HAS_MEDIA

View File

@@ -22,7 +22,7 @@
#include "../../inc/MarlinConfig.h"
#if ENABLED(SDSUPPORT)
#if HAS_MEDIA
#include "../gcode.h"
#include "../../sd/cardreader.h"
@@ -36,4 +36,4 @@ void GcodeSuite::M928() {
}
#endif // SDSUPPORT
#endif // HAS_MEDIA

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
@@ -138,4 +134,4 @@ void GcodeSuite::M104_M109(const bool isM109) {
SERIAL_FLUSH();
}
#endif // EXTRUDERS
#endif // HAS_HOTEND

View File

@@ -85,7 +85,7 @@ void GcodeSuite::M106() {
if (!got_preset && parser.seenval('S'))
speed = parser.value_ushort();
TERN_(FOAMCUTTER_XYUV, speed *= 2.55); // Get command in % of max heat
TERN_(FOAMCUTTER_XYUV, speed *= 2.55f); // Get command in % of max heat
// Set speed, with constraint
thermalManager.set_fan_speed(pfan, speed);

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

@@ -22,7 +22,7 @@
#include "../../inc/MarlinConfig.h"
#if BOTH(AUTO_REPORT_TEMPERATURES, HAS_TEMP_SENSOR)
#if ALL(AUTO_REPORT_TEMPERATURES, HAS_TEMP_SENSOR)
#include "../gcode.h"
#include "../../module/temperature.h"

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"
@@ -78,7 +79,7 @@ void GcodeSuite::M303() {
const celsius_t temp = seenS ? parser.value_celsius() : default_temp;
const bool u = parser.boolval('U');
#if ENABLED(DWIN_LCD_PROUI) && EITHER(PIDTEMP, PIDTEMPBED)
#if ENABLED(DWIN_LCD_PROUI) && ANY(PIDTEMP, PIDTEMPBED)
if (seenC) HMI_data.PidCycles = c;
if (seenS) {
switch (hid) {
@@ -89,13 +90,13 @@ void GcodeSuite::M303() {
}
#endif
#if DISABLED(BUSY_WHILE_HEATING)
KEEPALIVE_STATE(NOT_BUSY);
#endif
IF_DISABLED(BUSY_WHILE_HEATING, KEEPALIVE_STATE(NOT_BUSY));
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());
}