diff options
Diffstat (limited to 'Marlin/src/gcode/config')
-rw-r--r-- | Marlin/src/gcode/config/M200-M205.cpp | 191 | ||||
-rw-r--r-- | Marlin/src/gcode/config/M217.cpp | 171 | ||||
-rw-r--r-- | Marlin/src/gcode/config/M218.cpp | 71 | ||||
-rw-r--r-- | Marlin/src/gcode/config/M220.cpp | 51 | ||||
-rw-r--r-- | Marlin/src/gcode/config/M221.cpp | 47 | ||||
-rw-r--r-- | Marlin/src/gcode/config/M281.cpp | 68 | ||||
-rw-r--r-- | Marlin/src/gcode/config/M301.cpp | 91 | ||||
-rw-r--r-- | Marlin/src/gcode/config/M302.cpp | 63 | ||||
-rw-r--r-- | Marlin/src/gcode/config/M304.cpp | 48 | ||||
-rw-r--r-- | Marlin/src/gcode/config/M305.cpp | 81 | ||||
-rw-r--r-- | Marlin/src/gcode/config/M43.cpp | 386 | ||||
-rw-r--r-- | Marlin/src/gcode/config/M540.cpp | 40 | ||||
-rw-r--r-- | Marlin/src/gcode/config/M575.cpp | 75 | ||||
-rw-r--r-- | Marlin/src/gcode/config/M672.cpp | 98 | ||||
-rw-r--r-- | Marlin/src/gcode/config/M92.cpp | 114 |
15 files changed, 1595 insertions, 0 deletions
diff --git a/Marlin/src/gcode/config/M200-M205.cpp b/Marlin/src/gcode/config/M200-M205.cpp new file mode 100644 index 0000000..cb17fc4 --- /dev/null +++ b/Marlin/src/gcode/config/M200-M205.cpp @@ -0,0 +1,191 @@ +/** + * 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 "../gcode.h" +#include "../../MarlinCore.h" +#include "../../module/planner.h" + +#if DISABLED(NO_VOLUMETRICS) + + /** + * M200: Set filament diameter and set E axis units to cubic units + * + * T<extruder> - Optional extruder number. Current extruder if omitted. + * D<linear> - Set filament diameter and enable. D0 disables volumetric. + * S<bool> - Turn volumetric ON or OFF. + * L<float> - Volumetric extruder limit (in mm^3/sec). L0 disables the limit. + */ + void GcodeSuite::M200() { + + const int8_t target_extruder = get_target_extruder_from_command(); + if (target_extruder < 0) return; + + bool vol_enable = parser.volumetric_enabled, + can_enable = true; + + if (parser.seenval('D')) { + const float dval = parser.value_linear_units(); + if (dval) { // Set filament size for volumetric calculation + planner.set_filament_size(target_extruder, dval); + vol_enable = true; // Dn = enable for compatibility + } + else + can_enable = false; // D0 = disable for compatibility + } + + // Enable or disable with S1 / S0 + parser.volumetric_enabled = can_enable && parser.boolval('S', vol_enable); + + #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT) + if (parser.seenval('L')) { + // Set volumetric limit (in mm^3/sec) + const float lval = parser.value_float(); + if (WITHIN(lval, 0, 20)) + planner.set_volumetric_extruder_limit(target_extruder, lval); + else + SERIAL_ECHOLNPGM("?L value out of range (0-20)."); + } + #endif + + planner.calculate_volumetric_multipliers(); + } + +#endif // !NO_VOLUMETRICS + +/** + * M201: Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000) + * + * With multiple extruders use T to specify which one. + */ +void GcodeSuite::M201() { + + const int8_t target_extruder = get_target_extruder_from_command(); + if (target_extruder < 0) return; + + #ifdef XY_FREQUENCY_LIMIT + if (parser.seenval('F')) planner.set_frequency_limit(parser.value_byte()); + if (parser.seenval('G')) planner.xy_freq_min_speed_factor = constrain(parser.value_float(), 1, 100) / 100; + #endif + + LOOP_XYZE(i) { + if (parser.seen(axis_codes[i])) { + const uint8_t a = (i == E_AXIS ? uint8_t(E_AXIS_N(target_extruder)) : i); + planner.set_max_acceleration(a, parser.value_axis_units((AxisEnum)a)); + } + } +} + +/** + * M203: Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in units/sec + * + * With multiple extruders use T to specify which one. + */ +void GcodeSuite::M203() { + + const int8_t target_extruder = get_target_extruder_from_command(); + if (target_extruder < 0) return; + + LOOP_XYZE(i) + if (parser.seen(axis_codes[i])) { + const uint8_t a = (i == E_AXIS ? uint8_t(E_AXIS_N(target_extruder)) : i); + planner.set_max_feedrate(a, parser.value_axis_units((AxisEnum)a)); + } +} + +/** + * M204: Set Accelerations in units/sec^2 (M204 P1200 R3000 T3000) + * + * P = Printing moves + * R = Retract only (no X, Y, Z) moves + * T = Travel (non printing) moves + */ +void GcodeSuite::M204() { + if (!parser.seen("PRST")) { + SERIAL_ECHOPAIR("Acceleration: P", planner.settings.acceleration); + SERIAL_ECHOPAIR(" R", planner.settings.retract_acceleration); + SERIAL_ECHOLNPAIR_P(SP_T_STR, planner.settings.travel_acceleration); + } + else { + //planner.synchronize(); + // 'S' for legacy compatibility. Should NOT BE USED for new development + if (parser.seenval('S')) planner.settings.travel_acceleration = planner.settings.acceleration = parser.value_linear_units(); + if (parser.seenval('P')) planner.settings.acceleration = parser.value_linear_units(); + if (parser.seenval('R')) planner.settings.retract_acceleration = parser.value_linear_units(); + if (parser.seenval('T')) planner.settings.travel_acceleration = parser.value_linear_units(); + } +} + +/** + * M205: Set Advanced Settings + * + * B = Min Segment Time (µs) + * S = Min Feed Rate (units/s) + * T = Min Travel Feed Rate (units/s) + * X = Max X Jerk (units/sec^2) + * Y = Max Y Jerk (units/sec^2) + * Z = Max Z Jerk (units/sec^2) + * E = Max E Jerk (units/sec^2) + * J = Junction Deviation (mm) (If not using CLASSIC_JERK) + */ +void GcodeSuite::M205() { + #if HAS_JUNCTION_DEVIATION + #define J_PARAM "J" + #else + #define J_PARAM + #endif + #if HAS_CLASSIC_JERK + #define XYZE_PARAM "XYZE" + #else + #define XYZE_PARAM + #endif + if (!parser.seen("BST" J_PARAM XYZE_PARAM)) return; + + //planner.synchronize(); + if (parser.seen('B')) planner.settings.min_segment_time_us = parser.value_ulong(); + if (parser.seen('S')) planner.settings.min_feedrate_mm_s = parser.value_linear_units(); + if (parser.seen('T')) planner.settings.min_travel_feedrate_mm_s = parser.value_linear_units(); + #if HAS_JUNCTION_DEVIATION + if (parser.seen('J')) { + const float junc_dev = parser.value_linear_units(); + if (WITHIN(junc_dev, 0.01f, 0.3f)) { + planner.junction_deviation_mm = junc_dev; + TERN_(LIN_ADVANCE, planner.recalculate_max_e_jerk()); + } + else + SERIAL_ERROR_MSG("?J out of range (0.01 to 0.3)"); + } + #endif + #if HAS_CLASSIC_JERK + if (parser.seen('X')) planner.set_max_jerk(X_AXIS, parser.value_linear_units()); + if (parser.seen('Y')) planner.set_max_jerk(Y_AXIS, parser.value_linear_units()); + if (parser.seen('Z')) { + planner.set_max_jerk(Z_AXIS, parser.value_linear_units()); + #if HAS_MESH && DISABLED(LIMITED_JERK_EDITING) + if (planner.max_jerk.z <= 0.1f) + SERIAL_ECHOLNPGM("WARNING! Low Z Jerk may lead to unwanted pauses."); + #endif + } + #if HAS_CLASSIC_E_JERK + if (parser.seen('E')) planner.set_max_jerk(E_AXIS, parser.value_linear_units()); + #endif + #endif +} diff --git a/Marlin/src/gcode/config/M217.cpp b/Marlin/src/gcode/config/M217.cpp new file mode 100644 index 0000000..f2fefb5 --- /dev/null +++ b/Marlin/src/gcode/config/M217.cpp @@ -0,0 +1,171 @@ +/** + * 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 HAS_MULTI_EXTRUDER + +#include "../gcode.h" +#include "../../module/tool_change.h" + +#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + #include "../../module/motion.h" +#endif + +#include "../../MarlinCore.h" // for SP_X_STR, etc. + +void M217_report(const bool eeprom=false) { + + #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) + serialprintPGM(eeprom ? PSTR(" M217") : PSTR("Toolchange:")); + SERIAL_ECHOPAIR(" S", LINEAR_UNIT(toolchange_settings.swap_length)); + SERIAL_ECHOPAIR_P(SP_B_STR, LINEAR_UNIT(toolchange_settings.extra_resume), + SP_E_STR, LINEAR_UNIT(toolchange_settings.extra_prime), + SP_P_STR, LINEAR_UNIT(toolchange_settings.prime_speed)); + SERIAL_ECHOPAIR(" R", LINEAR_UNIT(toolchange_settings.retract_speed), + " U", LINEAR_UNIT(toolchange_settings.unretract_speed), + " F", toolchange_settings.fan_speed, + " G", toolchange_settings.fan_time); + + #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + SERIAL_ECHOPAIR(" A", int(migration.automode)); + SERIAL_ECHOPAIR(" L", LINEAR_UNIT(migration.last)); + #endif + + #if ENABLED(TOOLCHANGE_PARK) + SERIAL_ECHOPAIR(" W", LINEAR_UNIT(toolchange_settings.enable_park)); + SERIAL_ECHOPAIR_P(SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x)); + SERIAL_ECHOPAIR_P(SP_Y_STR, LINEAR_UNIT(toolchange_settings.change_point.y)); + #endif + + #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED) + SERIAL_ECHOPAIR(" V", LINEAR_UNIT(enable_first_prime)); + #endif + + #else + + UNUSED(eeprom); + + #endif + + SERIAL_ECHOPAIR_P(SP_Z_STR, LINEAR_UNIT(toolchange_settings.z_raise)); + SERIAL_EOL(); +} + +/** + * M217 - Set SINGLENOZZLE toolchange parameters + * + * // Tool change command + * Q Prime active tool and exit + * + * // Tool change settings + * S[linear] Swap length + * B[linear] Extra Swap length + * E[linear] Prime length + * P[linear/m] Prime speed + * R[linear/m] Retract speed + * U[linear/m] UnRetract speed + * V[linear] 0/1 Enable auto prime first extruder used + * W[linear] 0/1 Enable park & Z Raise + * X[linear] Park X (Requires TOOLCHANGE_PARK) + * Y[linear] Park Y (Requires TOOLCHANGE_PARK) + * Z[linear] Z Raise + * F[linear] Fan Speed 0-255 + * G[linear/s] Fan time + * + * Tool migration settings + * A[0|1] Enable auto-migration on runout + * L[index] Last extruder to use for auto-migration + * + * Tool migration command + * T[index] Migrate to next extruder or the given extruder + */ +void GcodeSuite::M217() { + + #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) + + static constexpr float max_extrude = TERN(PREVENT_LENGTHY_EXTRUDE, EXTRUDE_MAXLENGTH, 500); + + if (parser.seen('Q')) { tool_change_prime(); return; } + + if (parser.seenval('S')) { const float v = parser.value_linear_units(); toolchange_settings.swap_length = constrain(v, 0, max_extrude); } + if (parser.seenval('B')) { const float v = parser.value_linear_units(); toolchange_settings.extra_resume = constrain(v, -10, 10); } + if (parser.seenval('E')) { const float v = parser.value_linear_units(); toolchange_settings.extra_prime = constrain(v, 0, max_extrude); } + if (parser.seenval('P')) { const int16_t v = parser.value_linear_units(); toolchange_settings.prime_speed = constrain(v, 10, 5400); } + if (parser.seenval('R')) { const int16_t v = parser.value_linear_units(); toolchange_settings.retract_speed = constrain(v, 10, 5400); } + if (parser.seenval('U')) { const int16_t v = parser.value_linear_units(); toolchange_settings.unretract_speed = constrain(v, 10, 5400); } + #if TOOLCHANGE_FS_FAN >= 0 && HAS_FAN + if (parser.seenval('F')) { const int16_t v = parser.value_linear_units(); toolchange_settings.fan_speed = constrain(v, 0, 255); } + if (parser.seenval('G')) { const int16_t v = parser.value_linear_units(); toolchange_settings.fan_time = constrain(v, 1, 30); } + #endif + #endif + + #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED) + if (parser.seenval('V')) { enable_first_prime = parser.value_linear_units(); } + #endif + + #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 (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 + + if (parser.seenval('Z')) { toolchange_settings.z_raise = parser.value_linear_units(); } + + #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) + migration.target = 0; // 0 = disabled + + if (parser.seenval('L')) { // Last + const int16_t lval = parser.value_int(); + if (WITHIN(lval, 0, EXTRUDERS - 1)) { + migration.last = lval; + migration.automode = (active_extruder < migration.last); + } + } + + if (parser.seen('A')) // Auto on/off + migration.automode = parser.value_bool(); + + if (parser.seen('T')) { // Migrate now + if (parser.has_value()) { + const int16_t tval = parser.value_int(); + if (WITHIN(tval, 0, EXTRUDERS - 1) && tval != active_extruder) { + migration.target = tval + 1; + extruder_migration(); + migration.target = 0; // disable + return; + } + else + migration.target = 0; // disable + } + else { + extruder_migration(); + return; + } + } + + #endif + + M217_report(); +} + +#endif // HAS_MULTI_EXTRUDER diff --git a/Marlin/src/gcode/config/M218.cpp b/Marlin/src/gcode/config/M218.cpp new file mode 100644 index 0000000..7701320 --- /dev/null +++ b/Marlin/src/gcode/config/M218.cpp @@ -0,0 +1,71 @@ +/** + * 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 HAS_HOTEND_OFFSET + +#include "../gcode.h" +#include "../../module/motion.h" + +#if ENABLED(DELTA) + #include "../../module/planner.h" +#endif + +/** + * M218 - set hotend offset (in linear units) + * + * T<tool> + * X<xoffset> + * Y<yoffset> + * Z<zoffset> + */ +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 (!parser.seen("XYZ")) { + SERIAL_ECHO_START(); + SERIAL_ECHOPGM(STR_HOTEND_OFFSET); + HOTEND_LOOP() { + SERIAL_CHAR(' '); + SERIAL_ECHO(hotend_offset[e].x); + SERIAL_CHAR(','); + SERIAL_ECHO(hotend_offset[e].y); + SERIAL_CHAR(','); + SERIAL_ECHO_F(hotend_offset[e].z, 3); + } + SERIAL_EOL(); + } + + #if ENABLED(DELTA) + if (target_extruder == active_extruder) + do_blocking_move_to_xy(current_position, planner.settings.max_feedrate_mm_s[X_AXIS]); + #endif +} + +#endif // HAS_HOTEND_OFFSET diff --git a/Marlin/src/gcode/config/M220.cpp b/Marlin/src/gcode/config/M220.cpp new file mode 100644 index 0000000..75339f1 --- /dev/null +++ b/Marlin/src/gcode/config/M220.cpp @@ -0,0 +1,51 @@ +/** + * 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 "../gcode.h" +#include "../../module/motion.h" + +/** + * M220: Set speed percentage factor, aka "Feed Rate" + * + * Parameters + * S<percent> : Set the feed rate percentage factor + * + * Report the current speed percentage factor if no parameter is specified + * + * For MMU2 and MMU2S devices... + * B : Flag to back up the current factor + * R : Flag to restore the last-saved factor + */ +void GcodeSuite::M220() { + + static int16_t backup_feedrate_percentage = 100; + if (parser.seen('B')) backup_feedrate_percentage = feedrate_percentage; + if (parser.seen('R')) feedrate_percentage = backup_feedrate_percentage; + + if (parser.seenval('S')) feedrate_percentage = parser.value_int(); + + if (!parser.seen_any()) { + SERIAL_ECHOPAIR("FR:", feedrate_percentage); + SERIAL_CHAR('%'); + SERIAL_EOL(); + } +} diff --git a/Marlin/src/gcode/config/M221.cpp b/Marlin/src/gcode/config/M221.cpp new file mode 100644 index 0000000..7ba22d1 --- /dev/null +++ b/Marlin/src/gcode/config/M221.cpp @@ -0,0 +1,47 @@ +/** + * 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 "../gcode.h" +#include "../../module/planner.h" + +#if EXTRUDERS + +/** + * M221: Set extrusion percentage (M221 T0 S95) + */ +void GcodeSuite::M221() { + + const int8_t target_extruder = get_target_extruder_from_command(); + if (target_extruder < 0) return; + + if (parser.seenval('S')) + planner.set_flow(target_extruder, parser.value_int()); + else { + SERIAL_ECHO_START(); + SERIAL_CHAR('E', '0' + target_extruder); + SERIAL_ECHOPAIR(" Flow: ", planner.flow_percentage[target_extruder]); + SERIAL_CHAR('%'); + SERIAL_EOL(); + } +} + +#endif // EXTRUDERS diff --git a/Marlin/src/gcode/config/M281.cpp b/Marlin/src/gcode/config/M281.cpp new file mode 100644 index 0000000..018ca1c --- /dev/null +++ b/Marlin/src/gcode/config/M281.cpp @@ -0,0 +1,68 @@ +/** + * 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(EDITABLE_SERVO_ANGLES) + +#include "../gcode.h" +#include "../../module/servo.h" + +/** + * M281 - Edit / Report Servo Angles + * + * P<index> - Servo to update + * L<angle> - Deploy Angle + * U<angle> - Stowed Angle + */ +void GcodeSuite::M281() { + if (!parser.seenval('P')) return; + const int servo_index = parser.value_int(); + if (WITHIN(servo_index, 0, NUM_SERVOS - 1)) { + #if ENABLED(BLTOUCH) + if (servo_index == Z_PROBE_SERVO_NR) { + SERIAL_ERROR_MSG("BLTouch angles can't be changed."); + return; + } + #endif + bool angle_change = false; + if (parser.seen('L')) { + servo_angles[servo_index][0] = parser.value_int(); + angle_change = true; + } + if (parser.seen('U')) { + servo_angles[servo_index][1] = parser.value_int(); + angle_change = true; + } + if (!angle_change) { + SERIAL_ECHO_START(); + SERIAL_ECHOLNPAIR(" Servo ", servo_index, + " L", servo_angles[servo_index][0], + " U", servo_angles[servo_index][1]); + } + } + else { + SERIAL_ERROR_START(); + SERIAL_ECHOLNPAIR("Servo ", servo_index, " out of range"); + } +} + +#endif // EDITABLE_SERVO_ANGLES diff --git a/Marlin/src/gcode/config/M301.cpp b/Marlin/src/gcode/config/M301.cpp new file mode 100644 index 0000000..7b3f576 --- /dev/null +++ b/Marlin/src/gcode/config/M301.cpp @@ -0,0 +1,91 @@ +/** + * 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(PIDTEMP) + +#include "../gcode.h" +#include "../../module/temperature.h" + +/** + * M301: Set PID parameters P I D (and optionally C, L) + * + * E[extruder] Default: 0 + * + * P[float] Kp term + * I[float] Ki term (unscaled) + * D[float] Kd term (unscaled) + * + * With PID_EXTRUSION_SCALING: + * + * C[float] Kc term + * L[int] LPQ length + * + * With PID_FAN_SCALING: + * + * F[float] Kf term + */ +void GcodeSuite::M301() { + + // multi-extruder PID patch: M301 updates or prints a single extruder's PID values + // default behavior (omitting E parameter) is to update for extruder 0 only + const uint8_t e = parser.byteval('E'); // extruder being updated + + if (e < HOTENDS) { // catch bad input value + if (parser.seen('P')) PID_PARAM(Kp, e) = parser.value_float(); + if (parser.seen('I')) PID_PARAM(Ki, e) = scalePID_i(parser.value_float()); + if (parser.seen('D')) PID_PARAM(Kd, e) = scalePID_d(parser.value_float()); + #if ENABLED(PID_EXTRUSION_SCALING) + if (parser.seen('C')) PID_PARAM(Kc, e) = parser.value_float(); + if (parser.seenval('L')) thermalManager.lpq_len = parser.value_int(); + NOMORE(thermalManager.lpq_len, LPQ_MAX_LEN); + NOLESS(thermalManager.lpq_len, 0); + #endif + + #if ENABLED(PID_FAN_SCALING) + if (parser.seen('F')) PID_PARAM(Kf, e) = parser.value_float(); + #endif + + thermalManager.updatePID(); + + SERIAL_ECHO_START(); + #if ENABLED(PID_PARAMS_PER_HOTEND) + SERIAL_ECHOPAIR(" e:", e); // specify extruder in serial output + #endif + SERIAL_ECHOPAIR(" p:", PID_PARAM(Kp, e), + " i:", unscalePID_i(PID_PARAM(Ki, e)), + " d:", unscalePID_d(PID_PARAM(Kd, e))); + #if ENABLED(PID_EXTRUSION_SCALING) + SERIAL_ECHOPAIR(" c:", PID_PARAM(Kc, e)); + #endif + #if ENABLED(PID_FAN_SCALING) + SERIAL_ECHOPAIR(" f:", PID_PARAM(Kf, e)); + #endif + + SERIAL_EOL(); + } + else + SERIAL_ERROR_MSG(STR_INVALID_EXTRUDER); +} + +#endif // PIDTEMP diff --git a/Marlin/src/gcode/config/M302.cpp b/Marlin/src/gcode/config/M302.cpp new file mode 100644 index 0000000..afdc6c9 --- /dev/null +++ b/Marlin/src/gcode/config/M302.cpp @@ -0,0 +1,63 @@ +/** + * 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(PREVENT_COLD_EXTRUSION) + +#include "../gcode.h" +#include "../../module/temperature.h" + +/** + * M302: Allow cold extrudes, or set the minimum extrude temperature + * + * S<temperature> sets the minimum extrude temperature + * P<bool> enables (1) or disables (0) cold extrusion + * + * Examples: + * + * M302 ; report current cold extrusion state + * M302 P0 ; enable cold extrusion checking + * M302 P1 ; disable cold extrusion checking + * M302 S0 ; always allow extrusion (disables checking) + * M302 S170 ; only allow extrusion above 170 + * M302 S170 P1 ; set min extrude temp to 170 but leave disabled + */ +void GcodeSuite::M302() { + const bool seen_S = parser.seen('S'); + if (seen_S) { + thermalManager.extrude_min_temp = parser.value_celsius(); + thermalManager.allow_cold_extrude = (thermalManager.extrude_min_temp == 0); + } + + if (parser.seen('P')) + thermalManager.allow_cold_extrude = (thermalManager.extrude_min_temp == 0) || parser.value_bool(); + else if (!seen_S) { + // Report current state + SERIAL_ECHO_START(); + SERIAL_ECHOPGM("Cold extrudes are "); + serialprintPGM(thermalManager.allow_cold_extrude ? PSTR("en") : PSTR("dis")); + SERIAL_ECHOLNPAIR("abled (min temp ", thermalManager.extrude_min_temp, "C)"); + } +} + +#endif // PREVENT_COLD_EXTRUSION diff --git a/Marlin/src/gcode/config/M304.cpp b/Marlin/src/gcode/config/M304.cpp new file mode 100644 index 0000000..10739be --- /dev/null +++ b/Marlin/src/gcode/config/M304.cpp @@ -0,0 +1,48 @@ +/** + * 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(PIDTEMPBED) + +#include "../gcode.h" +#include "../../module/temperature.h" + +/** + * M304 - Set and/or Report the current Bed PID values + * + * P<pval> - Set the P value + * I<ival> - Set the I value + * D<dval> - Set the D value + */ +void GcodeSuite::M304() { + if (parser.seen('P')) thermalManager.temp_bed.pid.Kp = parser.value_float(); + if (parser.seen('I')) thermalManager.temp_bed.pid.Ki = scalePID_i(parser.value_float()); + if (parser.seen('D')) thermalManager.temp_bed.pid.Kd = scalePID_d(parser.value_float()); + + SERIAL_ECHO_START(); + SERIAL_ECHOLNPAIR(" p:", thermalManager.temp_bed.pid.Kp, + " i:", unscalePID_i(thermalManager.temp_bed.pid.Ki), + " d:", unscalePID_d(thermalManager.temp_bed.pid.Kd)); +} + +#endif // PIDTEMPBED diff --git a/Marlin/src/gcode/config/M305.cpp b/Marlin/src/gcode/config/M305.cpp new file mode 100644 index 0000000..3e7206a --- /dev/null +++ b/Marlin/src/gcode/config/M305.cpp @@ -0,0 +1,81 @@ +/** + * 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 HAS_USER_THERMISTORS + +#include "../gcode.h" +#include "../../module/temperature.h" + +/** + * M305: Set (or report) custom thermistor parameters + * + * P[index] Thermistor table index + * R[ohms] Pullup resistor value + * T[ohms] Resistance at 25C + * B[beta] Thermistor "beta" value + * C[coeff] Steinhart-Hart Coefficient 'C' + * + * Format: M305 P[tbl_index] R[pullup_resistor_val] T[therm_25C_resistance] B[therm_beta] C[Steinhart_Hart_C_coeff] + * + * Examples: M305 P0 R4700 T100000 B3950 C0.0 + * M305 P0 R4700 + * M305 P0 T100000 + * M305 P0 B3950 + * M305 P0 C0.0 + */ +void GcodeSuite::M305() { + const int8_t t_index = parser.intval('P', -1); + const bool do_set = parser.seen("BCRT"); + + // A valid P index is required + if (t_index >= (USER_THERMISTORS) || (do_set && t_index < 0)) { + SERIAL_ECHO_START(); + SERIAL_ECHOLNPAIR("!Invalid index. (0 <= P <= ", int(USER_THERMISTORS - 1), ")"); + } + else if (do_set) { + if (parser.seen('R')) // Pullup resistor value + if (!thermalManager.set_pull_up_res(t_index, parser.value_float())) + SERIAL_ECHO_MSG("!Invalid series resistance. (0 < R < 1000000)"); + + if (parser.seen('T')) // Resistance at 25C + if (!thermalManager.set_res25(t_index, parser.value_float())) + SERIAL_ECHO_MSG("!Invalid 25C resistance. (0 < T < 10000000)"); + + if (parser.seen('B')) // Beta value + if (!thermalManager.set_beta(t_index, parser.value_float())) + SERIAL_ECHO_MSG("!Invalid beta. (0 < B < 1000000)"); + + if (parser.seen('C')) // Steinhart-Hart C coefficient + if (!thermalManager.set_sh_coeff(t_index, parser.value_float())) + 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) + thermalManager.log_user_thermistor(i); + } + else // ...one user thermistor + thermalManager.log_user_thermistor(t_index); +} + +#endif // HAS_USER_THERMISTORS diff --git a/Marlin/src/gcode/config/M43.cpp b/Marlin/src/gcode/config/M43.cpp new file mode 100644 index 0000000..005fdf0 --- /dev/null +++ b/Marlin/src/gcode/config/M43.cpp @@ -0,0 +1,386 @@ +/** + * 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(PINS_DEBUGGING) + +#include "../gcode.h" +#include "../../MarlinCore.h" // for pin_is_protected +#include "../../pins/pinsDebug.h" +#include "../../module/endstops.h" + +#if HAS_Z_SERVO_PROBE + #include "../../module/probe.h" + #include "../../module/servo.h" +#endif + +#if ENABLED(BLTOUCH) + #include "../../feature/bltouch.h" +#endif + +#if ENABLED(HOST_PROMPT_SUPPORT) + #include "../../feature/host_actions.h" +#endif + +#if ENABLED(EXTENSIBLE_UI) + #include "../../lcd/extui/ui_api.h" +#endif + +#if HAS_RESUME_CONTINUE + #include "../../lcd/marlinui.h" +#endif + +#ifndef GET_PIN_MAP_PIN_M43 + #define GET_PIN_MAP_PIN_M43(Q) GET_PIN_MAP_PIN(Q) +#endif + +inline void toggle_pins() { + const bool ignore_protection = parser.boolval('I'); + const int repeat = parser.intval('R', 1), + start = PARSED_PIN_INDEX('S', 0), + end = PARSED_PIN_INDEX('L', NUM_DIGITAL_PINS - 1), + wait = parser.intval('W', 500); + + LOOP_S_LE_N(i, start, end) { + 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))) { + report_pin_state_extended(pin, ignore_protection, true, PSTR("Untouched ")); + SERIAL_EOL(); + } + else { + watchdog_refresh(); + report_pin_state_extended(pin, ignore_protection, true, PSTR("Pulsing ")); + #ifdef __STM32F1__ + const auto prior_mode = _GET_MODE(i); + #else + const bool prior_mode = GET_PINMODE(pin); + #endif + #if AVR_AT90USB1286_FAMILY // Teensy IDEs don't know about these pins so must use FASTIO + if (pin == TEENSY_E2) { + SET_OUTPUT(TEENSY_E2); + for (int16_t j = 0; j < repeat; j++) { + WRITE(TEENSY_E2, LOW); safe_delay(wait); + WRITE(TEENSY_E2, HIGH); safe_delay(wait); + WRITE(TEENSY_E2, LOW); safe_delay(wait); + } + } + else if (pin == TEENSY_E3) { + SET_OUTPUT(TEENSY_E3); + for (int16_t j = 0; j < repeat; j++) { + WRITE(TEENSY_E3, LOW); safe_delay(wait); + WRITE(TEENSY_E3, HIGH); safe_delay(wait); + WRITE(TEENSY_E3, LOW); safe_delay(wait); + } + } + else + #endif + { + pinMode(pin, OUTPUT); + for (int16_t j = 0; j < repeat; j++) { + watchdog_refresh(); extDigitalWrite(pin, 0); safe_delay(wait); + watchdog_refresh(); extDigitalWrite(pin, 1); safe_delay(wait); + watchdog_refresh(); extDigitalWrite(pin, 0); safe_delay(wait); + watchdog_refresh(); + } + } + #ifdef __STM32F1__ + _SET_MODE(i, prior_mode); + #else + pinMode(pin, prior_mode); + #endif + } + SERIAL_EOL(); + } + SERIAL_ECHOLNPGM("Done."); + +} // toggle_pins + +inline void servo_probe_test() { + + #if !(NUM_SERVOS > 0 && HAS_SERVO_0) + + SERIAL_ERROR_MSG("SERVO not set up."); + + #elif !HAS_Z_SERVO_PROBE + + SERIAL_ERROR_MSG("Z_PROBE_SERVO_NR not set up."); + + #else // HAS_Z_SERVO_PROBE + + const uint8_t probe_index = parser.byteval('P', Z_PROBE_SERVO_NR); + + SERIAL_ECHOLNPAIR("Servo probe test\n" + ". using index: ", int(probe_index), + ", deploy angle: ", servo_angles[probe_index][0], + ", stow angle: ", servo_angles[probe_index][1] + ); + + bool deploy_state = false, stow_state; + + #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) + + #define PROBE_TEST_PIN Z_MIN_PIN + constexpr bool probe_inverting = Z_MIN_ENDSTOP_INVERTING; + + SERIAL_ECHOLNPAIR(". Probe Z_MIN_PIN: ", int(PROBE_TEST_PIN)); + SERIAL_ECHOPGM(". Z_MIN_ENDSTOP_INVERTING: "); + + #else + + #define PROBE_TEST_PIN Z_MIN_PROBE_PIN + constexpr bool probe_inverting = Z_MIN_PROBE_ENDSTOP_INVERTING; + + SERIAL_ECHOLNPAIR(". Probe Z_MIN_PROBE_PIN: ", int(PROBE_TEST_PIN)); + SERIAL_ECHOPGM( ". Z_MIN_PROBE_ENDSTOP_INVERTING: "); + + #endif + + serialprint_truefalse(probe_inverting); + SERIAL_EOL(); + + SET_INPUT_PULLUP(PROBE_TEST_PIN); + + // First, check for a probe that recognizes an advanced BLTouch sequence. + // In addition to STOW and DEPLOY, it uses SW MODE (and RESET in the beginning) + // to see if this is one of the following: BLTOUCH Classic 1.2, 1.3, or + // BLTouch Smart 1.0, 2.0, 2.2, 3.0, 3.1. But only if the user has actually + // configured a BLTouch as being present. If the user has not configured this, + // the BLTouch will be detected in the last phase of these tests (see further on). + bool blt = false; + // This code will try to detect a BLTouch probe or clone + #if ENABLED(BLTOUCH) + SERIAL_ECHOLNPGM(". Check for BLTOUCH"); + bltouch._reset(); + bltouch._stow(); + if (probe_inverting == READ(PROBE_TEST_PIN)) { + bltouch._set_SW_mode(); + if (probe_inverting != READ(PROBE_TEST_PIN)) { + bltouch._deploy(); + if (probe_inverting == READ(PROBE_TEST_PIN)) { + bltouch._stow(); + SERIAL_ECHOLNPGM("= BLTouch Classic 1.2, 1.3, Smart 1.0, 2.0, 2.2, 3.0, 3.1 detected."); + // Check for a 3.1 by letting the user trigger it, later + blt = true; + } + } + } + #endif + + // The following code is common to all kinds of servo probes. + // Since it could be a real servo or a BLTouch (any kind) or a clone, + // use only "common" functions - i.e. SERVO_MOVE. No bltouch.xxxx stuff. + + // If it is already recognised as a being a BLTouch, no need for this 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 { + MOVE_SERVO(probe_index, servo_angles[Z_PROBE_SERVO_NR][0]); // Deploy + safe_delay(500); + deploy_state = READ(PROBE_TEST_PIN); + MOVE_SERVO(probe_index, 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_ECHOLNPAIR(" DEPLOYED state: HIGH (logic 1)", + " STOWED (triggered) state: LOW (logic 0)"); + } + else { + SERIAL_ECHOLNPAIR(" DEPLOYED state: LOW (logic 0)", + " 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'."); + #endif + return; + } + } + + // Ask the user for a trigger event and measure the pulse width. + MOVE_SERVO(probe_index, servo_angles[Z_PROBE_SERVO_NR][0]); // Deploy + safe_delay(500); + SERIAL_ECHOLNPGM("** Please trigger probe within 30 sec **"); + uint16_t probe_counter = 0; + + // Wait 30 seconds for user to trigger probe + for (uint16_t j = 0; j < 500 * 30 && probe_counter == 0 ; j++) { + safe_delay(2); + + if (0 == j % (500 * 1)) gcode.reset_stepper_timeout(); // Keep steppers powered + + if (deploy_state != READ(PROBE_TEST_PIN)) { // probe triggered + for (probe_counter = 0; probe_counter < 15 && deploy_state != READ(PROBE_TEST_PIN); ++probe_counter) safe_delay(2); + + SERIAL_ECHOPGM(". Pulse width"); + if (probe_counter == 15) + SERIAL_ECHOLNPGM(": 30ms or more"); + else + SERIAL_ECHOLNPAIR(" (+/- 4ms): ", probe_counter * 2); + + if (probe_counter >= 4) { + if (probe_counter == 15) { + if (blt) SERIAL_ECHOPGM("= BLTouch V3.1"); + else SERIAL_ECHOPGM("= Z Servo Probe"); + } + else SERIAL_ECHOPGM("= BLTouch pre V3.1 (or compatible)"); + SERIAL_ECHOLNPGM(" detected."); + } + else SERIAL_ECHOLNPGM("FAIL: Noise detected - please re-run test"); + + MOVE_SERVO(probe_index, servo_angles[Z_PROBE_SERVO_NR][1]); // Stow + return; + } + } + + if (!probe_counter) SERIAL_ECHOLNPGM("FAIL: No trigger detected"); + + #endif // HAS_Z_SERVO_PROBE + +} // servo_probe_test + +/** + * M43: Pin debug - report pin state, watch pins, toggle pins and servo probe test/report + * + * M43 - report name and state of pin(s) + * P<pin> Pin to read or watch. If omitted, reads all pins. + * I Flag to ignore Marlin's pin protection. + * + * M43 W - Watch pins -reporting changes- until reset, click, or M108. + * P<pin> Pin to read or watch. If omitted, read/watch all pins. + * I Flag to ignore Marlin's pin protection. + * + * M43 E<bool> - Enable / disable background endstop monitoring + * - Machine continues to operate + * - Reports changes to endstops + * - Toggles LED_PIN when an endstop changes + * - Cannot reliably catch the 5mS pulse from BLTouch type probes + * + * M43 T - Toggle pin(s) and report which pin is being toggled + * S<pin> - Start Pin number. If not given, will default to 0 + * L<pin> - End Pin number. If not given, will default to last pin defined for this board + * I<bool> - Flag to ignore Marlin's pin protection. Use with caution!!!! + * R - Repeat pulses on each pin this number of times before continueing to next pin + * W - Wait time (in miliseconds) between pulses. If not given will default to 500 + * + * M43 S - Servo probe test + * P<index> - Probe index (optional - defaults to 0 + */ +void GcodeSuite::M43() { + + // 'T' must be first. It uses 'S' and 'E' differently. + if (parser.seen('T')) return toggle_pins(); + + // 'E' Enable or disable endstop monitoring and return + if (parser.seen('E')) { + endstops.monitor_flag = parser.value_bool(); + SERIAL_ECHOPGM("endstop monitor "); + serialprintPGM(endstops.monitor_flag ? PSTR("en") : PSTR("dis")); + SERIAL_ECHOLNPGM("abled"); + return; + } + + // 'S' Run servo probe test and return + if (parser.seen('S')) return servo_probe_test(); + + // 'P' Get the range of pins to test or watch + uint8_t first_pin = PARSED_PIN_INDEX('P', 0), + last_pin = parser.seenval('P') ? first_pin : NUMBER_PINS_TOTAL - 1; + + if (first_pin > last_pin) return; + + // 'I' to ignore protected pins + const bool ignore_protection = parser.boolval('I'); + + // 'W' Watch until click, M108, or reset + if (parser.boolval('W')) { + SERIAL_ECHOLNPGM("Watching pins"); + #ifdef ARDUINO_ARCH_SAM + NOLESS(first_pin, 2); // Don't hijack the UART pins + #endif + uint8_t pin_state[last_pin - first_pin + 1]; + LOOP_S_LE_N(i, first_pin, last_pin) { + 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; + pinMode(pin, INPUT_PULLUP); + delay(1); + /* + if (IS_ANALOG(pin)) + pin_state[pin - first_pin] = analogRead(DIGITAL_PIN_TO_ANALOG_PIN(pin)); // int16_t pin_state[...] + else + //*/ + pin_state[i - first_pin] = extDigitalRead(pin); + } + + #if HAS_RESUME_CONTINUE + KEEPALIVE_STATE(PAUSED_FOR_USER); + wait_for_user = true; + TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("M43 Wait Called"), CONTINUE_STR)); + TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("M43 Wait Called"))); + #endif + + for (;;) { + LOOP_S_LE_N(i, first_pin, last_pin) { + 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; + const byte val = + /* + IS_ANALOG(pin) + ? analogRead(DIGITAL_PIN_TO_ANALOG_PIN(pin)) : // int16_t val + : + //*/ + extDigitalRead(pin); + if (val != pin_state[i - first_pin]) { + report_pin_state_extended(pin, ignore_protection, false); + pin_state[i - first_pin] = val; + } + } + + #if HAS_RESUME_CONTINUE + ui.update(); + if (!wait_for_user) break; + #endif + + safe_delay(200); + } + } + else { + // Report current state of selected pin(s) + LOOP_S_LE_N(i, first_pin, last_pin) { + pin_t pin = GET_PIN_MAP_PIN_M43(i); + if (VALID_PIN(pin)) report_pin_state_extended(pin, ignore_protection, true); + } + } +} + +#endif // PINS_DEBUGGING diff --git a/Marlin/src/gcode/config/M540.cpp b/Marlin/src/gcode/config/M540.cpp new file mode 100644 index 0000000..54d52f3 --- /dev/null +++ b/Marlin/src/gcode/config/M540.cpp @@ -0,0 +1,40 @@ +/** + * 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(SD_ABORT_ON_ENDSTOP_HIT) + +#include "../gcode.h" +#include "../../module/stepper.h" + +/** + * M540: Set whether SD card print should abort on endstop hit (M540 S<0|1>) + */ +void GcodeSuite::M540() { + + if (parser.seen('S')) + planner.abort_on_endstop_hit = parser.value_bool(); + +} + +#endif // SD_ABORT_ON_ENDSTOP_HIT diff --git a/Marlin/src/gcode/config/M575.cpp b/Marlin/src/gcode/config/M575.cpp new file mode 100644 index 0000000..44723b7 --- /dev/null +++ b/Marlin/src/gcode/config/M575.cpp @@ -0,0 +1,75 @@ +/** + * 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(BAUD_RATE_GCODE) + +#include "../gcode.h" + +/** + * M575 - Change serial baud rate + * + * P<index> - Serial port index. Omit for all. + * B<baudrate> - Baud rate (bits per second) + */ +void GcodeSuite::M575() { + 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: { + const int8_t port = parser.intval('P', -99); + const bool set0 = (port == -99 || port == 0); + if (set0) SERIAL_ECHO_MSG(" Serial ", '0', " baud rate set to ", baud); + #if HAS_MULTI_SERIAL + const bool set1 = (port == -99 || port == 1); + if (set1) SERIAL_ECHO_MSG(" Serial ", '1', " baud rate set to ", baud); + #endif + + SERIAL_FLUSH(); + + if (set0) { MYSERIAL0.end(); MYSERIAL0.begin(baud); } + + #if HAS_MULTI_SERIAL + if (set1) { MYSERIAL1.end(); MYSERIAL1.begin(baud); } + #endif + + } break; + default: SERIAL_ECHO_MSG("?(B)aud rate implausible."); + } +} + +#endif // BAUD_RATE_GCODE diff --git a/Marlin/src/gcode/config/M672.cpp b/Marlin/src/gcode/config/M672.cpp new file mode 100644 index 0000000..af74230 --- /dev/null +++ b/Marlin/src/gcode/config/M672.cpp @@ -0,0 +1,98 @@ +/** + * 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(DUET_SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD) + +#include "../gcode.h" +#include "../../HAL/shared/Delay.h" +#include "../parser.h" + +/** + * 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 + * + * To set custom sensitivity: + * Duet: M672 S105:aaa:bbb + * Marlin: M672 Saaa + * + * (where aaa is the desired sensitivity and bbb is 255 - aaa). + * + * Revert sensitivity to factory settings: + * Duet: M672 S105:131:131 + * Marlin: M672 R + */ + +#define M672_PROGBYTE 105 // magic byte to start programming custom sensitivity +#define M672_ERASEBYTE 131 // magic byte to clear custom sensitivity + +// +// Smart Effector byte send protocol: +// +// 0 0 1 0 ... always 0010 +// b7 b6 b5 b4 ~b4 ... hi bits, NOT last bit +// 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) { + switch (bits) { + default: { OUT_WRITE(SMART_EFFECTOR_MOD_PIN, !!(b & 0x80)); b <<= 1; break; } // send bit, shift next into place + case 7: + case 12: { OUT_WRITE(SMART_EFFECTOR_MOD_PIN, !!(b & 0x80)); break; } // send bit. no shift + case 8: + case 13: { OUT_WRITE(SMART_EFFECTOR_MOD_PIN, !(b & 0x80)); b <<= 1; break; } // send inverted previous bit + case 0: case 1: // 00 + case 3: { OUT_WRITE(SMART_EFFECTOR_MOD_PIN, LOW); break; } // 0010 + case 2: { OUT_WRITE(SMART_EFFECTOR_MOD_PIN, HIGH); break; } // 001 + } + DELAY_US(1000); + } +} + +/** + * 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); + M672_send(M672_ERASEBYTE); + } + else if (parser.seenval('S')) { + const int8_t M672_sensitivity = parser.value_byte(); + M672_send(M672_PROGBYTE); + M672_send(M672_sensitivity); + M672_send(255 - M672_sensitivity); + } + else { + SERIAL_ECHO_MSG("!'S' or 'R' parameter required."); + return; + } + + OUT_WRITE(SMART_EFFECTOR_MOD_PIN, LOW); // Keep Smart Effector in NORMAL mode +} + +#endif // DUET_SMART_EFFECTOR && SMART_EFFECTOR_MOD_PIN diff --git a/Marlin/src/gcode/config/M92.cpp b/Marlin/src/gcode/config/M92.cpp new file mode 100644 index 0000000..0a7d52b --- /dev/null +++ b/Marlin/src/gcode/config/M92.cpp @@ -0,0 +1,114 @@ +/** + * 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 "../gcode.h" +#include "../../module/planner.h" + +void report_M92(const bool echo=true, const int8_t e=-1) { + if (echo) SERIAL_ECHO_START(); else SERIAL_CHAR(' '); + SERIAL_ECHOPAIR_P(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])); + #if DISABLED(DISTINCT_E_FACTORS) + SERIAL_ECHOPAIR_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS])); + #endif + SERIAL_EOL(); + + #if ENABLED(DISTINCT_E_FACTORS) + LOOP_L_N(i, E_STEPPERS) { + if (e >= 0 && i != e) continue; + if (echo) SERIAL_ECHO_START(); else SERIAL_CHAR(' '); + SERIAL_ECHOLNPAIR_P(PSTR(" M92 T"), (int)i, + SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS_N(i)])); + } + #endif + + UNUSED_E(e); +} + +/** + * M92: Set axis steps-per-unit for one or more axes, X, Y, Z, and E. + * (Follows the same syntax as G92) + * + * With multiple extruders use T to specify which one. + * + * If no argument is given print the current values. + * + * With MAGIC_NUMBERS_GCODE: + * Use 'H' and/or 'L' to get ideal layer-height information. + * 'H' specifies micro-steps to use. We guess if it's not supplied. + * 'L' specifies a desired layer height. Nearest good heights are shown. + */ +void GcodeSuite::M92() { + + const int8_t target_extruder = get_target_extruder_from_command(); + if (target_extruder < 0) return; + + // No arguments? Show M92 report. + if (!parser.seen("XYZE" + #if ENABLED(MAGIC_NUMBERS_GCODE) + "HL" + #endif + )) return report_M92(true, target_extruder); + + LOOP_XYZE(i) { + if (parser.seenval(axis_codes[i])) { + if (i == E_AXIS) { + const float value = parser.value_per_axis_units((AxisEnum)(E_AXIS_N(target_extruder))); + if (value < 20) { + float factor = planner.settings.axis_steps_per_mm[E_AXIS_N(target_extruder)] / value; // increase e constants if M92 E14 is given for netfab. + #if HAS_CLASSIC_JERK && HAS_CLASSIC_E_JERK + planner.max_jerk.e *= factor; + #endif + planner.settings.max_feedrate_mm_s[E_AXIS_N(target_extruder)] *= factor; + planner.max_acceleration_steps_per_s2[E_AXIS_N(target_extruder)] *= factor; + } + planner.settings.axis_steps_per_mm[E_AXIS_N(target_extruder)] = value; + } + else { + planner.settings.axis_steps_per_mm[i] = parser.value_per_axis_units((AxisEnum)i); + } + } + } + planner.refresh_positioning(); + + #if ENABLED(MAGIC_NUMBERS_GCODE) + #ifndef Z_MICROSTEPS + #define Z_MICROSTEPS 16 + #endif + const float wanted = parser.floatval('L'); + if (parser.seen('H') || wanted) { + const uint16_t argH = parser.ushortval('H'), + micro_steps = argH ?: Z_MICROSTEPS; + const float z_full_step_mm = micro_steps * planner.steps_to_mm[Z_AXIS]; + SERIAL_ECHO_START(); + SERIAL_ECHOPAIR("{ micro_steps:", micro_steps, ", z_full_step_mm:", z_full_step_mm); + if (wanted) { + const float best = uint16_t(wanted / z_full_step_mm) * z_full_step_mm; + SERIAL_ECHOPAIR(", best:[", best); + if (best != wanted) { SERIAL_CHAR(','); SERIAL_DECIMAL(best + z_full_step_mm); } + SERIAL_CHAR(']'); + } + SERIAL_ECHOLNPGM(" }"); + } + #endif +} |