Обновление 2.0.6.1
This commit is contained in:
@@ -405,7 +405,7 @@ inline bool turn_on_heaters() {
|
||||
inline bool prime_nozzle() {
|
||||
|
||||
const feedRate_t fr_slow_e = planner.settings.max_feedrate_mm_s[E_AXIS] / 15.0f;
|
||||
#if HAS_LCD_MENU && DISABLED(TOUCH_BUTTONS) // ui.button_pressed issue with touchscreen
|
||||
#if HAS_LCD_MENU && !HAS_TOUCH_XPT2046 // ui.button_pressed issue with touchscreen
|
||||
#if ENABLED(PREVENT_LENGTHY_EXTRUDE)
|
||||
float Total_Prime = 0.0;
|
||||
#endif
|
||||
@@ -490,7 +490,7 @@ void GcodeSuite::G26() {
|
||||
|
||||
// Don't allow Mesh Validation without homing first,
|
||||
// or if the parameter parsing did not go OK, abort
|
||||
if (axis_unhomed_error()) return;
|
||||
if (homing_needed_error()) return;
|
||||
|
||||
// Change the tool first, if specified
|
||||
if (parser.seenval('T')) tool_change(parser.value_int());
|
||||
|
||||
@@ -176,7 +176,7 @@ void GcodeSuite::G35() {
|
||||
probe.stow();
|
||||
|
||||
// After this operation the Z position needs correction
|
||||
set_axis_not_trusted(Z_AXIS);
|
||||
set_axis_never_homed(Z_AXIS);
|
||||
|
||||
// Home Z after the alignment procedure
|
||||
process_subcommands_now_P(PSTR("G28Z"));
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "../../module/probe.h"
|
||||
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
#include "../../module/configuration_store.h"
|
||||
#include "../../module/settings.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
|
||||
@@ -183,7 +183,7 @@ G29_TYPE GcodeSuite::G29() {
|
||||
faux = ENABLED(DEBUG_LEVELING_FEATURE) && DISABLED(PROBE_MANUALLY) ? parser.boolval('C') : no_action;
|
||||
|
||||
// Don't allow auto-leveling without homing first
|
||||
if (axis_unhomed_error()) G29_RETURN(false);
|
||||
if (homing_needed_error()) G29_RETURN(false);
|
||||
|
||||
if (!no_action && planner.leveling_active && parser.boolval('O')) { // Auto-level only if needed
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("> Auto-level not needed, skip");
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
DEBUG_SECTION(log_G28, "home_z_safely", DEBUGGING(LEVELING));
|
||||
|
||||
// Disallow Z homing if X or Y homing is needed
|
||||
if (axis_unhomed_error(_BV(X_AXIS) | _BV(Y_AXIS))) return;
|
||||
if (homing_needed_error(_BV(X_AXIS) | _BV(Y_AXIS))) return;
|
||||
|
||||
sync_plan_position();
|
||||
|
||||
@@ -299,8 +299,8 @@ void GcodeSuite::G28() {
|
||||
#else // NOT DELTA
|
||||
|
||||
const bool homeZ = parser.seen('Z'),
|
||||
needX = homeZ && TERN0(Z_SAFE_HOMING, axes_need_homing(_BV(X_AXIS))),
|
||||
needY = homeZ && TERN0(Z_SAFE_HOMING, axes_need_homing(_BV(Y_AXIS))),
|
||||
needX = homeZ && TERN0(Z_SAFE_HOMING, axes_should_home(_BV(X_AXIS))),
|
||||
needY = homeZ && TERN0(Z_SAFE_HOMING, axes_should_home(_BV(Y_AXIS))),
|
||||
homeX = needX || parser.seen('X'), homeY = needY || parser.seen('Y'),
|
||||
home_all = homeX == homeY && homeX == homeZ, // All or None
|
||||
doX = home_all || homeX, doY = home_all || homeY, doZ = home_all || homeZ;
|
||||
|
||||
@@ -346,7 +346,7 @@ void GcodeSuite::G34() {
|
||||
|
||||
#if ENABLED(HOME_AFTER_G34)
|
||||
// After this operation the z position needs correction
|
||||
set_axis_not_trusted(Z_AXIS);
|
||||
set_axis_never_homed(Z_AXIS);
|
||||
// Home Z after the alignment procedure
|
||||
process_subcommands_now_P(PSTR("G28Z"));
|
||||
#else
|
||||
|
||||
@@ -584,7 +584,7 @@ void GcodeSuite::G425() {
|
||||
TEMPORARY_SOFT_ENDSTOP_STATE(false);
|
||||
TEMPORARY_BED_LEVELING_STATE(false);
|
||||
|
||||
if (axis_unhomed_error()) return;
|
||||
if (homing_needed_error()) return;
|
||||
|
||||
measurements_t m;
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
* - When calibrating bed, probe temperature is held constant.
|
||||
* Compensation values are deltas to first probe measurement at bed temp. = 60°C.
|
||||
* - The hotend will not be heated at any time.
|
||||
* - On my Prusa MK3S clone I put a piece of paper between the probe and the hotend
|
||||
* - On my Průša MK3S clone I put a piece of paper between the probe and the hotend
|
||||
* so the hotend fan would not cool my probe constantly. Alternativly you could just
|
||||
* make sure the fan is not running while running the calibration process.
|
||||
*
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include "../gcode.h"
|
||||
#include "../queue.h"
|
||||
#include "../../libs/hex_print_routines.h"
|
||||
#include "../../libs/hex_print.h"
|
||||
|
||||
#include "../../MarlinCore.h" // for idle()
|
||||
|
||||
@@ -156,8 +156,8 @@ inline int32_t count_test_bytes(const char * const start_free_memory) {
|
||||
// Start and end the dump on a nice 16 byte boundary
|
||||
// (even though the values are not 16-byte aligned).
|
||||
//
|
||||
start_free_memory = (char*)(ptr_int_t(uint32_t(start_free_memory) & ~0xFUL)); // Align to 16-byte boundary
|
||||
end_free_memory = (char*)(ptr_int_t(uint32_t(end_free_memory) | 0xFUL)); // Align end_free_memory to the 15th byte (at or above end_free_memory)
|
||||
start_free_memory = (char*)(uintptr_t(uint32_t(start_free_memory) & ~0xFUL)); // Align to 16-byte boundary
|
||||
end_free_memory = (char*)(uintptr_t(uint32_t(end_free_memory) | 0xFUL)); // Align end_free_memory to the 15th byte (at or above end_free_memory)
|
||||
|
||||
// Dump command main loop
|
||||
while (start_free_memory < end_free_memory) {
|
||||
@@ -189,8 +189,8 @@ inline int32_t count_test_bytes(const char * const start_free_memory) {
|
||||
// Round the start and end locations to produce full lines of output
|
||||
//
|
||||
dump_free_memory(
|
||||
(char*)(ptr_int_t(uint32_t(start) & ~0xFUL)), // Align to 16-byte boundary
|
||||
(char*)(ptr_int_t(uint32_t(end) | 0xFUL)) // Align end_free_memory to the 15th byte (at or above end_free_memory)
|
||||
(char*)(uintptr_t(uint32_t(start) & ~0xFUL)), // Align to 16-byte boundary
|
||||
(char*)(uintptr_t(uint32_t(end) | 0xFUL)) // Align end_free_memory to the 15th byte (at or above end_free_memory)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,13 +27,10 @@
|
||||
#include "../gcode.h"
|
||||
#include "../../module/motion.h"
|
||||
#include "../../module/probe.h"
|
||||
#include "../../lcd/ultralcd.h"
|
||||
|
||||
#include "../../feature/bedlevel/bedlevel.h"
|
||||
|
||||
#if HAS_SPI_LCD
|
||||
#include "../../lcd/ultralcd.h"
|
||||
#endif
|
||||
|
||||
#if HAS_LEVELING
|
||||
#include "../../module/planner.h"
|
||||
#endif
|
||||
@@ -58,7 +55,7 @@ extern const char SP_Y_STR[];
|
||||
|
||||
void GcodeSuite::M48() {
|
||||
|
||||
if (axis_unhomed_error()) return;
|
||||
if (homing_needed_error()) return;
|
||||
|
||||
const int8_t verbose_level = parser.byteval('V', 1);
|
||||
if (!WITHIN(verbose_level, 0, 4)) {
|
||||
@@ -77,61 +74,85 @@ void GcodeSuite::M48() {
|
||||
|
||||
const ProbePtRaise raise_after = parser.boolval('E') ? PROBE_PT_STOW : PROBE_PT_RAISE;
|
||||
|
||||
xy_float_t next_pos = current_position;
|
||||
|
||||
const xy_pos_t probe_pos = {
|
||||
parser.linearval('X', next_pos.x + probe.offset_xy.x), // If no X use the probe's current X position
|
||||
parser.linearval('Y', next_pos.y + probe.offset_xy.y) // If no Y, ditto
|
||||
// Test at the current position by default, overridden by X and Y
|
||||
const xy_pos_t test_position = {
|
||||
parser.linearval('X', current_position.x + probe.offset_xy.x), // If no X use the probe's current X position
|
||||
parser.linearval('Y', current_position.y + probe.offset_xy.y) // If no Y, ditto
|
||||
};
|
||||
|
||||
if (!probe.can_reach(probe_pos)) {
|
||||
if (!probe.can_reach(test_position)) {
|
||||
ui.set_status_P(GET_TEXT(MSG_M48_OUT_OF_BOUNDS), 99);
|
||||
SERIAL_ECHOLNPGM("? (X,Y) out of bounds.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the number of leg moves per test-point
|
||||
bool seen_L = parser.seen('L');
|
||||
uint8_t n_legs = seen_L ? parser.value_byte() : 0;
|
||||
if (n_legs > 15) {
|
||||
SERIAL_ECHOLNPGM("?Number of legs in movement not plausible (0-15).");
|
||||
SERIAL_ECHOLNPGM("?Legs of movement implausible (0-15).");
|
||||
return;
|
||||
}
|
||||
if (n_legs == 1) n_legs = 2;
|
||||
|
||||
// Schizoid motion as an optional stress-test
|
||||
const bool schizoid_flag = parser.boolval('S');
|
||||
if (schizoid_flag && !seen_L) n_legs = 7;
|
||||
|
||||
/**
|
||||
* Now get everything to the specified probe point So we can safely do a
|
||||
* probe to get us close to the bed. If the Z-Axis is far from the bed,
|
||||
* we don't want to use that as a starting point for each probe.
|
||||
*/
|
||||
if (verbose_level > 2)
|
||||
SERIAL_ECHOLNPGM("Positioning the probe...");
|
||||
|
||||
// Disable bed level correction in M48 because we want the raw data when we probe
|
||||
// Always disable Bed Level correction before probing...
|
||||
|
||||
#if HAS_LEVELING
|
||||
const bool was_enabled = planner.leveling_active;
|
||||
set_bed_leveling_enabled(false);
|
||||
#endif
|
||||
|
||||
// Work with reasonable feedrates
|
||||
remember_feedrate_scaling_off();
|
||||
|
||||
float mean = 0.0, sigma = 0.0, min = 99999.9, max = -99999.9, sample_set[n_samples];
|
||||
// Working variables
|
||||
float mean = 0.0, // The average of all points so far, used to calculate deviation
|
||||
sigma = 0.0, // Standard deviation of all points so far
|
||||
min = 99999.9, // Smallest value sampled so far
|
||||
max = -99999.9, // Largest value sampled so far
|
||||
sample_set[n_samples]; // Storage for sampled values
|
||||
|
||||
auto dev_report = [](const bool verbose, const float &mean, const float &sigma, const float &min, const float &max, const bool final=false) {
|
||||
if (verbose) {
|
||||
SERIAL_ECHOPAIR_F("Mean: ", mean, 6);
|
||||
if (!final) SERIAL_ECHOPAIR_F(" Sigma: ", sigma, 6);
|
||||
SERIAL_ECHOPAIR_F(" Min: ", min, 3);
|
||||
SERIAL_ECHOPAIR_F(" Max: ", max, 3);
|
||||
SERIAL_ECHOPAIR_F(" Range: ", max-min, 3);
|
||||
if (final) SERIAL_EOL();
|
||||
}
|
||||
if (final) {
|
||||
SERIAL_ECHOLNPAIR_F("Standard Deviation: ", sigma, 6);
|
||||
SERIAL_EOL();
|
||||
}
|
||||
};
|
||||
|
||||
// Move to the first point, deploy, and probe
|
||||
const float t = probe.probe_at_point(probe_pos, raise_after, verbose_level);
|
||||
const float t = probe.probe_at_point(test_position, raise_after, verbose_level);
|
||||
bool probing_good = !isnan(t);
|
||||
|
||||
if (probing_good) {
|
||||
randomSeed(millis());
|
||||
|
||||
float sample_sum = 0.0;
|
||||
|
||||
LOOP_L_N(n, n_samples) {
|
||||
#if HAS_SPI_LCD
|
||||
// Display M48 progress in the status bar
|
||||
ui.status_printf_P(0, PSTR(S_FMT ": %d/%d"), GET_TEXT(MSG_M48_POINT), int(n + 1), int(n_samples));
|
||||
#endif
|
||||
|
||||
// When there are "legs" of movement move around the point before probing
|
||||
if (n_legs) {
|
||||
|
||||
// Pick a random direction, starting angle, and radius
|
||||
const int dir = (random(0, 10) > 5.0) ? -1 : 1; // clockwise or counter clockwise
|
||||
float angle = random(0, 360);
|
||||
const float radius = random(
|
||||
@@ -142,48 +163,51 @@ void GcodeSuite::M48() {
|
||||
int(5), int(0.125 * _MIN(X_BED_SIZE, Y_BED_SIZE))
|
||||
#endif
|
||||
);
|
||||
|
||||
if (verbose_level > 3) {
|
||||
SERIAL_ECHOPAIR("Start radius:", radius, " angle:", angle, " dir:");
|
||||
if (dir > 0) SERIAL_CHAR('C');
|
||||
SERIAL_ECHOLNPGM("CW");
|
||||
}
|
||||
|
||||
// Move from leg to leg in rapid succession
|
||||
LOOP_L_N(l, n_legs - 1) {
|
||||
float delta_angle;
|
||||
|
||||
// Move some distance around the perimeter
|
||||
float delta_angle;
|
||||
if (schizoid_flag) {
|
||||
// The points of a 5 point star are 72 degrees apart. We need to
|
||||
// skip a point and go to the next one on the star.
|
||||
// The points of a 5 point star are 72 degrees apart.
|
||||
// Skip a point and go to the next one on the star.
|
||||
delta_angle = dir * 2.0 * 72.0;
|
||||
}
|
||||
else {
|
||||
// If we do this line, we are just trying to move further
|
||||
// around the circle.
|
||||
delta_angle = dir * (float) random(25, 45);
|
||||
// Just move further along the perimeter.
|
||||
delta_angle = dir * (float)random(25, 45);
|
||||
}
|
||||
|
||||
angle += delta_angle;
|
||||
while (angle > 360.0) angle -= 360.0; // We probably do not need to keep the angle between 0 and 2*PI, but the
|
||||
// Arduino documentation says the trig functions should not be given values
|
||||
while (angle < 0.0) angle += 360.0; // outside of this range. It looks like they behave correctly with
|
||||
// numbers outside of the range, but just to be safe we clamp them.
|
||||
|
||||
const xy_pos_t noz_pos = probe_pos - probe.offset_xy;
|
||||
next_pos.set(noz_pos.x + cos(RADIANS(angle)) * radius,
|
||||
noz_pos.y + sin(RADIANS(angle)) * radius);
|
||||
// Trig functions work without clamping, but just to be safe...
|
||||
while (angle > 360.0) angle -= 360.0;
|
||||
while (angle < 0.0) angle += 360.0;
|
||||
|
||||
#if DISABLED(DELTA)
|
||||
LIMIT(next_pos.x, X_MIN_POS, X_MAX_POS);
|
||||
LIMIT(next_pos.y, Y_MIN_POS, Y_MAX_POS);
|
||||
#else
|
||||
// If we have gone out too far, we can do a simple fix and scale the numbers
|
||||
// back in closer to the origin.
|
||||
// Choose the next position as an offset to chosen test position
|
||||
const xy_pos_t noz_pos = test_position - probe.offset_xy;
|
||||
xy_pos_t next_pos = {
|
||||
noz_pos.x + cos(RADIANS(angle)) * radius,
|
||||
noz_pos.y + sin(RADIANS(angle)) * radius
|
||||
};
|
||||
|
||||
#if ENABLED(DELTA)
|
||||
// If the probe can't reach the point on a round bed...
|
||||
// Simply scale the numbers to bring them closer to origin.
|
||||
while (!probe.can_reach(next_pos)) {
|
||||
next_pos *= 0.8f;
|
||||
if (verbose_level > 3)
|
||||
SERIAL_ECHOLNPAIR_P(PSTR("Moving inward: X"), next_pos.x, SP_Y_STR, next_pos.y);
|
||||
}
|
||||
#else
|
||||
// For a rectangular bed just keep the probe in bounds
|
||||
LIMIT(next_pos.x, X_MIN_POS, X_MAX_POS);
|
||||
LIMIT(next_pos.y, Y_MIN_POS, Y_MAX_POS);
|
||||
#endif
|
||||
|
||||
if (verbose_level > 3)
|
||||
@@ -194,45 +218,35 @@ void GcodeSuite::M48() {
|
||||
} // n_legs
|
||||
|
||||
// Probe a single point
|
||||
sample_set[n] = probe.probe_at_point(probe_pos, raise_after, 0);
|
||||
const float pz = probe.probe_at_point(test_position, raise_after, 0);
|
||||
|
||||
// Break the loop if the probe fails
|
||||
probing_good = !isnan(sample_set[n]);
|
||||
probing_good = !isnan(pz);
|
||||
if (!probing_good) break;
|
||||
|
||||
/**
|
||||
* Get the current mean for the data points we have so far
|
||||
*/
|
||||
float sum = 0.0;
|
||||
LOOP_LE_N(j, n) sum += sample_set[j];
|
||||
mean = sum / (n + 1);
|
||||
// Store the new sample
|
||||
sample_set[n] = pz;
|
||||
|
||||
NOMORE(min, sample_set[n]);
|
||||
NOLESS(max, sample_set[n]);
|
||||
// Keep track of the largest and smallest samples
|
||||
NOMORE(min, pz);
|
||||
NOLESS(max, pz);
|
||||
|
||||
/**
|
||||
* Now, use that mean to calculate the standard deviation for the
|
||||
* data points we have so far
|
||||
*/
|
||||
sum = 0.0;
|
||||
LOOP_LE_N(j, n)
|
||||
sum += sq(sample_set[j] - mean);
|
||||
// Get the mean value of all samples thus far
|
||||
sample_sum += pz;
|
||||
mean = sample_sum / (n + 1);
|
||||
|
||||
sigma = SQRT(sum / (n + 1));
|
||||
if (verbose_level > 0) {
|
||||
if (verbose_level > 1) {
|
||||
SERIAL_ECHO(n + 1);
|
||||
SERIAL_ECHOPAIR(" of ", int(n_samples));
|
||||
SERIAL_ECHOPAIR_F(": z: ", sample_set[n], 3);
|
||||
if (verbose_level > 2) {
|
||||
SERIAL_ECHOPAIR_F(" mean: ", mean, 4);
|
||||
SERIAL_ECHOPAIR_F(" sigma: ", sigma, 6);
|
||||
SERIAL_ECHOPAIR_F(" min: ", min, 3);
|
||||
SERIAL_ECHOPAIR_F(" max: ", max, 3);
|
||||
SERIAL_ECHOPAIR_F(" range: ", max-min, 3);
|
||||
}
|
||||
SERIAL_EOL();
|
||||
}
|
||||
// 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);
|
||||
sigma = SQRT(dev_sum / (n + 1));
|
||||
|
||||
if (verbose_level > 1) {
|
||||
SERIAL_ECHO(n + 1);
|
||||
SERIAL_ECHOPAIR(" of ", int(n_samples));
|
||||
SERIAL_ECHOPAIR_F(": z: ", pz, 3);
|
||||
dev_report(verbose_level > 2, mean, sigma, min, max);
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
||||
} // n_samples loop
|
||||
@@ -242,16 +256,7 @@ void GcodeSuite::M48() {
|
||||
|
||||
if (probing_good) {
|
||||
SERIAL_ECHOLNPGM("Finished!");
|
||||
|
||||
if (verbose_level > 0) {
|
||||
SERIAL_ECHOPAIR_F("Mean: ", mean, 6);
|
||||
SERIAL_ECHOPAIR_F(" Min: ", min, 3);
|
||||
SERIAL_ECHOPAIR_F(" Max: ", max, 3);
|
||||
SERIAL_ECHOLNPAIR_F(" Range: ", max-min, 3);
|
||||
}
|
||||
|
||||
SERIAL_ECHOLNPAIR_F("Standard Deviation: ", sigma, 6);
|
||||
SERIAL_EOL();
|
||||
dev_report(verbose_level > 0, mean, sigma, min, max, true);
|
||||
|
||||
#if HAS_SPI_LCD
|
||||
// Display M48 results in the status bar
|
||||
|
||||
@@ -33,7 +33,21 @@
|
||||
* B<baudrate> - Baud rate (bits per second)
|
||||
*/
|
||||
void GcodeSuite::M575() {
|
||||
const int32_t baud = parser.ulongval('B');
|
||||
int32_t baud = parser.ulongval('B');
|
||||
switch (baud) {
|
||||
case 24:
|
||||
case 96:
|
||||
case 192:
|
||||
case 384:
|
||||
case 576:
|
||||
case 1152: baud *= 100; break;
|
||||
case 250:
|
||||
case 500: baud *= 1000; break;
|
||||
case 19: baud = 19200; break;
|
||||
case 38: baud = 38400; break;
|
||||
case 57: baud = 57600; break;
|
||||
case 115: baud = 115200; break;
|
||||
}
|
||||
switch (baud) {
|
||||
case 2400: case 9600: case 19200: case 38400: case 57600:
|
||||
case 115200: case 250000: case 500000: case 1000000: {
|
||||
|
||||
@@ -22,20 +22,12 @@
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD)
|
||||
#if ENABLED(DUET_SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD)
|
||||
|
||||
#include "../gcode.h"
|
||||
#include "../../HAL/shared/Delay.h"
|
||||
#include "../parser.h"
|
||||
|
||||
/**
|
||||
* M672 - Set/reset Duet Smart Effector sensitivity
|
||||
*
|
||||
* One of these is required:
|
||||
* S<sensitivity> - 0-255
|
||||
* R - Flag to reset sensitivity to default
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Marlin format for the M672 command is different than shown in the Duet Smart Effector
|
||||
* documentation https://duet3d.dozuki.com/Wiki/Smart_effector_and_carriage_adapters_for_delta_printer
|
||||
@@ -77,6 +69,13 @@ void M672_send(uint8_t b) { // bit rate requirement: 1KHz +/- 30%
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* M672 - Set/reset Duet Smart Effector sensitivity
|
||||
*
|
||||
* One of these is required:
|
||||
* S<sensitivity> - 0-255
|
||||
* R - Flag to reset sensitivity to default
|
||||
*/
|
||||
void GcodeSuite::M672() {
|
||||
if (parser.seen('R')) {
|
||||
M672_send(M672_ERASEBYTE);
|
||||
@@ -96,4 +95,4 @@ void GcodeSuite::M672() {
|
||||
OUT_WRITE(SMART_EFFECTOR_MOD_PIN, LOW); // Keep Smart Effector in NORMAL mode
|
||||
}
|
||||
|
||||
#endif // SMART_EFFECTOR && SMART_EFFECTOR_MOD_PIN
|
||||
#endif // DUET_SMART_EFFECTOR && SMART_EFFECTOR_MOD_PIN
|
||||
|
||||
@@ -21,16 +21,14 @@
|
||||
*/
|
||||
|
||||
#include "../gcode.h"
|
||||
|
||||
#include "../../module/temperature.h"
|
||||
#include "../../module/stepper.h"
|
||||
#include "../../module/printcounter.h" // for print_job_timer
|
||||
#include "../../module/planner.h" // for planner.finish_and_disable
|
||||
#include "../../module/printcounter.h" // for print_job_timer.stop
|
||||
#include "../../lcd/ultralcd.h" // for LCD_MESSAGEPGM_P
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if HAS_LCD_MENU
|
||||
#include "../../lcd/ultralcd.h"
|
||||
#endif
|
||||
|
||||
#if HAS_SUICIDE
|
||||
#include "../../MarlinCore.h"
|
||||
#endif
|
||||
@@ -39,6 +37,8 @@
|
||||
|
||||
#if ENABLED(AUTO_POWER_CONTROL)
|
||||
#include "../../feature/power.h"
|
||||
#else
|
||||
void restore_stepper_drivers();
|
||||
#endif
|
||||
|
||||
// Could be moved to a feature, but this is all the data
|
||||
@@ -108,7 +108,5 @@ void GcodeSuite::M81() {
|
||||
PSU_OFF();
|
||||
#endif
|
||||
|
||||
#if HAS_LCD_MENU
|
||||
LCD_MESSAGEPGM_P(PSTR(MACHINE_NAME " " STR_OFF "."));
|
||||
#endif
|
||||
LCD_MESSAGEPGM_P(PSTR(MACHINE_NAME " " STR_OFF "."));
|
||||
}
|
||||
|
||||
92
Marlin/src/gcode/control/M993_M994.cpp
Normal file
92
Marlin/src/gcode/control/M993_M994.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if ALL(HAS_SPI_FLASH, SDSUPPORT, MARLIN_DEV_MODE)
|
||||
|
||||
#include "../gcode.h"
|
||||
#include "../../sd/cardreader.h"
|
||||
#include "../../libs/W25Qxx.h"
|
||||
|
||||
/**
|
||||
* M993: Backup SPI Flash to SD
|
||||
*/
|
||||
void GcodeSuite::M993() {
|
||||
if (!card.isMounted()) card.mount();
|
||||
|
||||
char fname[] = "spiflash.bin";
|
||||
card.openFileWrite(fname);
|
||||
if (!card.isFileOpen()) {
|
||||
SERIAL_ECHOLNPAIR("Failed to open ", fname, " to write.");
|
||||
return;
|
||||
}
|
||||
|
||||
W25QXXFlash W25QXX;
|
||||
|
||||
uint8_t buf[1024];
|
||||
uint32_t addr = 0;
|
||||
W25QXX.init(SPI_QUARTER_SPEED);
|
||||
SERIAL_ECHOPGM("Save SPI Flash");
|
||||
while (addr < SPI_FLASH_SIZE) {
|
||||
W25QXX.SPI_FLASH_BufferRead(buf, addr, COUNT(buf));
|
||||
addr += COUNT(buf);
|
||||
card.write(buf, COUNT(buf));
|
||||
if (addr % (COUNT(buf) * 10) == 0) SERIAL_CHAR('.');
|
||||
}
|
||||
SERIAL_ECHOLNPGM(" done");
|
||||
|
||||
card.closefile();
|
||||
}
|
||||
|
||||
/**
|
||||
* M994: Load a backup from SD to SPI Flash
|
||||
*/
|
||||
void GcodeSuite::M994() {
|
||||
if (!card.isMounted()) card.mount();
|
||||
|
||||
char fname[] = "spiflash.bin";
|
||||
card.openFileRead(fname);
|
||||
if (!card.isFileOpen()) {
|
||||
SERIAL_ECHOLNPAIR("Failed to open ", fname, " to read.");
|
||||
return;
|
||||
}
|
||||
|
||||
W25QXXFlash W25QXX;
|
||||
|
||||
uint8_t buf[1024];
|
||||
uint32_t addr = 0;
|
||||
W25QXX.init(SPI_QUARTER_SPEED);
|
||||
W25QXX.SPI_FLASH_BulkErase();
|
||||
SERIAL_ECHOPGM("Load SPI Flash");
|
||||
while(addr < SPI_FLASH_SIZE) {
|
||||
card.read(buf, COUNT(buf));
|
||||
W25QXX.SPI_FLASH_BufferWrite(buf, addr, COUNT(buf));
|
||||
addr += COUNT(buf);
|
||||
if (addr % (COUNT(buf) * 10) == 0) SERIAL_CHAR('.');
|
||||
}
|
||||
SERIAL_ECHOLNPGM(" done");
|
||||
|
||||
card.closefile();
|
||||
}
|
||||
|
||||
#endif // HAS_SPI_FLASH && SDSUPPORT && MARLIN_DEV_MODE
|
||||
@@ -28,7 +28,9 @@
|
||||
* M997: Perform in-application firmware update
|
||||
*/
|
||||
void GcodeSuite::M997() {
|
||||
|
||||
flashFirmware(parser.intval('S'));
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "../gcode.h"
|
||||
#include "../../module/configuration_store.h"
|
||||
#include "../../module/settings.h"
|
||||
#include "../../core/serial.h"
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
@@ -60,7 +60,7 @@ void GcodeSuite::M502() {
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
|
||||
#if ENABLED(MARLIN_DEV_MODE)
|
||||
#include "../../libs/hex_print_routines.h"
|
||||
#include "../../libs/hex_print.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -126,7 +126,7 @@ void GcodeSuite::M240() {
|
||||
|
||||
#ifdef PHOTO_POSITION
|
||||
|
||||
if (axis_unhomed_error()) return;
|
||||
if (homing_needed_error()) return;
|
||||
|
||||
const xyz_pos_t old_pos = {
|
||||
current_position.x + parser.linearval('A'),
|
||||
|
||||
@@ -20,45 +20,47 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../../gcode.h"
|
||||
|
||||
#include "../../../inc/MarlinConfig.h"
|
||||
|
||||
#if HAS_CASE_LIGHT
|
||||
#include "../../../feature/caselight.h"
|
||||
#if ENABLED(CASE_LIGHT_ENABLE)
|
||||
|
||||
/**
|
||||
* M355: Turn case light on/off and set brightness
|
||||
*
|
||||
* P<byte> Set case light brightness (PWM pin required - ignored otherwise)
|
||||
*
|
||||
* S<bool> Set case light on/off
|
||||
*
|
||||
* When S turns on the light on a PWM pin then the current brightness level is used/restored
|
||||
*
|
||||
* M355 P200 S0 turns off the light & sets the brightness level
|
||||
* M355 S1 turns on the light with a brightness of 200 (assuming a PWM pin)
|
||||
*/
|
||||
void GcodeSuite::M355() {
|
||||
uint8_t args = 0;
|
||||
if (parser.seenval('P')) {
|
||||
++args, case_light_brightness = parser.value_byte();
|
||||
case_light_arg_flag = false;
|
||||
}
|
||||
if (parser.seenval('S')) {
|
||||
++args, case_light_on = parser.value_bool();
|
||||
case_light_arg_flag = true;
|
||||
}
|
||||
if (args) update_case_light();
|
||||
#include "../../../feature/caselight.h"
|
||||
#include "../../gcode.h"
|
||||
|
||||
// always report case light status
|
||||
SERIAL_ECHO_START();
|
||||
if (!case_light_on) {
|
||||
SERIAL_ECHOLNPGM("Case light: off");
|
||||
}
|
||||
else {
|
||||
if (!PWM_PIN(CASE_LIGHT_PIN)) SERIAL_ECHOLNPGM("Case light: on");
|
||||
else SERIAL_ECHOLNPAIR("Case light: ", case_light_brightness);
|
||||
}
|
||||
/**
|
||||
* M355: Turn case light on/off and set brightness
|
||||
*
|
||||
* P<byte> Set case light brightness (PWM pin required - ignored otherwise)
|
||||
*
|
||||
* S<bool> Set case light on/off
|
||||
*
|
||||
* When S turns on the light on a PWM pin then the current brightness level is used/restored
|
||||
*
|
||||
* M355 P200 S0 turns off the light & sets the brightness level
|
||||
* M355 S1 turns on the light with a brightness of 200 (assuming a PWM pin)
|
||||
*/
|
||||
void GcodeSuite::M355() {
|
||||
bool didset = false;
|
||||
if (parser.seenval('P')) {
|
||||
didset = true;
|
||||
caselight.brightness = parser.value_byte();
|
||||
}
|
||||
#endif // HAS_CASE_LIGHT
|
||||
const bool sflag = parser.seenval('S');
|
||||
if (sflag) {
|
||||
didset = true;
|
||||
caselight.on = parser.value_bool();
|
||||
}
|
||||
if (didset) caselight.update(sflag);
|
||||
|
||||
// Always report case light status
|
||||
SERIAL_ECHO_START();
|
||||
SERIAL_ECHOPGM("Case light: ");
|
||||
if (!caselight.on)
|
||||
SERIAL_ECHOLNPGM(STR_OFF);
|
||||
else {
|
||||
if (!PWM_PIN(CASE_LIGHT_PIN)) SERIAL_ECHOLNPGM(STR_ON);
|
||||
else SERIAL_ECHOLN(int(caselight.brightness));
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CASE_LIGHT_ENABLE
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
*/
|
||||
void GcodeSuite::G12() {
|
||||
// Don't allow nozzle cleaning without homing first
|
||||
if (axis_unhomed_error()) return;
|
||||
if (homing_needed_error()) return;
|
||||
|
||||
#ifdef WIPE_SEQUENCE_COMMANDS
|
||||
if (!parser.seen_any()) {
|
||||
|
||||
@@ -35,7 +35,10 @@
|
||||
* If brightness is left out, no value changed
|
||||
*
|
||||
* With NEOPIXEL_LED:
|
||||
* I<index> Set the Neopixel index to affect. Default: All
|
||||
* I<index> Set the NeoPixel index to affect. Default: All
|
||||
*
|
||||
* With NEOPIXEL2_SEPARATE:
|
||||
* S<index> The NeoPixel strip to set. Default is index 0.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
@@ -47,18 +50,35 @@
|
||||
* M150 P127 ; Set LED 50% brightness
|
||||
* M150 P ; Set LED full brightness
|
||||
* M150 I1 R ; Set NEOPIXEL index 1 to red
|
||||
* M150 S1 I1 R ; Set SEPARATE index 1 to red
|
||||
*/
|
||||
|
||||
void GcodeSuite::M150() {
|
||||
#if ENABLED(NEOPIXEL_LED)
|
||||
neo.set_neo_index(parser.intval('I', -1));
|
||||
const uint8_t index = parser.intval('I', -1);
|
||||
#if ENABLED(NEOPIXEL2_SEPARATE)
|
||||
const uint8_t unit = parser.intval('S'),
|
||||
brightness = unit ? neo2.brightness() : neo.brightness();
|
||||
*(unit ? &neo2.neoindex : &neo.neoindex) = index;
|
||||
#else
|
||||
const uint8_t brightness = neo.brightness();
|
||||
neo.neoindex = index;
|
||||
#endif
|
||||
#endif
|
||||
leds.set_color(MakeLEDColor(
|
||||
|
||||
const LEDColor color = MakeLEDColor(
|
||||
parser.seen('R') ? (parser.has_value() ? parser.value_byte() : 255) : 0,
|
||||
parser.seen('U') ? (parser.has_value() ? parser.value_byte() : 255) : 0,
|
||||
parser.seen('B') ? (parser.has_value() ? parser.value_byte() : 255) : 0,
|
||||
parser.seen('W') ? (parser.has_value() ? parser.value_byte() : 255) : 0,
|
||||
parser.seen('P') ? (parser.has_value() ? parser.value_byte() : 255) : neo.brightness()
|
||||
));
|
||||
parser.seen('P') ? (parser.has_value() ? parser.value_byte() : 255) : brightness
|
||||
);
|
||||
|
||||
#if ENABLED(NEOPIXEL2_SEPARATE)
|
||||
if (unit == 1) { leds2.set_color(color); return; }
|
||||
#endif
|
||||
|
||||
leds.set_color(color);
|
||||
}
|
||||
|
||||
#endif // HAS_COLOR_LEDS
|
||||
|
||||
83
Marlin/src/gcode/feature/password/M510-M512.cpp
Normal file
83
Marlin/src/gcode/feature/password/M510-M512.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if ENABLED(PASSWORD_FEATURE)
|
||||
|
||||
#include "../../../feature/password/password.h"
|
||||
#include "../../../core/serial.h"
|
||||
#include "../../gcode.h"
|
||||
|
||||
//
|
||||
// M510: Lock Printer
|
||||
//
|
||||
void GcodeSuite::M510() {
|
||||
password.lock_machine();
|
||||
}
|
||||
|
||||
//
|
||||
// M511: Unlock Printer
|
||||
//
|
||||
#if ENABLED(PASSWORD_UNLOCK_GCODE)
|
||||
|
||||
void GcodeSuite::M511() {
|
||||
if (password.is_locked) {
|
||||
password.value_entry = parser.ulongval('P');
|
||||
password.authentication_check();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PASSWORD_UNLOCK_GCODE
|
||||
|
||||
//
|
||||
// M512: Set/Change/Remove Password
|
||||
//
|
||||
#if ENABLED(PASSWORD_CHANGE_GCODE)
|
||||
|
||||
void GcodeSuite::M512() {
|
||||
if (password.is_set && parser.ulongval('P') != password.value) {
|
||||
SERIAL_ECHOLNPGM(STR_WRONG_PASSWORD);
|
||||
return;
|
||||
}
|
||||
|
||||
if (parser.seenval('S')) {
|
||||
password.value_entry = parser.ulongval('S');
|
||||
|
||||
if (password.value_entry < CAT(1e, PASSWORD_LENGTH)) {
|
||||
password.is_set = true;
|
||||
password.value = password.value_entry;
|
||||
SERIAL_ECHOLNPAIR(STR_PASSWORD_SET, password.value); // TODO: Update password.string
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM(STR_PASSWORD_TOO_LONG);
|
||||
}
|
||||
else {
|
||||
password.is_set = false;
|
||||
SERIAL_ECHOLNPGM(STR_PASSWORD_REMOVED);
|
||||
}
|
||||
SERIAL_ECHOLNPGM(STR_REMINDER_SAVE_SETTINGS);
|
||||
}
|
||||
|
||||
#endif // PASSWORD_CHANGE_GCODE
|
||||
|
||||
#endif // PASSWORD_FEATURE
|
||||
@@ -34,7 +34,7 @@
|
||||
*/
|
||||
void GcodeSuite::G27() {
|
||||
// Don't allow nozzle parking without homing first
|
||||
if (axis_unhomed_error()) return;
|
||||
if (homing_needed_error()) return;
|
||||
nozzle.park(parser.ushortval('P'));
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ void GcodeSuite::M701() {
|
||||
|
||||
#if ENABLED(NO_MOTION_BEFORE_HOMING)
|
||||
// Don't raise Z if the machine isn't homed
|
||||
if (axes_need_homing()) park_point.z = 0;
|
||||
if (axes_should_home()) park_point.z = 0;
|
||||
#endif
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
@@ -149,7 +149,7 @@ void GcodeSuite::M702() {
|
||||
|
||||
#if ENABLED(NO_MOTION_BEFORE_HOMING)
|
||||
// Don't raise Z if the machine isn't homed
|
||||
if (axes_need_homing()) park_point.z = 0;
|
||||
if (axes_should_home()) park_point.z = 0;
|
||||
#endif
|
||||
|
||||
#if ENABLED(MIXING_EXTRUDER)
|
||||
|
||||
@@ -61,6 +61,10 @@ GcodeSuite gcode;
|
||||
#include "../feature/spindle_laser.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(PASSWORD_FEATURE)
|
||||
#include "../feature/password/password.h"
|
||||
#endif
|
||||
|
||||
#include "../MarlinCore.h" // for idle()
|
||||
|
||||
// Inactivity shutdown
|
||||
@@ -245,7 +249,20 @@ void GcodeSuite::dwell(millis_t time) {
|
||||
void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
KEEPALIVE_STATE(IN_HANDLER);
|
||||
|
||||
DEBUG("Cmd %c %d",parser.command_letter,parser.codenum);
|
||||
#if ENABLED(MKS_WIFI)
|
||||
DEBUG("Gcode: %c %d",parser.command_letter,parser.codenum);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Block all Gcodes except M511 Unlock Printer, if printer is locked
|
||||
* Will still block Gcodes if M511 is disabled, in which case the printer should be unlocked via LCD Menu
|
||||
*/
|
||||
#if ENABLED(PASSWORD_FEATURE)
|
||||
if (password.is_locked && !(parser.command_letter == 'M' && parser.codenum == 511)) {
|
||||
SERIAL_ECHO_MSG(STR_PRINTER_LOCKED);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Handle a known G, M, or T
|
||||
switch (parser.command_letter) {
|
||||
@@ -791,6 +808,16 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 504: M504(); break; // M504: Validate EEPROM contents
|
||||
#endif
|
||||
|
||||
#if ENABLED(PASSWORD_FEATURE)
|
||||
case 510: M510(); break; // M510: Lock Printer
|
||||
#if ENABLED(PASSWORD_UNLOCK_GCODE)
|
||||
case 511: M511(); break; // M511: Unlock Printer
|
||||
#endif
|
||||
#if ENABLED(PASSWORD_CHANGE_GCODE)
|
||||
case 512: M512(); break;
|
||||
#endif // M512: Set/Change/Remove Password
|
||||
#endif
|
||||
|
||||
#if ENABLED(SDSUPPORT)
|
||||
case 524: M524(); break; // M524: Abort the current SD print job
|
||||
#endif
|
||||
@@ -820,7 +847,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 666: M666(); break; // M666: Set delta or multiple endstop adjustment
|
||||
#endif
|
||||
|
||||
#if ENABLED(SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD)
|
||||
#if ENABLED(DUET_SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD)
|
||||
case 672: M672(); break; // M672: Set/clear Duet Smart Effector sensitivity
|
||||
#endif
|
||||
|
||||
@@ -897,7 +924,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 351: M351(); break; // M351: Toggle MS1 MS2 pins directly, S# determines MS1 or MS2, X# sets the pin high/low.
|
||||
#endif
|
||||
|
||||
#if HAS_CASE_LIGHT
|
||||
#if ENABLED(CASE_LIGHT_ENABLE)
|
||||
case 355: M355(); break; // M355: Set case light brightness
|
||||
#endif
|
||||
|
||||
@@ -926,14 +953,34 @@ 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(HAS_SPI_FLASH, SDSUPPORT, MARLIN_DEV_MODE)
|
||||
case 993: M993(); break; // M993: Backup SPI Flash to SD
|
||||
case 994: M994(); break; // M994: Load a Backup from SD to SPI Flash
|
||||
#endif
|
||||
|
||||
#if ENABLED(TOUCH_SCREEN_CALIBRATION)
|
||||
case 995: M995(); break; // M995: Touch screen calibration for TFT display
|
||||
#endif
|
||||
|
||||
#if ENABLED(MKS_WIFI)
|
||||
case 991: if ( serial_port_index) {mks_m991();}; return;
|
||||
case 997: if ( serial_port_index) {mks_m997();}; return;
|
||||
#endif
|
||||
|
||||
|
||||
#if ENABLED(MKS_WIFI)
|
||||
case 997: if ( serial_port_index) {
|
||||
mks_m997();
|
||||
}else{
|
||||
#if ENABLED(PLATFORM_M997_SUPPORT)
|
||||
M997();
|
||||
#endif
|
||||
};
|
||||
return;
|
||||
#else
|
||||
#if ENABLED(PLATFORM_M997_SUPPORT)
|
||||
case 997: M997(); break; // M997: Perform in-application firmware update
|
||||
#endif
|
||||
#endif
|
||||
|
||||
case 999: M999(); break; // M999: Restart after being Stopped
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
* M141 - Set heated chamber target temp. S<temp> (Requires a chamber heater)
|
||||
* M145 - Set heatup values for materials on the LCD. H<hotend> B<bed> F<fan speed> for S<material> (0=PLA, 1=ABS)
|
||||
* M149 - Set temperature units. (Requires TEMPERATURE_UNITS_SUPPORT)
|
||||
* M150 - Set Status LED Color as R<red> U<green> B<blue> P<bright>. Values 0-255. (Requires BLINKM, RGB_LED, RGBW_LED, NEOPIXEL_LED, PCA9533, or PCA9632).
|
||||
* M150 - Set Status LED Color as R<red> U<green> B<blue> W<white> P<bright>. Values 0-255. (Requires BLINKM, RGB_LED, RGBW_LED, NEOPIXEL_LED, PCA9533, or PCA9632).
|
||||
* M155 - Auto-report temperatures with interval of S<seconds>. (Requires AUTO_REPORT_TEMPERATURES)
|
||||
* M163 - Set a single proportion for a mixing extruder. (Requires MIXING_EXTRUDER)
|
||||
* M164 - Commit the mix and save to a virtual tool (current, or as specified by 'S'). (Requires MIXING_EXTRUDER)
|
||||
@@ -225,6 +225,9 @@
|
||||
* M502 - Revert to the default "factory settings". ** Does not write them to EEPROM! **
|
||||
* M503 - Print the current settings (in memory): "M503 S<verbose>". S0 specifies compact output.
|
||||
* M504 - Validate EEPROM contents. (Requires EEPROM_SETTINGS)
|
||||
* M510 - Lock Printer
|
||||
* M511 - Unlock Printer
|
||||
* M512 - Set/Change/Remove Password
|
||||
* M524 - Abort the current SD print job started with M24. (Requires SDSUPPORT)
|
||||
* M540 - Enable/disable SD card abort on endstop hit: "M540 S<state>". (Requires SD_ABORT_ON_ENDSTOP_HIT)
|
||||
* M569 - Enable stealthChop on an axis. (Requires at least one _DRIVER_TYPE to be TMC2130/2160/2208/2209/5130/5160)
|
||||
@@ -233,7 +236,7 @@
|
||||
* M605 - Set Dual X-Carriage movement mode: "M605 S<mode> [X<x_offset>] [R<temp_offset>]". (Requires DUAL_X_CARRIAGE)
|
||||
* M665 - Set delta configurations: "M665 H<delta height> L<diagonal rod> R<delta radius> S<segments/s> B<calibration radius> X<Alpha angle trim> Y<Beta angle trim> Z<Gamma angle trim> (Requires DELTA)
|
||||
* M666 - Set/get offsets for delta (Requires DELTA) or dual endstops. (Requires [XYZ]_DUAL_ENDSTOPS)
|
||||
* M672 - Set/Reset Duet Smart Effector's sensitivity. (Requires SMART_EFFECTOR and SMART_EFFECTOR_MOD_PIN)
|
||||
* M672 - Set/Reset Duet Smart Effector's sensitivity. (Requires DUET_SMART_EFFECTOR and SMART_EFFECTOR_MOD_PIN)
|
||||
* M701 - Load filament (Requires FILAMENT_LOAD_UNLOAD_GCODES)
|
||||
* M702 - Unload filament (Requires FILAMENT_LOAD_UNLOAD_GCODES)
|
||||
* M810-M819 - Define/execute a G-code macro (Requires GCODE_MACROS)
|
||||
@@ -276,6 +279,9 @@
|
||||
* ************ Custom codes - This can change to suit future G-code regulations
|
||||
* G425 - Calibrate using a conductive object. (Requires CALIBRATION_GCODE)
|
||||
* M928 - Start SD logging: "M928 filename.gco". Stop with M29. (Requires SDSUPPORT)
|
||||
* M993 - Backup SPI Flash to SD
|
||||
* M994 - Load a Backup from SD to SPI Flash
|
||||
* M995 - Touch screen calibration for TFT display
|
||||
* M997 - Perform in-application firmware update
|
||||
* M999 - Restart after being stopped by error
|
||||
*
|
||||
@@ -701,7 +707,7 @@ private:
|
||||
static void M351();
|
||||
#endif
|
||||
|
||||
TERN_(HAS_CASE_LIGHT, static void M355());
|
||||
TERN_(CASE_LIGHT_ENABLE, static void M355());
|
||||
|
||||
TERN_(REPETIER_GCODE_M360, static void M360());
|
||||
|
||||
@@ -757,6 +763,16 @@ private:
|
||||
#endif
|
||||
TERN_(EEPROM_SETTINGS, static void M504());
|
||||
|
||||
#if ENABLED(PASSWORD_FEATURE)
|
||||
static void M510();
|
||||
#if ENABLED(PASSWORD_UNLOCK_GCODE)
|
||||
static void M511();
|
||||
#endif
|
||||
#if ENABLED(PASSWORD_CHANGE_GCODE)
|
||||
static void M512();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
TERN_(SDSUPPORT, static void M524());
|
||||
|
||||
TERN_(SD_ABORT_ON_ENDSTOP_HIT, static void M540());
|
||||
@@ -776,7 +792,7 @@ private:
|
||||
static void M666();
|
||||
#endif
|
||||
|
||||
#if ENABLED(SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD)
|
||||
#if ENABLED(DUET_SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD)
|
||||
static void M672();
|
||||
#endif
|
||||
|
||||
@@ -843,6 +859,13 @@ private:
|
||||
|
||||
TERN_(MAGNETIC_PARKING_EXTRUDER, static void M951());
|
||||
|
||||
TERN_(TOUCH_SCREEN_CALIBRATION, static void M995());
|
||||
|
||||
#if BOTH(HAS_SPI_FLASH, SDSUPPORT)
|
||||
static void M993();
|
||||
static void M994();
|
||||
#endif
|
||||
|
||||
TERN_(PLATFORM_M997_SUPPORT, static void M997());
|
||||
|
||||
static void M999();
|
||||
|
||||
@@ -61,7 +61,7 @@ void GcodeSuite::M206() {
|
||||
* Use M206 to set these values directly.
|
||||
*/
|
||||
void GcodeSuite::M428() {
|
||||
if (axis_unhomed_error()) return;
|
||||
if (homing_needed_error()) return;
|
||||
|
||||
xyz_float_t diff;
|
||||
LOOP_XYZ(i) {
|
||||
|
||||
@@ -93,8 +93,8 @@ void GcodeSuite::M115() {
|
||||
cap_line(PSTR("SOFTWARE_POWER"), ENABLED(PSU_CONTROL));
|
||||
|
||||
// TOGGLE_LIGHTS (M355)
|
||||
cap_line(PSTR("TOGGLE_LIGHTS"), ENABLED(HAS_CASE_LIGHT));
|
||||
cap_line(PSTR("CASE_LIGHT_BRIGHTNESS"), TERN0(HAS_CASE_LIGHT, PWM_PIN(CASE_LIGHT_PIN)));
|
||||
cap_line(PSTR("TOGGLE_LIGHTS"), ENABLED(CASE_LIGHT_ENABLE));
|
||||
cap_line(PSTR("CASE_LIGHT_BRIGHTNESS"), TERN0(CASE_LIGHT_ENABLE, PWM_PIN(CASE_LIGHT_PIN)));
|
||||
|
||||
// EMERGENCY_PARSER (M108, M112, M410, M876)
|
||||
cap_line(PSTR("EMERGENCY_PARSER"), ENABLED(EMERGENCY_PARSER));
|
||||
|
||||
39
Marlin/src/gcode/lcd/M995.cpp
Normal file
39
Marlin/src/gcode/lcd/M995.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(TOUCH_SCREEN_CALIBRATION)
|
||||
|
||||
#include "../gcode.h"
|
||||
#include "../../lcd/menu/menu.h"
|
||||
|
||||
/**
|
||||
* M995: Touch screen calibration for TFT display
|
||||
*/
|
||||
void GcodeSuite::M995() {
|
||||
|
||||
ui.goto_screen(touch_screen_calibration);
|
||||
|
||||
}
|
||||
|
||||
#endif // TOUCH_SCREEN_CALIBRATION
|
||||
@@ -52,7 +52,7 @@ void GcodeSuite::G0_G1(
|
||||
|
||||
if (IsRunning()
|
||||
#if ENABLED(NO_MOTION_BEFORE_HOMING)
|
||||
&& !axis_unhomed_error(
|
||||
&& !homing_needed_error(
|
||||
(parser.seen('X') ? _BV(X_AXIS) : 0)
|
||||
| (parser.seen('Y') ? _BV(Y_AXIS) : 0)
|
||||
| (parser.seen('Z') ? _BV(Z_AXIS) : 0) )
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
/**
|
||||
* Parameters interpreted according to:
|
||||
* https://linuxcnc.org/docs/2.6/html/gcode/gcode.html#sec:G5-Cubic-Spline
|
||||
* https://linuxcnc.org/docs/2.7/html/gcode/g-code.html#gcode:g5
|
||||
* However I, J omission is not supported at this point; all
|
||||
* parameters can be omitted and default to zero.
|
||||
*/
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
//#define DEBUG_GCODE_PARSER
|
||||
#if ENABLED(DEBUG_GCODE_PARSER)
|
||||
#include "../libs/hex_print_routines.h"
|
||||
#include "../libs/hex_print.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(TEMPERATURE_UNITS_SUPPORT)
|
||||
|
||||
@@ -40,7 +40,7 @@ GCodeQueue queue;
|
||||
#endif
|
||||
|
||||
#if ENABLED(BINARY_FILE_TRANSFER)
|
||||
#include "../feature/binary_protocol.h"
|
||||
#include "../feature/binary_stream.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||
@@ -639,11 +639,10 @@ void GCodeQueue::advance() {
|
||||
#if ENABLED(SERIAL_STATS_DROPPED_RX)
|
||||
SERIAL_ECHOLNPAIR("Dropped bytes: ", MYSERIAL0.dropped());
|
||||
#endif
|
||||
|
||||
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
|
||||
SERIAL_ECHOLNPAIR("Max RX Queue Size: ", MYSERIAL0.rxMaxEnqueued());
|
||||
#endif
|
||||
#endif // !defined(__AVR__) || !defined(USBCON)
|
||||
#endif
|
||||
|
||||
ok_to_send();
|
||||
}
|
||||
|
||||
@@ -75,7 +75,10 @@ void GcodeSuite::M1001() {
|
||||
TERN_(POWER_LOSS_RECOVERY, recovery.purge());
|
||||
|
||||
// Announce SD file completion
|
||||
SERIAL_ECHOLNPGM(STR_FILE_PRINTED);
|
||||
{
|
||||
PORT_REDIRECT(SERIAL_BOTH);
|
||||
SERIAL_ECHOLNPGM(STR_FILE_PRINTED);
|
||||
}
|
||||
|
||||
// Update the status LED color
|
||||
#if HAS_LEDS_OFF_FLAG
|
||||
|
||||
Reference in New Issue
Block a user