update code base to Marlin 2.0.9.2

This commit is contained in:
Stefan Kalscheuer
2021-10-03 18:57:12 +02:00
parent b9d7ba838e
commit 7077da3591
2617 changed files with 332093 additions and 103438 deletions

View File

@@ -0,0 +1,44 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 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(AIR_EVACUATION)
#include "../gcode.h"
#include "../../feature/spindle_laser.h"
/**
* M10: Vacuum or Blower On
*/
void GcodeSuite::M10() {
cutter.air_evac_enable(); // Turn on Vacuum or Blower motor
}
/**
* M11: Vacuum or Blower OFF
*/
void GcodeSuite::M11() {
cutter.air_evac_disable(); // Turn off Vacuum or Blower motor
}
#endif // AIR_EVACUATION

9
Marlin/src/gcode/control/M108_M112_M410.cpp Executable file → Normal file
View File

@@ -16,7 +16,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
@@ -25,15 +25,14 @@
#if DISABLED(EMERGENCY_PARSER)
#include "../gcode.h"
#include "../../MarlinCore.h" // for wait_for_heatup, kill, quickstop_stepper
#include "../../MarlinCore.h" // for wait_for_heatup, kill, M112_KILL_STR
#include "../../module/motion.h" // for quickstop_stepper
/**
* M108: Stop the waiting for heaters in M109, M190, M303. Does not affect the target temperature.
*/
void GcodeSuite::M108() {
#if HAS_RESUME_CONTINUE
wait_for_user = false;
#endif
TERN_(HAS_RESUME_CONTINUE, wait_for_user = false);
wait_for_heatup = false;
}

37
Marlin/src/gcode/control/M111.cpp Executable file → Normal file
View File

@@ -16,7 +16,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
@@ -28,21 +28,18 @@
void GcodeSuite::M111() {
if (parser.seen('S')) marlin_debug_flags = parser.byteval('S');
static const char str_debug_1[] PROGMEM = STR_DEBUG_ECHO,
str_debug_2[] PROGMEM = STR_DEBUG_INFO,
str_debug_4[] PROGMEM = STR_DEBUG_ERRORS,
str_debug_8[] PROGMEM = STR_DEBUG_DRYRUN,
str_debug_16[] PROGMEM = STR_DEBUG_COMMUNICATION
#if ENABLED(DEBUG_LEVELING_FEATURE)
, str_debug_lvl[] PROGMEM = STR_DEBUG_LEVELING
#endif
;
static PGMSTR(str_debug_1, STR_DEBUG_ECHO);
static PGMSTR(str_debug_2, STR_DEBUG_INFO);
static PGMSTR(str_debug_4, STR_DEBUG_ERRORS);
static PGMSTR(str_debug_8, STR_DEBUG_DRYRUN);
static PGMSTR(str_debug_16, STR_DEBUG_COMMUNICATION);
#if ENABLED(DEBUG_LEVELING_FEATURE)
static PGMSTR(str_debug_lvl, STR_DEBUG_LEVELING);
#endif
static PGM_P const debug_strings[] PROGMEM = {
str_debug_1, str_debug_2, str_debug_4, str_debug_8, str_debug_16
#if ENABLED(DEBUG_LEVELING_FEATURE)
, str_debug_lvl
#endif
str_debug_1, str_debug_2, str_debug_4, str_debug_8, str_debug_16,
TERN_(DEBUG_LEVELING_FEATURE, str_debug_lvl)
};
SERIAL_ECHO_START();
@@ -52,7 +49,7 @@ void GcodeSuite::M111() {
LOOP_L_N(i, COUNT(debug_strings)) {
if (TEST(marlin_debug_flags, i)) {
if (comma++) SERIAL_CHAR(',');
serialprintPGM((char*)pgm_read_ptr(&debug_strings[i]));
SERIAL_ECHOPGM_P((char*)pgm_read_ptr(&debug_strings[i]));
}
}
}
@@ -60,21 +57,21 @@ void GcodeSuite::M111() {
SERIAL_ECHOPGM(STR_DEBUG_OFF);
#if !defined(__AVR__) || !defined(USBCON)
#if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS)
SERIAL_ECHOPAIR("\nBuffer Overruns: ", MYSERIAL0.buffer_overruns());
SERIAL_ECHOPGM("\nBuffer Overruns: ", MYSERIAL1.buffer_overruns());
#endif
#if ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS)
SERIAL_ECHOPAIR("\nFraming Errors: ", MYSERIAL0.framing_errors());
SERIAL_ECHOPGM("\nFraming Errors: ", MYSERIAL1.framing_errors());
#endif
#if ENABLED(SERIAL_STATS_DROPPED_RX)
SERIAL_ECHOPAIR("\nDropped bytes: ", MYSERIAL0.dropped());
SERIAL_ECHOPGM("\nDropped bytes: ", MYSERIAL1.dropped());
#endif
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
SERIAL_ECHOPAIR("\nMax RX Queue Size: ", MYSERIAL0.rxMaxEnqueued());
SERIAL_ECHOPGM("\nMax RX Queue Size: ", MYSERIAL1.rxMaxEnqueued());
#endif
#endif // !defined(__AVR__) || !defined(USBCON)
#endif // !__AVR__ || !USBCON
}
SERIAL_EOL();
}

2
Marlin/src/gcode/control/M120_M121.cpp Executable file → Normal file
View File

@@ -16,7 +16,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/

232
Marlin/src/gcode/control/M17_M18_M84.cpp Executable file → Normal file
View File

@@ -16,62 +16,232 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../gcode.h"
#include "../../MarlinCore.h" // for stepper_inactive_time, disable_e_steppers
#include "../../lcd/ultralcd.h"
#include "../../lcd/marlinui.h"
#include "../../module/stepper.h"
#if BOTH(AUTO_BED_LEVELING_UBL, ULTRA_LCD)
#if ENABLED(AUTO_BED_LEVELING_UBL)
#include "../../feature/bedlevel/bedlevel.h"
#endif
/**
* M17: Enable stepper motors
*/
void GcodeSuite::M17() {
if (parser.seen("XYZE")) {
if (parser.seen('X')) ENABLE_AXIS_X();
if (parser.seen('Y')) ENABLE_AXIS_Y();
if (parser.seen('Z')) ENABLE_AXIS_Z();
#if HAS_E_STEPPER_ENABLE
if (parser.seen('E')) enable_e_steppers();
#define DEBUG_OUT ENABLED(MARLIN_DEV_MODE)
#include "../../core/debug_out.h"
#include "../../libs/hex_print.h"
inline axis_flags_t selected_axis_bits() {
axis_flags_t selected{0};
#if HAS_EXTRUDERS
if (parser.seen('E')) {
if (E_TERN0(parser.has_value())) {
const uint8_t e = parser.value_int();
if (e < EXTRUDERS)
selected.bits = _BV(INDEX_OF_AXIS(E_AXIS, e));
}
else
selected.bits = selected.e_bits();
}
#endif
selected.bits |= LINEAR_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)
);
return selected;
}
// Enable specified axes and warn about other affected axes
void do_enable(const axis_flags_t to_enable) {
const ena_mask_t was_enabled = stepper.axis_enabled.bits,
shall_enable = to_enable.bits & ~was_enabled;
DEBUG_ECHOLNPGM("Now Enabled: ", hex_word(stepper.axis_enabled.bits), " Enabling: ", hex_word(to_enable.bits), " | ", shall_enable);
if (!shall_enable) return; // All specified axes already enabled?
ena_mask_t also_enabled = 0; // Track steppers enabled due to overlap
// Enable all flagged axes
LOOP_LINEAR_AXES(a) {
if (TEST(shall_enable, a)) {
stepper.enable_axis(AxisEnum(a)); // Mark and enable the requested axis
DEBUG_ECHOLNPGM("Enabled ", axis_codes[a], " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... Enabled: ", hex_word(stepper.axis_enabled.bits));
also_enabled |= enable_overlap[a];
}
}
#if HAS_EXTRUDERS
LOOP_L_N(e, EXTRUDERS) {
const uint8_t a = INDEX_OF_AXIS(E_AXIS, e);
if (TEST(shall_enable, a)) {
stepper.ENABLE_EXTRUDER(e);
DEBUG_ECHOLNPGM("Enabled E", AS_DIGIT(e), " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... ", hex_word(stepper.axis_enabled.bits));
also_enabled |= enable_overlap[a];
}
}
#endif
if ((also_enabled &= ~(shall_enable | was_enabled))) {
SERIAL_CHAR('(');
LOOP_LINEAR_AXES(a) if (TEST(also_enabled, a)) SERIAL_CHAR(axis_codes[a], ' ');
#if HAS_EXTRUDERS
#define _EN_ALSO(N) if (TEST(also_enabled, INDEX_OF_AXIS(E_AXIS, N))) SERIAL_CHAR('E', '0' + N, ' ');
REPEAT(EXTRUDERS, _EN_ALSO)
#endif
SERIAL_ECHOLNPGM("also enabled)");
}
else {
LCD_MESSAGEPGM(MSG_NO_MOVE);
enable_all_steppers();
}
DEBUG_ECHOLNPGM("Enabled Now: ", hex_word(stepper.axis_enabled.bits));
}
/**
* M18, M84: Disable stepper motors
* M17: Enable stepper motor power for one or more axes.
* Print warnings for axes that share an ENABLE_PIN.
*
* Examples:
*
* M17 XZ ; Enable X and Z axes
* M17 E ; Enable all E steppers
* M17 E1 ; Enable just the E1 stepper
*/
void GcodeSuite::M17() {
if (parser.seen_axis()) {
if (any_enable_overlap())
do_enable(selected_axis_bits());
else {
#if HAS_EXTRUDERS
if (parser.seen('E')) {
if (parser.has_value()) {
const uint8_t e = parser.value_int();
if (e < EXTRUDERS) stepper.ENABLE_EXTRUDER(e);
}
else
stepper.enable_e_steppers();
}
#endif
LINEAR_AXIS_CODE(
if (parser.seen_test('X')) stepper.enable_axis(X_AXIS),
if (parser.seen_test('Y')) stepper.enable_axis(Y_AXIS),
if (parser.seen_test('Z')) stepper.enable_axis(Z_AXIS),
if (parser.seen_test(AXIS4_NAME)) stepper.enable_axis(I_AXIS),
if (parser.seen_test(AXIS5_NAME)) stepper.enable_axis(J_AXIS),
if (parser.seen_test(AXIS6_NAME)) stepper.enable_axis(K_AXIS)
);
}
}
else {
LCD_MESSAGEPGM(MSG_NO_MOVE);
stepper.enable_all_steppers();
}
}
void try_to_disable(const axis_flags_t to_disable) {
ena_mask_t still_enabled = to_disable.bits & stepper.axis_enabled.bits;
DEBUG_ECHOLNPGM("Enabled: ", hex_word(stepper.axis_enabled.bits), " To Disable: ", hex_word(to_disable.bits), " | ", hex_word(still_enabled));
if (!still_enabled) return;
// Attempt to disable all flagged axes
LOOP_LINEAR_AXES(a)
if (TEST(to_disable.bits, a)) {
DEBUG_ECHOPGM("Try to disable ", axis_codes[a], " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... ");
if (stepper.disable_axis(AxisEnum(a))) { // Mark the requested axis and request to disable
DEBUG_ECHOPGM("OK");
still_enabled &= ~(_BV(a) | enable_overlap[a]); // If actually disabled, clear one or more tracked bits
}
else
DEBUG_ECHOPGM("OVERLAP");
DEBUG_ECHOLNPGM(" ... still_enabled=", hex_word(still_enabled));
}
#if HAS_EXTRUDERS
LOOP_L_N(e, EXTRUDERS) {
const uint8_t a = INDEX_OF_AXIS(E_AXIS, e);
if (TEST(to_disable.bits, a)) {
DEBUG_ECHOPGM("Try to disable E", AS_DIGIT(e), " (", a, ") with overlap ", hex_word(enable_overlap[a]), " ... ");
if (stepper.DISABLE_EXTRUDER(e)) {
DEBUG_ECHOPGM("OK");
still_enabled &= ~(_BV(a) | enable_overlap[a]);
}
else
DEBUG_ECHOPGM("OVERLAP");
DEBUG_ECHOLNPGM(" ... still_enabled=", hex_word(still_enabled));
}
}
#endif
auto overlap_warning = [](const ena_mask_t axis_bits) {
SERIAL_ECHOPGM(" not disabled. Shared with");
LOOP_LINEAR_AXES(a) if (TEST(axis_bits, a)) SERIAL_CHAR(' ', axis_codes[a]);
#if HAS_EXTRUDERS
#define _EN_STILLON(N) if (TEST(axis_bits, INDEX_OF_AXIS(E_AXIS, N))) SERIAL_CHAR(' ', 'E', '0' + N);
REPEAT(EXTRUDERS, _EN_STILLON)
#endif
SERIAL_ECHOLNPGM(".");
};
// If any of the requested axes are still enabled, give a warning
LOOP_LINEAR_AXES(a) {
if (TEST(still_enabled, a)) {
SERIAL_CHAR(axis_codes[a]);
overlap_warning(stepper.axis_enabled.bits & enable_overlap[a]);
}
}
#if HAS_EXTRUDERS
LOOP_L_N(e, EXTRUDERS) {
const uint8_t a = INDEX_OF_AXIS(E_AXIS, e);
if (TEST(still_enabled, a)) {
SERIAL_CHAR('E', '0' + e);
overlap_warning(stepper.axis_enabled.bits & enable_overlap[a]);
}
}
#endif
DEBUG_ECHOLNPGM("Enabled Now: ", hex_word(stepper.axis_enabled.bits));
}
/**
* M18, M84: Disable stepper motor power for one or more axes.
* Print warnings for axes that share an ENABLE_PIN.
*/
void GcodeSuite::M18_M84() {
if (parser.seenval('S')) {
reset_stepper_timeout();
stepper_inactive_time = parser.value_millis_from_seconds();
}
else {
if (parser.seen("XYZE")) {
if (parser.seen_axis()) {
planner.synchronize();
if (parser.seen('X')) DISABLE_AXIS_X();
if (parser.seen('Y')) DISABLE_AXIS_Y();
if (parser.seen('Z')) DISABLE_AXIS_Z();
#if HAS_E_STEPPER_ENABLE
if (parser.seen('E')) disable_e_steppers();
#endif
if (any_enable_overlap())
try_to_disable(selected_axis_bits());
else {
#if HAS_EXTRUDERS
if (parser.seen('E')) {
if (E_TERN0(parser.has_value()))
stepper.DISABLE_EXTRUDER(parser.value_int());
else
stepper.disable_e_steppers();
}
#endif
LINEAR_AXIS_CODE(
if (parser.seen_test('X')) stepper.disable_axis(X_AXIS),
if (parser.seen_test('Y')) stepper.disable_axis(Y_AXIS),
if (parser.seen_test('Z')) stepper.disable_axis(Z_AXIS),
if (parser.seen_test(AXIS4_NAME)) stepper.disable_axis(I_AXIS),
if (parser.seen_test(AXIS5_NAME)) stepper.disable_axis(J_AXIS),
if (parser.seen_test(AXIS6_NAME)) stepper.disable_axis(K_AXIS)
);
}
}
else
planner.finish_and_disable();
#if HAS_LCD_MENU && ENABLED(AUTO_BED_LEVELING_UBL)
if (ubl.lcd_map_control) {
ubl.lcd_map_control = false;
ui.defer_status_screen(false);
}
#endif
TERN_(AUTO_BED_LEVELING_UBL, ubl.steppers_were_disabled());
}
}

28
Marlin/src/gcode/control/M211.cpp Executable file → Normal file
View File

@@ -16,7 +16,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
@@ -33,14 +33,22 @@
* Usage: M211 S1 to enable, M211 S0 to disable, M211 alone for report
*/
void GcodeSuite::M211() {
const xyz_pos_t l_soft_min = soft_endstop.min.asLogical(),
l_soft_max = soft_endstop.max.asLogical();
SERIAL_ECHO_START();
SERIAL_ECHOPGM(STR_SOFT_ENDSTOPS);
if (parser.seen('S')) soft_endstops_enabled = parser.value_bool();
serialprint_onoff(soft_endstops_enabled);
print_xyz(l_soft_min, PSTR(STR_SOFT_MIN), PSTR(" "));
print_xyz(l_soft_max, PSTR(STR_SOFT_MAX));
if (parser.seen('S'))
soft_endstop._enabled = parser.value_bool();
else
M211_report();
}
#endif
void GcodeSuite::M211_report(const bool forReplay/*=true*/) {
report_heading_etc(forReplay, PSTR(STR_SOFT_ENDSTOPS));
SERIAL_ECHOPGM(" M211 S", AS_DIGIT(soft_endstop._enabled), " ; ");
serialprintln_onoff(soft_endstop._enabled);
report_echo_start(forReplay);
const xyz_pos_t l_soft_min = soft_endstop.min.asLogical(),
l_soft_max = soft_endstop.max.asLogical();
print_pos(l_soft_min, PSTR(STR_SOFT_MIN), PSTR(" "));
print_pos(l_soft_max, PSTR(STR_SOFT_MAX));
}
#endif // HAS_SOFTWARE_ENDSTOPS

10
Marlin/src/gcode/control/M226.cpp Executable file → Normal file
View File

@@ -16,14 +16,20 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../../inc/MarlinConfig.h"
#if ENABLED(DIRECT_PIN_CONTROL)
#include "../gcode.h"
#include "../../MarlinCore.h" // for pin_is_protected and idle()
#include "../../module/stepper.h"
void protected_pin_err();
/**
* M226: Wait until the specified pin reaches the state required (M226 P<pin> S<state>)
*/
@@ -50,3 +56,5 @@ void GcodeSuite::M226() {
} // pin_state -1 0 1 && pin > -1
} // parser.seen('P')
}
#endif // DIRECT_PIN_CONTROL

53
Marlin/src/gcode/control/M280.cpp Executable file → Normal file
View File

@@ -16,7 +16,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
@@ -26,30 +26,51 @@
#include "../gcode.h"
#include "../../module/servo.h"
#include "../../module/planner.h"
/**
* M280: Get or set servo position. P<index> [S<angle>]
* M280: Get or set servo position.
* P<index> - Servo index
* S<angle> - Angle to set, omit to read current angle, or use -1 to detach
*
* With POLARGRAPH:
* T<ms> - Duration of servo move
*/
void GcodeSuite::M280() {
if (!parser.seen('P')) return;
if (!parser.seenval('P')) return;
TERN_(POLARGRAPH, planner.synchronize());
const int servo_index = parser.value_int();
if (WITHIN(servo_index, 0, NUM_SERVOS - 1)) {
if (parser.seen('S')) {
const int a = parser.value_int();
if (a == -1)
servo[servo_index].detach();
if (parser.seenval('S')) {
const int anew = parser.value_int();
if (anew >= 0) {
#if ENABLED(POLARGRAPH)
if (parser.seen('T')) { // (ms) Total duration of servo move
const int16_t t = constrain(parser.value_int(), 0, 10000);
const int aold = servo[servo_index].read();
millis_t now = millis();
const millis_t start = now, end = start + t;
while (PENDING(now, end)) {
safe_delay(50);
now = _MIN(millis(), end);
MOVE_SERVO(servo_index, LROUND(aold + (anew - aold) * (float(now - start) / t)));
}
}
#endif // POLARGRAPH
MOVE_SERVO(servo_index, anew);
}
else
MOVE_SERVO(servo_index, a);
}
else {
SERIAL_ECHO_START();
SERIAL_ECHOLNPAIR(" Servo ", servo_index, ": ", servo[servo_index].read());
DETACH_SERVO(servo_index);
}
else
SERIAL_ECHO_MSG(" Servo ", servo_index, ": ", servo[servo_index].read());
}
else {
SERIAL_ERROR_START();
SERIAL_ECHOLNPAIR("Servo ", servo_index, " out of range");
}
else
SERIAL_ERROR_MSG("Servo ", servo_index, " out of range");
}
#endif // HAS_SERVOS

View File

@@ -0,0 +1,45 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 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(SERVO_DETACH_GCODE)
#include "../gcode.h"
#include "../../module/servo.h"
/**
* M282: Detach Servo. P<index>
*/
void GcodeSuite::M282() {
if (!parser.seenval('P')) return;
const int servo_index = parser.value_int();
if (WITHIN(servo_index, 0, NUM_SERVOS - 1))
DETACH_SERVO(servo_index);
else
SERIAL_ECHO_MSG("Servo ", servo_index, " out of range");
}
#endif // SERVO_DETACH_GCODE

76
Marlin/src/gcode/control/M3-M5.cpp Executable file → Normal file
View File

@@ -16,7 +16,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
@@ -30,20 +30,16 @@
/**
* Laser:
*
* M3 - Laser ON/Power (Ramped power)
* M4 - Laser ON/Power (Continuous power)
*
* S<power> - Set power. S0 will turn the laser off.
* O<ocr> - Set power and OCR
*
* Spindle:
*
* M3 - Spindle ON (Clockwise)
* M4 - Spindle ON (Counter-clockwise)
*
* S<power> - Set power. S0 will turn the spindle off.
* O<ocr> - Set power and OCR
* Parameters:
* S<power> - Set power. S0 will turn the spindle/laser off, except in relative mode.
* O<ocr> - Set power and OCR (oscillator count register)
*
* If no PWM pin is defined then M3/M4 just turns it on.
*
@@ -70,31 +66,75 @@
* PWM duty cycle goes from 0 (off) to 255 (always on).
*/
void GcodeSuite::M3_M4(const bool is_M4) {
auto get_s_power = [] {
if (parser.seenval('S')) {
const float spwr = parser.value_float();
#if ENABLED(SPINDLE_SERVO)
cutter.unitPower = spwr;
#else
cutter.unitPower = TERN(SPINDLE_LASER_USE_PWM,
cutter.power_to_range(cutter_power_t(round(spwr))),
spwr > 0 ? 255 : 0);
#endif
}
else
cutter.unitPower = cutter.cpwr_to_upwr(SPEED_POWER_STARTUP);
return cutter.unitPower;
};
#if ENABLED(SPINDLE_FEATURE)
planner.synchronize(); // Wait for movement to complete before changing power
#if ENABLED(LASER_POWER_INLINE)
if (parser.seen('I') == DISABLED(LASER_POWER_INLINE_INVERT)) {
// Laser power in inline mode
cutter.inline_direction(is_M4); // Should always be unused
#if ENABLED(SPINDLE_LASER_USE_PWM)
if (parser.seen('O')) {
cutter.unitPower = cutter.power_to_range(parser.value_byte(), 0);
cutter.inline_ocr_power(cutter.unitPower); // The OCR is a value from 0 to 255 (uint8_t)
}
else
cutter.inline_power(cutter.upower_to_ocr(get_s_power()));
#else
cutter.set_inline_enabled(true);
#endif
return;
}
// Non-inline, standard case
cutter.inline_disable(); // Prevent future blocks re-setting the power
#endif
cutter.set_direction(is_M4);
planner.synchronize(); // Wait for previous movement commands (G0/G0/G2/G3) to complete before changing power
cutter.set_reverse(is_M4);
#if ENABLED(SPINDLE_LASER_PWM)
if (parser.seenval('O'))
cutter.set_ocr_power(parser.value_byte()); // The OCR is a value from 0 to 255 (uint8_t)
#if ENABLED(SPINDLE_LASER_USE_PWM)
if (parser.seenval('O')) {
cutter.unitPower = cutter.power_to_range(parser.value_byte(), 0);
cutter.ocr_set_power(cutter.unitPower); // The OCR is a value from 0 to 255 (uint8_t)
}
else
cutter.set_power(parser.intval('S', 255));
cutter.set_power(cutter.upower_to_ocr(get_s_power()));
#elif ENABLED(SPINDLE_SERVO)
cutter.set_power(get_s_power());
#else
cutter.set_enabled(true);
#endif
cutter.menuPower = cutter.unitPower;
}
/**
* M5 - Cutter OFF
* M5 - Cutter OFF (when moves are complete)
*/
void GcodeSuite::M5() {
#if ENABLED(SPINDLE_FEATURE)
planner.synchronize();
#if ENABLED(LASER_POWER_INLINE)
if (parser.seen('I') == DISABLED(LASER_POWER_INLINE_INVERT)) {
cutter.set_inline_enabled(false); // Laser power in inline mode
return;
}
// Non-inline, standard case
cutter.inline_disable(); // Prevent future blocks re-setting the power
#endif
planner.synchronize();
cutter.set_enabled(false);
cutter.menuPower = cutter.unitPower;
}
#endif // HAS_CUTTER

10
Marlin/src/gcode/control/M350_M351.cpp Executable file → Normal file
View File

@@ -16,7 +16,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
@@ -34,7 +34,7 @@
*/
void GcodeSuite::M350() {
if (parser.seen('S')) LOOP_LE_N(i, 4) stepper.microstep_mode(i, parser.value_byte());
LOOP_XYZE(i) if (parser.seen(axis_codes[i])) stepper.microstep_mode(i, parser.value_byte());
LOOP_LOGICAL_AXES(i) if (parser.seen(axis_codes[i])) stepper.microstep_mode(i, parser.value_byte());
if (parser.seen('B')) stepper.microstep_mode(4, parser.value_byte());
stepper.microstep_readings();
}
@@ -46,15 +46,15 @@ void GcodeSuite::M350() {
void GcodeSuite::M351() {
if (parser.seenval('S')) switch (parser.value_byte()) {
case 1:
LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper.microstep_ms(i, parser.value_byte(), -1, -1);
LOOP_LOGICAL_AXES(i) if (parser.seenval(axis_codes[i])) stepper.microstep_ms(i, parser.value_byte(), -1, -1);
if (parser.seenval('B')) stepper.microstep_ms(4, parser.value_byte(), -1, -1);
break;
case 2:
LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper.microstep_ms(i, -1, parser.value_byte(), -1);
LOOP_LOGICAL_AXES(i) if (parser.seenval(axis_codes[i])) stepper.microstep_ms(i, -1, parser.value_byte(), -1);
if (parser.seenval('B')) stepper.microstep_ms(4, -1, parser.value_byte(), -1);
break;
case 3:
LOOP_XYZE(i) if (parser.seenval(axis_codes[i])) stepper.microstep_ms(i, -1, -1, parser.value_byte());
LOOP_LOGICAL_AXES(i) if (parser.seenval(axis_codes[i])) stepper.microstep_ms(i, -1, -1, parser.value_byte());
if (parser.seenval('B')) stepper.microstep_ms(4, -1, -1, parser.value_byte());
break;
}

2
Marlin/src/gcode/control/M380_M381.cpp Executable file → Normal file
View File

@@ -16,7 +16,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/

2
Marlin/src/gcode/control/M400.cpp Executable file → Normal file
View File

@@ -16,7 +16,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/

58
Marlin/src/gcode/control/M42.cpp Executable file → Normal file
View File

@@ -16,18 +16,32 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../gcode.h"
#include "../../MarlinCore.h" // for pin_is_protected
#include "../../inc/MarlinConfig.h"
#if FAN_COUNT > 0
#if ENABLED(DIRECT_PIN_CONTROL)
#include "../gcode.h"
#include "../../MarlinCore.h" // for pin_is_protected
#if HAS_FAN
#include "../../module/temperature.h"
#endif
#ifdef MAPLE_STM32F1
// these are enums on the F1...
#define INPUT_PULLDOWN INPUT_PULLDOWN
#define INPUT_ANALOG INPUT_ANALOG
#define OUTPUT_OPEN_DRAIN OUTPUT_OPEN_DRAIN
#endif
void protected_pin_err() {
SERIAL_ERROR_MSG(STR_ERR_PROTECTED_PIN);
}
/**
* M42: Change pin status via GCode
*
@@ -48,23 +62,29 @@ void GcodeSuite::M42() {
if (!parser.boolval('I') && pin_is_protected(pin)) return protected_pin_err();
bool avoidWrite = false;
if (parser.seenval('M')) {
switch (parser.value_byte()) {
case 0: pinMode(pin, INPUT); break;
case 0: pinMode(pin, INPUT); avoidWrite = true; break;
case 1: pinMode(pin, OUTPUT); break;
case 2: pinMode(pin, INPUT_PULLUP); break;
case 2: pinMode(pin, INPUT_PULLUP); avoidWrite = true; break;
#ifdef INPUT_PULLDOWN
case 3: pinMode(pin, INPUT_PULLDOWN); break;
case 3: pinMode(pin, INPUT_PULLDOWN); avoidWrite = true; break;
#endif
default: SERIAL_ECHOLNPGM("Invalid Pin Mode");
#ifdef INPUT_ANALOG
case 4: pinMode(pin, INPUT_ANALOG); avoidWrite = true; break;
#endif
#ifdef OUTPUT_OPEN_DRAIN
case 5: pinMode(pin, OUTPUT_OPEN_DRAIN); break;
#endif
default: SERIAL_ECHOLNPGM("Invalid Pin Mode"); return;
}
return;
}
if (!parser.seenval('S')) return;
const byte pin_status = parser.value_byte();
#if FAN_COUNT > 0
#if HAS_FAN
switch (pin) {
#if HAS_FAN0
case FAN0_PIN: thermalManager.fan_speed[0] = pin_status; return;
@@ -93,7 +113,23 @@ void GcodeSuite::M42() {
}
#endif
pinMode(pin, OUTPUT);
if (avoidWrite) {
SERIAL_ECHOLNPGM("?Cannot write to INPUT");
return;
}
// 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
#ifndef OUTPUT_OPEN_DRAIN
pinMode(pin, OUTPUT);
#endif
extDigitalWrite(pin, pin_status);
#ifdef ARDUINO_ARCH_STM32
// A simple I/O will be set to 0 by analogWrite()
if (pin_status <= 1 && !PWM_PIN(pin)) return;
#endif
analogWrite(pin, pin_status);
}
#endif // DIRECT_PIN_CONTROL

88
Marlin/src/gcode/control/M605.cpp Executable file → Normal file
View File

@@ -16,7 +16,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
@@ -68,42 +68,50 @@
const DualXMode previous_mode = dual_x_carriage_mode;
dual_x_carriage_mode = (DualXMode)parser.value_byte();
mirrored_duplication_mode = false;
if (dual_x_carriage_mode == DXC_MIRRORED_MODE) {
if (previous_mode != DXC_DUPLICATION_MODE) {
SERIAL_ECHOLNPGM("Printer must be in DXC_DUPLICATION_MODE prior to ");
SERIAL_ECHOLNPGM("specifying DXC_MIRRORED_MODE.");
dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
return;
}
mirrored_duplication_mode = true;
stepper.set_directions();
float x_jog = current_position.x - .1;
for (uint8_t i = 2; --i;) {
planner.buffer_line(x_jog, current_position.y, current_position.z, current_position.e, feedrate_mm_s, 0);
x_jog += .1;
}
return;
}
idex_set_mirrored_mode(false);
switch (dual_x_carriage_mode) {
case DXC_FULL_CONTROL_MODE:
case DXC_AUTO_PARK_MODE:
break;
case DXC_DUPLICATION_MODE:
if (parser.seen('X')) duplicate_extruder_x_offset = _MAX(parser.value_linear_units(), X2_MIN_POS - x_home_pos(0));
// Set the X offset, but no less than the safety gap
if (parser.seen('X')) duplicate_extruder_x_offset = _MAX(parser.value_linear_units(), (X2_MIN_POS) - (X1_MIN_POS));
if (parser.seen('R')) duplicate_extruder_temp_offset = parser.value_celsius_diff();
// Always switch back to tool 0
if (active_extruder != 0) tool_change(0);
break;
case DXC_MIRRORED_MODE: {
if (previous_mode != DXC_DUPLICATION_MODE) {
SERIAL_ECHOLNPGM("Printer must be in DXC_DUPLICATION_MODE prior to ");
SERIAL_ECHOLNPGM("specifying DXC_MIRRORED_MODE.");
dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
return;
}
idex_set_mirrored_mode(true);
// Do a small 'jog' motion in the X axis
xyze_pos_t dest = current_position; dest.x -= 0.1f;
for (uint8_t i = 2; --i;) {
planner.buffer_line(dest, feedrate_mm_s, 0);
dest.x += 0.1f;
}
} return;
default:
dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
break;
}
active_extruder_parked = false;
extruder_duplication_enabled = false;
stepper.set_directions();
delayed_move_time = 0;
idex_set_parked(false);
set_duplication_enabled(false);
#ifdef EVENT_GCODE_IDEX_AFTER_MODECHANGE
gcode.process_subcommands_now_P(PSTR(EVENT_GCODE_IDEX_AFTER_MODECHANGE));
#endif
}
else if (!parser.seen('W')) // if no S or W parameter, the DXC mode gets reset to the user's default
dual_x_carriage_mode = DEFAULT_DUAL_X_CARRIAGE_MODE;
@@ -119,26 +127,26 @@
case DXC_DUPLICATION_MODE: DEBUG_ECHOPGM("DUPLICATION"); break;
case DXC_MIRRORED_MODE: DEBUG_ECHOPGM("MIRRORED"); break;
}
DEBUG_ECHOPAIR("\nActive Ext: ", int(active_extruder));
DEBUG_ECHOPGM("\nActive Ext: ", active_extruder);
if (!active_extruder_parked) DEBUG_ECHOPGM(" NOT ");
DEBUG_ECHOPGM(" parked.");
DEBUG_ECHOPAIR("\nactive_extruder_x_pos: ", current_position.x);
DEBUG_ECHOPAIR("\ninactive_extruder_x_pos: ", inactive_extruder_x_pos);
DEBUG_ECHOPAIR("\nextruder_duplication_enabled: ", int(extruder_duplication_enabled));
DEBUG_ECHOPAIR("\nduplicate_extruder_x_offset: ", duplicate_extruder_x_offset);
DEBUG_ECHOPAIR("\nduplicate_extruder_temp_offset: ", duplicate_extruder_temp_offset);
DEBUG_ECHOPAIR("\ndelayed_move_time: ", delayed_move_time);
DEBUG_ECHOPAIR("\nX1 Home X: ", x_home_pos(0), "\nX1_MIN_POS=", int(X1_MIN_POS), "\nX1_MAX_POS=", int(X1_MAX_POS));
DEBUG_ECHOPAIR("\nX2 Home X: ", x_home_pos(1), "\nX2_MIN_POS=", int(X2_MIN_POS), "\nX2_MAX_POS=", int(X2_MAX_POS));
DEBUG_ECHOPAIR("\nX2_HOME_DIR=", int(X2_HOME_DIR), "\nX2_HOME_POS=", int(X2_HOME_POS));
DEBUG_ECHOPAIR("\nDEFAULT_DUAL_X_CARRIAGE_MODE=", STRINGIFY(DEFAULT_DUAL_X_CARRIAGE_MODE));
DEBUG_ECHOPAIR("\toolchange_settings.z_raise=", toolchange_settings.z_raise);
DEBUG_ECHOPAIR("\nDEFAULT_DUPLICATION_X_OFFSET=", int(DEFAULT_DUPLICATION_X_OFFSET));
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();
HOTEND_LOOP() {
DEBUG_ECHOPAIR_P(SP_T_STR, int(e));
LOOP_XYZ(a) DEBUG_ECHOPAIR(" hotend_offset[", int(e), "].", XYZ_CHAR(a) | 0x20, "=", hotend_offset[e][a]);
DEBUG_ECHOPGM_P(SP_T_STR, e);
LOOP_LINEAR_AXES(a) DEBUG_ECHOPGM(" hotend_offset[", e, "].", AS_CHAR(AXIS_CHAR(a) | 0x20), "=", hotend_offset[e][a]);
DEBUG_EOL();
}
DEBUG_EOL();
@@ -164,7 +172,7 @@
if (parser.seenval('P')) duplication_e_mask = parser.value_int(); // Set the mask directly
else if (parser.seenval('E')) duplication_e_mask = pow(2, parser.value_int() + 1) - 1; // Set the mask by E index
ena = (2 == parser.intval('S', extruder_duplication_enabled ? 2 : 0));
extruder_duplication_enabled = ena && (duplication_e_mask >= 3);
set_duplication_enabled(ena && (duplication_e_mask >= 3));
}
SERIAL_ECHO_START();
SERIAL_ECHOPGM(STR_DUPLICATION_MODE);

38
Marlin/src/gcode/control/M7-M9.cpp Executable file → Normal file
View File

@@ -16,13 +16,13 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../../inc/MarlinConfig.h"
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(COOLANT_CONTROL)
#if ANY(COOLANT_MIST, COOLANT_FLOOD, AIR_ASSIST)
#include "../gcode.h"
#include "../../module/planner.h"
@@ -37,27 +37,41 @@
}
#endif
#if ENABLED(COOLANT_FLOOD)
#if EITHER(COOLANT_FLOOD, AIR_ASSIST)
#if ENABLED(AIR_ASSIST)
#include "../../feature/spindle_laser.h"
#endif
/**
* M8: Flood Coolant On
* M8: Flood Coolant / Air Assist ON
*/
void GcodeSuite::M8() {
planner.synchronize(); // Wait for move to arrive
WRITE(COOLANT_FLOOD_PIN, !(COOLANT_FLOOD_INVERT)); // Turn on Flood coolant
planner.synchronize(); // Wait for move to arrive
#if ENABLED(COOLANT_FLOOD)
WRITE(COOLANT_FLOOD_PIN, !(COOLANT_FLOOD_INVERT)); // Turn on Flood coolant
#endif
#if ENABLED(AIR_ASSIST)
cutter.air_assist_enable(); // Turn on Air Assist
#endif
}
#endif
/**
* M9: Coolant OFF
* M9: Coolant / Air Assist OFF
*/
void GcodeSuite::M9() {
planner.synchronize(); // Wait for move to arrive
planner.synchronize(); // Wait for move to arrive
#if ENABLED(COOLANT_MIST)
WRITE(COOLANT_MIST_PIN, COOLANT_MIST_INVERT); // Turn off Mist coolant
WRITE(COOLANT_MIST_PIN, COOLANT_MIST_INVERT); // Turn off Mist coolant
#endif
#if ENABLED(COOLANT_FLOOD)
WRITE(COOLANT_FLOOD_PIN, COOLANT_FLOOD_INVERT); // Turn off Flood coolant
WRITE(COOLANT_FLOOD_PIN, COOLANT_FLOOD_INVERT); // Turn off Flood coolant
#endif
#if ENABLED(AIR_ASSIST)
cutter.air_assist_disable(); // Turn off Air Assist
#endif
}
#endif // COOLANT_CONTROL
#endif // COOLANT_MIST | COOLANT_FLOOD | AIR_ASSIST

View File

@@ -16,41 +16,36 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#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/marlinui.h" // for LCD_MESSAGEPGM_P
#include "../../inc/MarlinConfig.h"
#if HAS_LCD_MENU
#include "../../lcd/ultralcd.h"
#endif
// PATCH START: Knutwurst
#if ENABLED(ANYCUBIC_TOUCHSCREEN)
#include "../../lcd/anycubic_touchscreen.h"
#endif
// PATCH END: Knutwurst
#if ENABLED(PSU_CONTROL)
#include "../queue.h"
#include "../../feature/power.h"
#endif
#if HAS_SUICIDE
#include "../../MarlinCore.h"
#endif
#if ENABLED(PSU_CONTROL)
#if ENABLED(AUTO_POWER_CONTROL)
#include "../../feature/power.h"
#endif
// Could be moved to a feature, but this is all the data
bool powersupply_on;
#if HAS_TRINAMIC_CONFIG
#include "../../feature/tmc_util.h"
#endif
/**
* M80 : Turn on the Power Supply
* M80 S : Report the current state and exit
@@ -59,11 +54,11 @@
// S: Report the current power supply state and exit
if (parser.seen('S')) {
serialprintPGM(powersupply_on ? PSTR("PS:1\n") : PSTR("PS:0\n"));
SERIAL_ECHOPGM_P(powerManager.psu_on ? PSTR("PS:1\n") : PSTR("PS:0\n"));
return;
}
PSU_ON();
powerManager.power_on();
/**
* If you have a switch on suicide pin, this is useful
@@ -71,25 +66,19 @@
* a print without suicide...
*/
#if HAS_SUICIDE
OUT_WRITE(SUICIDE_PIN, !SUICIDE_PIN_INVERTING);
#endif
#if DISABLED(AUTO_POWER_CONTROL)
delay(PSU_POWERUP_DELAY); // Wait for power to settle
restore_stepper_drivers();
#endif
#if HAS_LCD_MENU
ui.reset_status();
OUT_WRITE(SUICIDE_PIN, !SUICIDE_PIN_STATE);
#endif
// PATCH START: Knutwurst
#ifdef ANYCUBIC_TOUCHSCREEN
AnycubicTouchscreen.CommandScan();
#endif
// PATCH END: Knutwurst
TERN_(HAS_LCD_MENU, ui.reset_status());
}
#endif // ENABLED(PSU_CONTROL)
#endif // PSU_CONTROL
/**
* M81: Turn off Power, including Power Supply, if there is one.
@@ -98,10 +87,11 @@
*/
void GcodeSuite::M81() {
thermalManager.disable_all_heaters();
print_job_timer.stop();
planner.finish_and_disable();
#if FAN_COUNT > 0
print_job_timer.stop();
#if HAS_FAN
thermalManager.zero_fan_speeds();
#if ENABLED(PROBING_FANS_OFF)
thermalManager.fans_paused = false;
@@ -114,10 +104,8 @@ void GcodeSuite::M81() {
#if HAS_SUICIDE
suicide();
#elif ENABLED(PSU_CONTROL)
PSU_OFF();
powerManager.power_off_soon();
#endif
#if HAS_LCD_MENU
LCD_MESSAGEPGM_P(PSTR(MACHINE_NAME " " STR_OFF "."));
#endif
LCD_MESSAGEPGM_P(PSTR(MACHINE_NAME " " STR_OFF "."));
}

3
Marlin/src/gcode/control/M85.cpp Executable file → Normal file
View File

@@ -16,12 +16,11 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../gcode.h"
#include "../../MarlinCore.h" // for max_inactive_time
/**
* M85: Set inactivity shutdown timer with parameter S<seconds>. To disable set zero (default)

View File

@@ -0,0 +1,88 @@
/**
* 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_ECHOLNPGM("Failed to open ", fname, " to write.");
return;
}
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_ECHOLNPGM("Failed to open ", fname, " to read.");
return;
}
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

10
Marlin/src/gcode/control/M997.cpp Executable file → Normal file
View File

@@ -16,7 +16,7 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
@@ -24,11 +24,19 @@
#if ENABLED(PLATFORM_M997_SUPPORT)
#if ENABLED(DWIN_CREALITY_LCD_ENHANCED)
#include "../../lcd/e3v2/enhanced/dwin.h"
#endif
/**
* M997: Perform in-application firmware update
*/
void GcodeSuite::M997() {
TERN_(DWIN_CREALITY_LCD_ENHANCED, DWIN_RebootScreen());
flashFirmware(parser.intval('S'));
}
#endif

7
Marlin/src/gcode/control/M999.cpp Executable file → Normal file
View File

@@ -16,13 +16,13 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../gcode.h"
#include "../../lcd/ultralcd.h" // for lcd_reset_alert_level
#include "../../lcd/marlinui.h" // for lcd_reset_alert_level
#include "../../MarlinCore.h" // for marlin_state
#include "../queue.h" // for flush_and_request_resend
@@ -34,7 +34,6 @@
*
* Sending "M999 S1" will resume printing without flushing the
* existing command buffer.
*
*/
void GcodeSuite::M999() {
marlin_state = MF_RUNNING;
@@ -42,5 +41,5 @@ void GcodeSuite::M999() {
if (parser.boolval('S')) return;
queue.flush_and_request_resend();
queue.flush_and_request_resend(queue.ring_buffer.command_port());
}

46
Marlin/src/gcode/control/T.cpp Executable file → Normal file
View File

@@ -16,19 +16,19 @@
* 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 <http://www.gnu.org/licenses/>.
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../gcode.h"
#include "../../module/tool_change.h"
#if ENABLED(DEBUG_LEVELING_FEATURE) || EXTRUDERS > 1
#if EITHER(HAS_MULTI_EXTRUDER, DEBUG_LEVELING_FEATURE)
#include "../../module/motion.h"
#endif
#if ENABLED(PRUSA_MMU2)
#include "../../feature/mmu2/mmu2.h"
#if HAS_PRUSA_MMU2
#include "../../feature/mmu/mmu2.h"
#endif
#define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
@@ -40,41 +40,31 @@
* F[units/min] Set the movement feedrate
* S1 Don't move the tool in XY after change
*
* For PRUSA_MMU2:
* 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.
* 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 uint8_t tool_index) {
void GcodeSuite::T(const int8_t tool_index) {
if (DEBUGGING(LEVELING)) {
DEBUG_ECHOLNPAIR(">>> T(", tool_index, ")");
DEBUG_POS("BEFORE", current_position);
}
DEBUG_SECTION(log_T, "T", DEBUGGING(LEVELING));
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("...(", tool_index, ")");
#if ENABLED(PRUSA_MMU2)
// Count this command as movement / activity
reset_stepper_timeout();
#if HAS_PRUSA_MMU2
if (parser.string_arg) {
mmu2.tool_change(parser.string_arg); // Special commands T?/Tx/Tc
return;
}
#endif
#if EXTRUDERS < 2
tool_change(tool_index);
#else
tool_change(
tool_index,
(tool_index == active_extruder) || parser.boolval('S')
);
#endif
if (DEBUGGING(LEVELING)) {
DEBUG_POS("AFTER", current_position);
DEBUG_ECHOLNPGM("<<< T()");
}
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')
#endif
);
}