Browse Source

🎨 Standardize G-code reporting

Scott Lahteine 2 years ago
parent
commit
79c72ed821
48 changed files with 1359 additions and 1169 deletions
  1. 5
    5
      Marlin/src/HAL/AVR/pinsDebug.h
  2. 44
    3
      Marlin/src/core/language.h
  3. 2
    0
      Marlin/src/core/types.h
  4. 4
    7
      Marlin/src/feature/fwretract.cpp
  5. 3
    3
      Marlin/src/feature/fwretract.h
  6. 14
    0
      Marlin/src/gcode/bedlevel/M420.cpp
  7. 24
    10
      Marlin/src/gcode/calibrate/G34_M422.cpp
  8. 18
    0
      Marlin/src/gcode/calibrate/M425.cpp
  9. 36
    0
      Marlin/src/gcode/calibrate/M665.cpp
  10. 35
    33
      Marlin/src/gcode/calibrate/M666.cpp
  11. 17
    17
      Marlin/src/gcode/calibrate/M852.cpp
  12. 136
    6
      Marlin/src/gcode/config/M200-M205.cpp
  13. 35
    38
      Marlin/src/gcode/config/M217.cpp
  14. 15
    14
      Marlin/src/gcode/config/M218.cpp
  15. 23
    14
      Marlin/src/gcode/config/M281.cpp
  16. 40
    23
      Marlin/src/gcode/config/M301.cpp
  17. 9
    5
      Marlin/src/gcode/config/M304.cpp
  18. 2
    2
      Marlin/src/gcode/config/M305.cpp
  19. 9
    4
      Marlin/src/gcode/config/M309.cpp
  20. 3
    3
      Marlin/src/gcode/config/M575.cpp
  21. 37
    36
      Marlin/src/gcode/config/M92.cpp
  22. 2
    2
      Marlin/src/gcode/control/M17_M18_M84.cpp
  23. 13
    5
      Marlin/src/gcode/control/M211.cpp
  24. 13
    0
      Marlin/src/gcode/feature/advance/M900.cpp
  25. 12
    12
      Marlin/src/gcode/feature/controllerfan/M710.cpp
  26. 40
    2
      Marlin/src/gcode/feature/digipot/M907-M910.cpp
  27. 25
    0
      Marlin/src/gcode/feature/fwretract/M207-M209.cpp
  28. 21
    15
      Marlin/src/gcode/feature/network/M552-M554.cpp
  29. 18
    0
      Marlin/src/gcode/feature/pause/M603.cpp
  30. 8
    5
      Marlin/src/gcode/feature/powerloss/M413.cpp
  31. 12
    0
      Marlin/src/gcode/feature/runout/M412.cpp
  32. 62
    0
      Marlin/src/gcode/feature/trinamic/M569.cpp
  33. 95
    0
      Marlin/src/gcode/feature/trinamic/M906.cpp
  34. 160
    0
      Marlin/src/gcode/feature/trinamic/M911-M914.cpp
  35. 19
    1
      Marlin/src/gcode/gcode.cpp
  36. 69
    12
      Marlin/src/gcode/gcode.h
  37. 21
    17
      Marlin/src/gcode/geometry/M206_M428.cpp
  38. 19
    0
      Marlin/src/gcode/lcd/M145.cpp
  39. 9
    3
      Marlin/src/gcode/lcd/M250.cpp
  40. 9
    2
      Marlin/src/gcode/lcd/M256.cpp
  41. 7
    0
      Marlin/src/gcode/lcd/M414.cpp
  42. 8
    9
      Marlin/src/gcode/parser.h
  43. 18
    13
      Marlin/src/gcode/probe/M851.cpp
  44. 7
    0
      Marlin/src/gcode/units/M149.cpp
  45. 2
    2
      Marlin/src/module/endstops.cpp
  46. 164
    828
      Marlin/src/module/settings.cpp
  47. 14
    17
      Marlin/src/module/temperature.cpp
  48. 1
    1
      Marlin/src/module/temperature.h

+ 5
- 5
Marlin/src/HAL/AVR/pinsDebug.h View File

@@ -235,7 +235,7 @@ static void print_is_also_tied() { SERIAL_ECHOPGM(" is also tied to this pin");
235 235
 
236 236
 inline void com_print(const uint8_t N, const uint8_t Z) {
237 237
   const uint8_t *TCCRA = (uint8_t*)TCCR_A(N);
238
-  SERIAL_ECHOPAIR("    COM", AS_CHAR('0' + N));
238
+  SERIAL_ECHOPAIR("    COM", AS_DIGIT(N));
239 239
   SERIAL_CHAR(Z);
240 240
   SERIAL_ECHOPAIR(": ", int((*TCCRA >> (6 - Z * 2)) & 0x03));
241 241
 }
@@ -247,7 +247,7 @@ void timer_prefix(uint8_t T, char L, uint8_t N) {  // T - timer    L - pwm  N -
247 247
   uint8_t WGM = (((*TCCRB & _BV(WGM_2)) >> 1) | (*TCCRA & (_BV(WGM_0) | _BV(WGM_1))));
248 248
   if (N == 4) WGM |= ((*TCCRB & _BV(WGM_3)) >> 1);
249 249
 
250
-  SERIAL_ECHOPAIR("    TIMER", AS_CHAR(T + '0'));
250
+  SERIAL_ECHOPAIR("    TIMER", AS_DIGIT(T));
251 251
   SERIAL_CHAR(L);
252 252
   SERIAL_ECHO_SP(3);
253 253
 
@@ -262,11 +262,11 @@ void timer_prefix(uint8_t T, char L, uint8_t N) {  // T - timer    L - pwm  N -
262 262
   SERIAL_ECHOPAIR("    WGM: ", WGM);
263 263
   com_print(T,L);
264 264
   SERIAL_ECHOPAIR("    CS: ", (*TCCRB & (_BV(CS_0) | _BV(CS_1) | _BV(CS_2)) ));
265
-  SERIAL_ECHOPAIR("    TCCR", AS_CHAR(T + '0'), "A: ", *TCCRA);
266
-  SERIAL_ECHOPAIR("    TCCR", AS_CHAR(T + '0'), "B: ", *TCCRB);
265
+  SERIAL_ECHOPAIR("    TCCR", AS_DIGIT(T), "A: ", *TCCRA);
266
+  SERIAL_ECHOPAIR("    TCCR", AS_DIGIT(T), "B: ", *TCCRB);
267 267
 
268 268
   const uint8_t *TMSK = (uint8_t*)TIMSK(T);
269
-  SERIAL_ECHOPAIR("    TIMSK", AS_CHAR(T + '0'), ": ", *TMSK);
269
+  SERIAL_ECHOPAIR("    TIMSK", AS_DIGIT(T), ": ", *TMSK);
270 270
 
271 271
   const uint8_t OCIE = L - 'A' + 1;
272 272
   if (N == 3) { if (WGM == 0 || WGM == 2 || WGM ==  4 || WGM ==  6) err_is_counter(); }

+ 44
- 3
Marlin/src/core/language.h View File

@@ -158,9 +158,7 @@
158 158
 #define STR_OFF                             "OFF"
159 159
 #define STR_ENDSTOP_HIT                     "TRIGGERED"
160 160
 #define STR_ENDSTOP_OPEN                    "open"
161
-#define STR_HOTEND_OFFSET                   "Hotend offsets:"
162 161
 #define STR_DUPLICATION_MODE                "Duplication mode: "
163
-#define STR_SOFT_ENDSTOPS                   "Soft endstops: "
164 162
 #define STR_SOFT_MIN                        "  Min: "
165 163
 #define STR_SOFT_MAX                        "  Max: "
166 164
 
@@ -262,6 +260,49 @@
262 260
 #define STR_REMINDER_SAVE_SETTINGS          "Remember to save!"
263 261
 #define STR_PASSWORD_SET                    "Password is "
264 262
 
263
+// Settings Report Strings
264
+#define STR_Z_AUTO_ALIGN                    "Z Auto-Align"
265
+#define STR_BACKLASH_COMPENSATION           "Backlash compensation"
266
+#define STR_DELTA_SETTINGS                  "Delta settings (L<diagonal-rod> R<radius> H<height> S<segments-per-sec> XYZ<tower-angle-trim> ABC<rod-trim>)"
267
+#define STR_SCARA_SETTINGS                  "SCARA settings"
268
+#define STR_SCARA_S                         "S<seg-per-sec>"
269
+#define STR_SCARA_P_T_Z                     "P<theta-psi-offset> T<theta-offset> Z<home-offset>"
270
+#define STR_ENDSTOP_ADJUSTMENT              "Endstop adjustment"
271
+#define STR_SKEW_FACTOR                     "Skew Factor"
272
+#define STR_FILAMENT_SETTINGS               "Filament settings"
273
+#define STR_MAX_ACCELERATION                "Max Acceleration (units/s2)"
274
+#define STR_MAX_FEEDRATES                   "Max feedrates (units/s)"
275
+#define STR_ACCELERATION_P_R_T              "Acceleration (units/s2) (P<print-accel> R<retract-accel> T<travel-accel>)"
276
+#define STR_TOOL_CHANGING                   "Tool-changing"
277
+#define STR_HOTEND_OFFSETS                  "Hotend offsets"
278
+#define STR_SERVO_ANGLES                    "Servo Angles"
279
+#define STR_HOTEND_PID                      "Hotend PID"
280
+#define STR_BED_PID                         "Bed PID"
281
+#define STR_CHAMBER_PID                     "Chamber PID"
282
+#define STR_STEPS_PER_UNIT                  "Steps per unit"
283
+#define STR_LINEAR_ADVANCE                  "Linear Advance"
284
+#define STR_CONTROLLER_FAN                  "Controller Fan"
285
+#define STR_STEPPER_MOTOR_CURRENTS          "Stepper motor currents"
286
+#define STR_RETRACT_S_F_Z                   "Retract (S<length> F<feedrate> Z<lift>)"
287
+#define STR_RECOVER_S_F                     "Recover (S<length> F<feedrate>)"
288
+#define STR_AUTO_RETRACT_S                  "Auto-Retract (S<enable>)"
289
+#define STR_FILAMENT_LOAD_UNLOAD            "Filament load/unload"
290
+#define STR_POWER_LOSS_RECOVERY             "Power-loss recovery"
291
+#define STR_FILAMENT_RUNOUT_SENSOR          "Filament runout sensor"
292
+#define STR_DRIVER_STEPPING_MODE            "Driver stepping mode"
293
+#define STR_STEPPER_DRIVER_CURRENT          "Stepper driver current"
294
+#define STR_HYBRID_THRESHOLD                "Hybrid Threshold"
295
+#define STR_STALLGUARD_THRESHOLD            "StallGuard threshold"
296
+#define STR_HOME_OFFSET                     "Home offset"
297
+#define STR_SOFT_ENDSTOPS                   "Soft endstops"
298
+#define STR_MATERIAL_HEATUP                 "Material heatup parameters"
299
+#define STR_LCD_CONTRAST                    "LCD Contrast"
300
+#define STR_LCD_BRIGHTNESS                  "LCD Brightness"
301
+#define STR_UI_LANGUAGE                     "UI Language"
302
+#define STR_Z_PROBE_OFFSET                  "Z-Probe Offset"
303
+#define STR_TEMPERATURE_UNITS               "Temperature Units"
304
+#define STR_USER_THERMISTORS                "User thermistors"
305
+
265 306
 //
266 307
 // Endstop Names used by Endstops::report_states
267 308
 //
@@ -290,7 +331,7 @@
290 331
 
291 332
 #define STR_Z_PROBE                         "z_probe"
292 333
 #define STR_PROBE_EN                        "probe_en"
293
-#define STR_FILAMENT_RUNOUT_SENSOR          "filament"
334
+#define STR_FILAMENT                        "filament"
294 335
 
295 336
 // General axis names
296 337
 #define STR_X "X"

+ 2
- 0
Marlin/src/core/types.h View File

@@ -55,6 +55,8 @@ struct IF<true, L, R> { typedef L type; };
55 55
 #define LOGICAL_AXIS_ELEM(O)    LOGICAL_AXIS_LIST(O.e, O.x, O.y, O.z, O.i, O.j, O.k)
56 56
 #define LOGICAL_AXIS_DECL(T,V)  LOGICAL_AXIS_LIST(T e=V, T x=V, T y=V, T z=V, T i=V, T j=V, T k=V)
57 57
 
58
+#define LOGICAL_AXES_STRING LOGICAL_AXIS_GANG("E", "X", "Y", "Z", AXIS4_STR, AXIS5_STR, AXIS6_STR)
59
+
58 60
 #if HAS_EXTRUDERS
59 61
   #define LIST_ITEM_E(N) , N
60 62
   #define CODE_ITEM_E(N) ; N

+ 4
- 7
Marlin/src/feature/fwretract.cpp View File

@@ -36,7 +36,7 @@ FWRetract fwretract; // Single instance - this calls the constructor
36 36
 #include "../module/planner.h"
37 37
 #include "../module/stepper.h"
38 38
 
39
-#include "../gcode/parser.h"
39
+#include "../gcode/gcode.h"
40 40
 
41 41
 #if ENABLED(RETRACT_SYNC_MIXING)
42 42
   #include "mixing.h"
@@ -214,8 +214,7 @@ void FWRetract::M207() {
214 214
   if (parser.seenval('W')) settings.swap_retract_length   = parser.value_axis_units(E_AXIS);
215 215
 }
216 216
 
217
-void FWRetract::M207_report(const bool forReplay/*=false*/) {
218
-  if (!forReplay) { SERIAL_ECHO_MSG("; Retract: S<length> F<units/m> Z<lift>"); SERIAL_ECHO_START(); }
217
+void FWRetract::M207_report() {
219 218
   SERIAL_ECHOLNPAIR_P(
220 219
       PSTR("  M207 S"), LINEAR_UNIT(settings.retract_length)
221 220
     , PSTR(" W"), LINEAR_UNIT(settings.swap_retract_length)
@@ -240,8 +239,7 @@ void FWRetract::M208() {
240 239
   if (parser.seen('W')) settings.swap_retract_recover_extra         = parser.value_axis_units(E_AXIS);
241 240
 }
242 241
 
243
-void FWRetract::M208_report(const bool forReplay/*=false*/) {
244
-  if (!forReplay) { SERIAL_ECHO_MSG("; Recover: S<length> F<units/m>"); SERIAL_ECHO_START(); }
242
+void FWRetract::M208_report() {
245 243
   SERIAL_ECHOLNPAIR(
246 244
       "  M208 S", LINEAR_UNIT(settings.retract_recover_extra)
247 245
     , " W", LINEAR_UNIT(settings.swap_retract_recover_extra)
@@ -262,8 +260,7 @@ void FWRetract::M208_report(const bool forReplay/*=false*/) {
262 260
       enable_autoretract(parser.value_bool());
263 261
   }
264 262
 
265
-  void FWRetract::M209_report(const bool forReplay/*=false*/) {
266
-    if (!forReplay) { SERIAL_ECHO_MSG("; Auto-Retract: S=0 to disable, 1 to interpret E-only moves as retract/recover"); SERIAL_ECHO_START(); }
263
+  void FWRetract::M209_report() {
267 264
     SERIAL_ECHOLNPAIR("  M209 S", AS_DIGIT(autoretract_enabled));
268 265
   }
269 266
 

+ 3
- 3
Marlin/src/feature/fwretract.h View File

@@ -76,13 +76,13 @@ public:
76 76
 
77 77
   static void retract(const bool retracting OPTARG(HAS_MULTI_EXTRUDER, bool swapping = false));
78 78
 
79
+  static void M207_report();
79 80
   static void M207();
80
-  static void M207_report(const bool forReplay=false);
81
+  static void M208_report();
81 82
   static void M208();
82
-  static void M208_report(const bool forReplay=false);
83 83
   #if ENABLED(FWRETRACT_AUTORETRACT)
84
+    static void M209_report();
84 85
     static void M209();
85
-    static void M209_report(const bool forReplay=false);
86 86
   #endif
87 87
 };
88 88
 

+ 14
- 0
Marlin/src/gcode/bedlevel/M420.cpp View File

@@ -242,4 +242,18 @@ void GcodeSuite::M420() {
242 242
     report_current_position();
243 243
 }
244 244
 
245
+void GcodeSuite::M420_report(const bool forReplay/*=true*/) {
246
+  report_heading_etc(forReplay, PSTR(
247
+    TERN(MESH_BED_LEVELING, "Mesh Bed Leveling", TERN(AUTO_BED_LEVELING_UBL, "Unified Bed Leveling", "Auto Bed Leveling"))
248
+  ));
249
+  SERIAL_ECHOPAIR_P(
250
+    PSTR("  M420 S"), planner.leveling_active
251
+    #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
252
+      , SP_Z_STR, LINEAR_UNIT(planner.z_fade_height)
253
+    #endif
254
+    , " ; Leveling "
255
+  );
256
+  serialprintln_onoff(planner.leveling_active);
257
+}
258
+
245 259
 #endif // HAS_LEVELING

+ 24
- 10
Marlin/src/gcode/calibrate/G34_M422.cpp View File

@@ -475,21 +475,13 @@ void GcodeSuite::G34() {
475 475
  */
476 476
 void GcodeSuite::M422() {
477 477
 
478
+  if (!parser.seen_any()) return M422_report();
479
+
478 480
   if (parser.seen('R')) {
479 481
     z_stepper_align.reset_to_default();
480 482
     return;
481 483
   }
482 484
 
483
-  if (!parser.seen_any()) {
484
-    LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS)
485
-      SERIAL_ECHOLNPAIR_P(PSTR("M422 S"), i + 1, SP_X_STR, z_stepper_align.xy[i].x, SP_Y_STR, z_stepper_align.xy[i].y);
486
-    #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
487
-      LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS)
488
-        SERIAL_ECHOLNPAIR_P(PSTR("M422 W"), i + 1, SP_X_STR, z_stepper_align.stepper_xy[i].x, SP_Y_STR, z_stepper_align.stepper_xy[i].y);
489
-    #endif
490
-    return;
491
-  }
492
-
493 485
   const bool is_probe_point = parser.seen('S');
494 486
 
495 487
   if (TERN0(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS, is_probe_point && parser.seen('W'))) {
@@ -545,4 +537,26 @@ void GcodeSuite::M422() {
545 537
   pos_dest[position_index] = pos;
546 538
 }
547 539
 
540
+void GcodeSuite::M422_report(const bool forReplay/*=true*/) {
541
+  report_heading(forReplay, PSTR(STR_Z_AUTO_ALIGN));
542
+  LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS) {
543
+    report_echo_start(forReplay);
544
+    SERIAL_ECHOLNPAIR_P(
545
+      PSTR("  M422 S"), i + 1,
546
+      SP_X_STR, z_stepper_align.xy[i].x,
547
+      SP_Y_STR, z_stepper_align.xy[i].y
548
+    );
549
+  }
550
+  #if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
551
+    LOOP_L_N(i, NUM_Z_STEPPER_DRIVERS) {
552
+      report_echo_start(forReplay);
553
+      SERIAL_ECHOLNPAIR_P(
554
+        PSTR("  M422 W"), i + 1,
555
+        SP_X_STR, z_stepper_align.stepper_xy[i].x,
556
+        SP_Y_STR, z_stepper_align.stepper_xy[i].y
557
+      );
558
+    }
559
+  #endif
560
+}
561
+
548 562
 #endif // Z_STEPPER_AUTO_ALIGN

+ 18
- 0
Marlin/src/gcode/calibrate/M425.cpp View File

@@ -113,4 +113,22 @@ void GcodeSuite::M425() {
113 113
   }
114 114
 }
115 115
 
116
+void GcodeSuite::M425_report(const bool forReplay/*=true*/) {
117
+  report_heading_etc(forReplay, PSTR(STR_BACKLASH_COMPENSATION));
118
+  SERIAL_ECHOLNPAIR_P(
119
+    PSTR("  M425 F"), backlash.get_correction()
120
+    #ifdef BACKLASH_SMOOTHING_MM
121
+      , PSTR(" S"), LINEAR_UNIT(backlash.smoothing_mm)
122
+    #endif
123
+    , LIST_N(DOUBLE(LINEAR_AXES),
124
+        SP_X_STR, LINEAR_UNIT(backlash.distance_mm.x),
125
+        SP_Y_STR, LINEAR_UNIT(backlash.distance_mm.y),
126
+        SP_Z_STR, LINEAR_UNIT(backlash.distance_mm.z),
127
+        SP_I_STR, LINEAR_UNIT(backlash.distance_mm.i),
128
+        SP_J_STR, LINEAR_UNIT(backlash.distance_mm.j),
129
+        SP_K_STR, LINEAR_UNIT(backlash.distance_mm.k)
130
+      )
131
+  );
132
+}
133
+
116 134
 #endif // BACKLASH_GCODE

+ 36
- 0
Marlin/src/gcode/calibrate/M665.cpp View File

@@ -30,6 +30,7 @@
30 30
 #if ENABLED(DELTA)
31 31
 
32 32
   #include "../../module/delta.h"
33
+
33 34
   /**
34 35
    * M665: Set delta configurations
35 36
    *
@@ -45,6 +46,8 @@
45 46
    *    C = Gamma (Tower 3) diagonal rod trim
46 47
    */
47 48
   void GcodeSuite::M665() {
49
+    if (!parser.seen_any()) return M665_report();
50
+
48 51
     if (parser.seenval('H')) delta_height              = parser.value_linear_units();
49 52
     if (parser.seenval('L')) delta_diagonal_rod        = parser.value_linear_units();
50 53
     if (parser.seenval('R')) delta_radius              = parser.value_linear_units();
@@ -58,6 +61,22 @@
58 61
     recalc_delta_settings();
59 62
   }
60 63
 
64
+  void GcodeSuite::M665_report(const bool forReplay/*=true*/) {
65
+    report_heading_etc(forReplay, PSTR(STR_DELTA_SETTINGS));
66
+    SERIAL_ECHOLNPAIR_P(
67
+        PSTR("  M665 L"), LINEAR_UNIT(delta_diagonal_rod)
68
+      , PSTR(" R"), LINEAR_UNIT(delta_radius)
69
+      , PSTR(" H"), LINEAR_UNIT(delta_height)
70
+      , PSTR(" S"), segments_per_second
71
+      , SP_X_STR, LINEAR_UNIT(delta_tower_angle_trim.a)
72
+      , SP_Y_STR, LINEAR_UNIT(delta_tower_angle_trim.b)
73
+      , SP_Z_STR, LINEAR_UNIT(delta_tower_angle_trim.c)
74
+      , PSTR(" A"), LINEAR_UNIT(delta_diagonal_rod_trim.a)
75
+      , PSTR(" B"), LINEAR_UNIT(delta_diagonal_rod_trim.b)
76
+      , PSTR(" C"), LINEAR_UNIT(delta_diagonal_rod_trim.c)
77
+    );
78
+  }
79
+
61 80
 #elif IS_SCARA
62 81
 
63 82
   #include "../../module/scara.h"
@@ -68,6 +87,9 @@
68 87
    * Parameters:
69 88
    *
70 89
    *   S[segments-per-second] - Segments-per-second
90
+   *
91
+   * Without NO_WORKSPACE_OFFSETS:
92
+   *
71 93
    *   P[theta-psi-offset]    - Theta-Psi offset, added to the shoulder (A/X) angle
72 94
    *   T[theta-offset]        - Theta     offset, added to the elbow    (B/Y) angle
73 95
    *   Z[z-offset]            - Z offset, added to Z
@@ -76,6 +98,8 @@
76 98
    *   B, T, and Y are all aliases for the elbow angle
77 99
    */
78 100
   void GcodeSuite::M665() {
101
+    if (!parser.seen_any()) return M665_report();
102
+
79 103
     if (parser.seenval('S')) segments_per_second = parser.value_float();
80 104
 
81 105
     #if HAS_SCARA_OFFSET
@@ -107,6 +131,18 @@
107 131
     #endif // HAS_SCARA_OFFSET
108 132
   }
109 133
 
134
+  void GcodeSuite::M665_report(const bool forReplay/*=true*/) {
135
+    report_heading_etc(forReplay, PSTR(STR_SCARA_SETTINGS " (" STR_SCARA_S TERN_(HAS_SCARA_OFFSET, " " STR_SCARA_P_T_Z) ")"));
136
+    SERIAL_ECHOLNPAIR_P(
137
+      PSTR("  M665 S"), segments_per_second
138
+      #if HAS_SCARA_OFFSET
139
+        , SP_P_STR, scara_home_offset.a
140
+        , SP_T_STR, scara_home_offset.b
141
+        , SP_Z_STR, LINEAR_UNIT(scara_home_offset.z)
142
+      #endif
143
+    );
144
+  }
145
+
110 146
 #endif
111 147
 
112 148
 #endif // IS_KINEMATIC

+ 35
- 33
Marlin/src/gcode/calibrate/M666.cpp View File

@@ -36,38 +36,6 @@
36 36
 #define DEBUG_OUT ENABLED(DEBUG_LEVELING_FEATURE)
37 37
 #include "../../core/debug_out.h"
38 38
 
39
-void M666_report(const bool forReplay=true) {
40
-  if (!forReplay) { SERIAL_ECHOLNPGM("; Endstop adjustment:"); SERIAL_ECHO_START(); }
41
-  #if ENABLED(DELTA)
42
-    SERIAL_ECHOLNPAIR_P(
43
-        PSTR("  M666 X"), LINEAR_UNIT(delta_endstop_adj.a)
44
-      , SP_Y_STR, LINEAR_UNIT(delta_endstop_adj.b)
45
-      , SP_Z_STR, LINEAR_UNIT(delta_endstop_adj.c)
46
-    );
47
-  #else
48
-    SERIAL_ECHOPGM("  M666");
49
-    #if ENABLED(X_DUAL_ENDSTOPS)
50
-      SERIAL_ECHOLNPAIR_P(SP_X_STR, LINEAR_UNIT(endstops.x2_endstop_adj));
51
-    #endif
52
-    #if ENABLED(Y_DUAL_ENDSTOPS)
53
-      SERIAL_ECHOLNPAIR_P(SP_Y_STR, LINEAR_UNIT(endstops.y2_endstop_adj));
54
-    #endif
55
-    #if ENABLED(Z_MULTI_ENDSTOPS)
56
-      #if NUM_Z_STEPPER_DRIVERS >= 3
57
-        SERIAL_ECHOPAIR(" S2 Z", LINEAR_UNIT(endstops.z3_endstop_adj));
58
-        if (!forReplay) SERIAL_ECHO_START();
59
-        SERIAL_ECHOPAIR("  M666 S3 Z", LINEAR_UNIT(endstops.z3_endstop_adj));
60
-        #if NUM_Z_STEPPER_DRIVERS >= 4
61
-          if (!forReplay) SERIAL_ECHO_START();
62
-          SERIAL_ECHOPAIR("  M666 S4 Z", LINEAR_UNIT(endstops.z4_endstop_adj));
63
-        #endif
64
-      #else
65
-        SERIAL_ECHOLNPAIR_P(SP_Z_STR, LINEAR_UNIT(endstops.z2_endstop_adj));
66
-      #endif
67
-    #endif
68
-  #endif
69
-}
70
-
71 39
 #if ENABLED(DELTA)
72 40
 
73 41
   /**
@@ -92,6 +60,15 @@ void M666_report(const bool forReplay=true) {
92 60
     if (!is_set) M666_report();
93 61
   }
94 62
 
63
+  void GcodeSuite::M666_report(const bool forReplay/*=true*/) {
64
+    report_heading_etc(forReplay, PSTR(STR_ENDSTOP_ADJUSTMENT));
65
+    SERIAL_ECHOLNPAIR_P(
66
+        PSTR("  M666 X"), LINEAR_UNIT(delta_endstop_adj.a)
67
+      , SP_Y_STR, LINEAR_UNIT(delta_endstop_adj.b)
68
+      , SP_Z_STR, LINEAR_UNIT(delta_endstop_adj.c)
69
+    );
70
+  }
71
+
95 72
 #else
96 73
 
97 74
   /**
@@ -105,6 +82,8 @@ void M666_report(const bool forReplay=true) {
105 82
    *       Set All: M666 Z<offset>
106 83
    */
107 84
   void GcodeSuite::M666() {
85
+    if (!parser.seen_any()) return M666_report();
86
+
108 87
     #if ENABLED(X_DUAL_ENDSTOPS)
109 88
       if (parser.seenval('X')) endstops.x2_endstop_adj = parser.value_linear_units();
110 89
     #endif
@@ -123,7 +102,30 @@ void M666_report(const bool forReplay=true) {
123 102
         #endif
124 103
       }
125 104
     #endif
126
-    if (!parser.seen("XYZ")) M666_report();
105
+  }
106
+
107
+  void GcodeSuite::M666_report(const bool forReplay/*=true*/) {
108
+    report_heading_etc(forReplay, PSTR(STR_ENDSTOP_ADJUSTMENT));
109
+    SERIAL_ECHOPGM("  M666");
110
+    #if ENABLED(X_DUAL_ENDSTOPS)
111
+      SERIAL_ECHOLNPAIR_P(SP_X_STR, LINEAR_UNIT(endstops.x2_endstop_adj));
112
+    #endif
113
+    #if ENABLED(Y_DUAL_ENDSTOPS)
114
+      SERIAL_ECHOLNPAIR_P(SP_Y_STR, LINEAR_UNIT(endstops.y2_endstop_adj));
115
+    #endif
116
+    #if ENABLED(Z_MULTI_ENDSTOPS)
117
+      #if NUM_Z_STEPPER_DRIVERS >= 3
118
+        SERIAL_ECHOPAIR(" S2 Z", LINEAR_UNIT(endstops.z3_endstop_adj));
119
+        report_echo_start(forReplay);
120
+        SERIAL_ECHOPAIR("  M666 S3 Z", LINEAR_UNIT(endstops.z3_endstop_adj));
121
+        #if NUM_Z_STEPPER_DRIVERS >= 4
122
+          report_echo_start(forReplay);
123
+          SERIAL_ECHOPAIR("  M666 S4 Z", LINEAR_UNIT(endstops.z4_endstop_adj));
124
+        #endif
125
+      #else
126
+        SERIAL_ECHOLNPAIR_P(SP_Z_STR, LINEAR_UNIT(endstops.z2_endstop_adj));
127
+      #endif
128
+    #endif
127 129
   }
128 130
 
129 131
 #endif // HAS_EXTRA_ENDSTOPS

+ 17
- 17
Marlin/src/gcode/calibrate/M852.cpp View File

@@ -36,10 +36,11 @@
36 36
  *  K[yz_factor] - New YZ skew factor
37 37
  */
38 38
 void GcodeSuite::M852() {
39
-  uint8_t ijk = 0, badval = 0, setval = 0;
39
+  if (!parser.seen("SIJK")) return M852_report();
40 40
 
41
-  if (parser.seen('I') || parser.seen('S')) {
42
-    ++ijk;
41
+  uint8_t badval = 0, setval = 0;
42
+
43
+  if (parser.seenval('I') || parser.seenval('S')) {
43 44
     const float value = parser.value_linear_units();
44 45
     if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) {
45 46
       if (planner.skew_factor.xy != value) {
@@ -53,8 +54,7 @@ void GcodeSuite::M852() {
53 54
 
54 55
   #if ENABLED(SKEW_CORRECTION_FOR_Z)
55 56
 
56
-    if (parser.seen('J')) {
57
-      ++ijk;
57
+    if (parser.seenval('J')) {
58 58
       const float value = parser.value_linear_units();
59 59
       if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) {
60 60
         if (planner.skew_factor.xz != value) {
@@ -66,8 +66,7 @@ void GcodeSuite::M852() {
66 66
         ++badval;
67 67
     }
68 68
 
69
-    if (parser.seen('K')) {
70
-      ++ijk;
69
+    if (parser.seenval('K')) {
71 70
       const float value = parser.value_linear_units();
72 71
       if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) {
73 72
         if (planner.skew_factor.yz != value) {
@@ -90,17 +89,18 @@ void GcodeSuite::M852() {
90 89
     sync_plan_position();
91 90
     report_current_position();
92 91
   }
92
+}
93 93
 
94
-  if (!ijk) {
95
-    SERIAL_ECHO_START();
96
-    SERIAL_ECHOPGM("Skew Factor");
97
-    SERIAL_ECHOPAIR_F(" XY: ", planner.skew_factor.xy, 6);
98
-    #if ENABLED(SKEW_CORRECTION_FOR_Z)
99
-      SERIAL_ECHOPAIR_F(" XZ: ", planner.skew_factor.xz, 6);
100
-      SERIAL_ECHOPAIR_F(" YZ: ", planner.skew_factor.yz, 6);
101
-    #endif
102
-    SERIAL_EOL();
103
-  }
94
+void GcodeSuite::M852_report(const bool forReplay/*=true*/) {
95
+  report_heading_etc(forReplay, PSTR(STR_SKEW_FACTOR));
96
+  SERIAL_ECHOPAIR_F("  M851 I", planner.skew_factor.xy, 6);
97
+  #if ENABLED(SKEW_CORRECTION_FOR_Z)
98
+    SERIAL_ECHOPAIR_F(" J", planner.skew_factor.xz, 6);
99
+    SERIAL_ECHOPAIR_F(" K", planner.skew_factor.yz, 6);
100
+    SERIAL_ECHOLNPGM(" ; XY, XZ, YZ");
101
+  #else
102
+    SERIAL_ECHOLNPGM(" ; XY");
103
+  #endif
104 104
 }
105 105
 
106 106
 #endif // SKEW_CORRECTION_GCODE

+ 136
- 6
Marlin/src/gcode/config/M200-M205.cpp View File

@@ -32,9 +32,14 @@
32 32
    *    T<extruder> - Optional extruder number. Current extruder if omitted.
33 33
    *    D<linear>   - Set filament diameter and enable. D0 disables volumetric.
34 34
    *    S<bool>     - Turn volumetric ON or OFF.
35
+   *
36
+   * With VOLUMETRIC_EXTRUDER_LIMIT:
37
+   *
35 38
    *    L<float>    - Volumetric extruder limit (in mm^3/sec). L0 disables the limit.
36 39
    */
37 40
   void GcodeSuite::M200() {
41
+    if (!parser.seen("DST" TERN_(VOLUMETRIC_EXTRUDER_LIMIT, "L")))
42
+      return M200_report();
38 43
 
39 44
     const int8_t target_extruder = get_target_extruder_from_command();
40 45
     if (target_extruder < 0) return;
@@ -69,6 +74,37 @@
69 74
     planner.calculate_volumetric_multipliers();
70 75
   }
71 76
 
77
+  void GcodeSuite::M200_report(const bool forReplay/*=true*/) {
78
+    if (!forReplay) {
79
+      report_heading(forReplay, PSTR(STR_FILAMENT_SETTINGS), false);
80
+      if (!parser.volumetric_enabled) SERIAL_ECHOPGM(" (Disabled):");
81
+      SERIAL_EOL();
82
+      report_echo_start(forReplay);
83
+    }
84
+
85
+    #if EXTRUDERS == 1
86
+    {
87
+      SERIAL_ECHOLNPAIR(
88
+        "  M200 S", parser.volumetric_enabled, " D", LINEAR_UNIT(planner.filament_size[0])
89
+        #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
90
+          , " L", LINEAR_UNIT(planner.volumetric_extruder_limit[0])
91
+        #endif
92
+      );
93
+    }
94
+    #else
95
+      SERIAL_ECHOLNPAIR("  M200 S", parser.volumetric_enabled);
96
+      LOOP_L_N(i, EXTRUDERS) {
97
+        report_echo_start(forReplay);
98
+        SERIAL_ECHOLNPAIR(
99
+          "  M200 T", i, " D", LINEAR_UNIT(planner.filament_size[i])
100
+          #if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
101
+            , " L", LINEAR_UNIT(planner.volumetric_extruder_limit[i])
102
+          #endif
103
+        );
104
+      }
105
+    #endif
106
+  }
107
+
72 108
 #endif // !NO_VOLUMETRICS
73 109
 
74 110
 /**
@@ -77,6 +113,8 @@
77 113
  *       With multiple extruders use T to specify which one.
78 114
  */
79 115
 void GcodeSuite::M201() {
116
+  if (!parser.seen("T" LOGICAL_AXES_STRING))
117
+    return M201_report();
80 118
 
81 119
   const int8_t target_extruder = get_target_extruder_from_command();
82 120
   if (target_extruder < 0) return;
@@ -94,12 +132,40 @@ void GcodeSuite::M201() {
94 132
   }
95 133
 }
96 134
 
135
+void GcodeSuite::M201_report(const bool forReplay/*=true*/) {
136
+  report_heading_etc(forReplay, PSTR(STR_MAX_ACCELERATION));
137
+  SERIAL_ECHOLNPAIR_P(
138
+    LIST_N(DOUBLE(LINEAR_AXES),
139
+      PSTR("  M201 X"), LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[X_AXIS]),
140
+      SP_Y_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Y_AXIS]),
141
+      SP_Z_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Z_AXIS]),
142
+      SP_I_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[I_AXIS]),
143
+      SP_J_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[J_AXIS]),
144
+      SP_K_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[K_AXIS])
145
+    )
146
+    #if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
147
+      , SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_acceleration_mm_per_s2[E_AXIS])
148
+    #endif
149
+  );
150
+  #if ENABLED(DISTINCT_E_FACTORS)
151
+    LOOP_L_N(i, E_STEPPERS) {
152
+      report_echo_start(forReplay);
153
+      SERIAL_ECHOLNPAIR_P(
154
+          PSTR("  M201 T"), i
155
+        , SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(i)])
156
+      );
157
+    }
158
+  #endif
159
+}
160
+
97 161
 /**
98 162
  * M203: Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in units/sec
99 163
  *
100 164
  *       With multiple extruders use T to specify which one.
101 165
  */
102 166
 void GcodeSuite::M203() {
167
+  if (!parser.seen("T" LOGICAL_AXES_STRING))
168
+    return M203_report();
103 169
 
104 170
   const int8_t target_extruder = get_target_extruder_from_command();
105 171
   if (target_extruder < 0) return;
@@ -111,6 +177,32 @@ void GcodeSuite::M203() {
111 177
     }
112 178
 }
113 179
 
180
+void GcodeSuite::M203_report(const bool forReplay/*=true*/) {
181
+  report_heading_etc(forReplay, PSTR(STR_MAX_FEEDRATES));
182
+  SERIAL_ECHOLNPAIR_P(
183
+    LIST_N(DOUBLE(LINEAR_AXES),
184
+      PSTR("  M203 X"), LINEAR_UNIT(planner.settings.max_feedrate_mm_s[X_AXIS]),
185
+      SP_Y_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Y_AXIS]),
186
+      SP_Z_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Z_AXIS]),
187
+      SP_I_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[I_AXIS]),
188
+      SP_J_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[J_AXIS]),
189
+      SP_K_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[K_AXIS])
190
+    )
191
+    #if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
192
+      , SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_feedrate_mm_s[E_AXIS])
193
+    #endif
194
+  );
195
+  #if ENABLED(DISTINCT_E_FACTORS)
196
+    LOOP_L_N(i, E_STEPPERS) {
197
+      SERIAL_ECHO_START();
198
+      SERIAL_ECHOLNPAIR_P(
199
+          PSTR("  M203 T"), i
200
+        , SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_feedrate_mm_s[E_AXIS_N(i)])
201
+      );
202
+    }
203
+  #endif
204
+}
205
+
114 206
 /**
115 207
  * M204: Set Accelerations in units/sec^2 (M204 P1200 R3000 T3000)
116 208
  *
@@ -119,11 +211,8 @@ void GcodeSuite::M203() {
119 211
  *    T = Travel (non printing) moves
120 212
  */
121 213
 void GcodeSuite::M204() {
122
-  if (!parser.seen("PRST")) {
123
-    SERIAL_ECHOPAIR("Acceleration: P", planner.settings.acceleration);
124
-    SERIAL_ECHOPAIR(" R", planner.settings.retract_acceleration);
125
-    SERIAL_ECHOLNPAIR_P(SP_T_STR, planner.settings.travel_acceleration);
126
-  }
214
+  if (!parser.seen("PRST"))
215
+    return M204_report();
127 216
   else {
128 217
     //planner.synchronize();
129 218
     // 'S' for legacy compatibility. Should NOT BE USED for new development
@@ -134,6 +223,15 @@ void GcodeSuite::M204() {
134 223
   }
135 224
 }
136 225
 
226
+void GcodeSuite::M204_report(const bool forReplay/*=true*/) {
227
+  report_heading_etc(forReplay, PSTR(STR_ACCELERATION_P_R_T));
228
+  SERIAL_ECHOLNPAIR_P(
229
+      PSTR("  M204 P"), LINEAR_UNIT(planner.settings.acceleration)
230
+    , PSTR(" R"), LINEAR_UNIT(planner.settings.retract_acceleration)
231
+    , SP_T_STR, LINEAR_UNIT(planner.settings.travel_acceleration)
232
+  );
233
+}
234
+
137 235
 /**
138 236
  * M205: Set Advanced Settings
139 237
  *
@@ -147,7 +245,8 @@ void GcodeSuite::M204() {
147 245
  *    J = Junction Deviation (mm) (If not using CLASSIC_JERK)
148 246
  */
149 247
 void GcodeSuite::M205() {
150
-  if (!parser.seen("BST" TERN_(HAS_JUNCTION_DEVIATION, "J") TERN_(HAS_CLASSIC_JERK, "XYZE"))) return;
248
+  if (!parser.seen("BST" TERN_(HAS_JUNCTION_DEVIATION, "J") TERN_(HAS_CLASSIC_JERK, "XYZE")))
249
+    return M205_report();
151 250
 
152 251
   //planner.synchronize();
153 252
   if (parser.seenval('B')) planner.settings.min_segment_time_us = parser.value_ulong();
@@ -184,3 +283,34 @@ void GcodeSuite::M205() {
184 283
     #endif
185 284
   #endif // HAS_CLASSIC_JERK
186 285
 }
286
+
287
+void GcodeSuite::M205_report(const bool forReplay/*=true*/) {
288
+  report_heading_etc(forReplay, PSTR(
289
+    "Advanced (B<min_segment_time_us> S<min_feedrate> T<min_travel_feedrate>"
290
+    TERN_(HAS_JUNCTION_DEVIATION, " J<junc_dev>")
291
+    TERN_(HAS_CLASSIC_JERK, " X<max_x_jerk> Y<max_y_jerk> Z<max_z_jerk>")
292
+    TERN_(HAS_CLASSIC_E_JERK, " E<max_e_jerk>")
293
+    ")"
294
+  ));
295
+  SERIAL_ECHOLNPAIR_P(
296
+      PSTR("  M205 B"), LINEAR_UNIT(planner.settings.min_segment_time_us)
297
+    , PSTR(" S"), LINEAR_UNIT(planner.settings.min_feedrate_mm_s)
298
+    , SP_T_STR, LINEAR_UNIT(planner.settings.min_travel_feedrate_mm_s)
299
+    #if HAS_JUNCTION_DEVIATION
300
+      , PSTR(" J"), LINEAR_UNIT(planner.junction_deviation_mm)
301
+    #endif
302
+    #if HAS_CLASSIC_JERK
303
+      , LIST_N(DOUBLE(LINEAR_AXES),
304
+        SP_X_STR, LINEAR_UNIT(planner.max_jerk.x),
305
+        SP_Y_STR, LINEAR_UNIT(planner.max_jerk.y),
306
+        SP_Z_STR, LINEAR_UNIT(planner.max_jerk.z),
307
+        SP_I_STR, LINEAR_UNIT(planner.max_jerk.i),
308
+        SP_J_STR, LINEAR_UNIT(planner.max_jerk.j),
309
+        SP_K_STR, LINEAR_UNIT(planner.max_jerk.k)
310
+      )
311
+      #if HAS_CLASSIC_E_JERK
312
+        , SP_E_STR, LINEAR_UNIT(planner.max_jerk.e)
313
+      #endif
314
+    #endif
315
+  );
316
+}

+ 35
- 38
Marlin/src/gcode/config/M217.cpp View File

@@ -33,44 +33,6 @@
33 33
 
34 34
 #include "../../MarlinCore.h" // for SP_X_STR, etc.
35 35
 
36
-void M217_report(const bool eeprom=false) {
37
-
38
-  #if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
39
-    SERIAL_ECHOPGM_P(eeprom ? PSTR("  M217") : PSTR("Toolchange:"));
40
-    SERIAL_ECHOPAIR(" S", LINEAR_UNIT(toolchange_settings.swap_length));
41
-    SERIAL_ECHOPAIR_P(SP_B_STR, LINEAR_UNIT(toolchange_settings.extra_resume),
42
-                      SP_E_STR, LINEAR_UNIT(toolchange_settings.extra_prime),
43
-                      SP_P_STR, LINEAR_UNIT(toolchange_settings.prime_speed));
44
-    SERIAL_ECHOPAIR(" R", LINEAR_UNIT(toolchange_settings.retract_speed),
45
-                    " U", LINEAR_UNIT(toolchange_settings.unretract_speed),
46
-                    " F", toolchange_settings.fan_speed,
47
-                    " G", toolchange_settings.fan_time);
48
-
49
-    #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
50
-      SERIAL_ECHOPAIR(" A", migration.automode);
51
-      SERIAL_ECHOPAIR(" L", LINEAR_UNIT(migration.last));
52
-    #endif
53
-
54
-    #if ENABLED(TOOLCHANGE_PARK)
55
-      SERIAL_ECHOPAIR(" W", LINEAR_UNIT(toolchange_settings.enable_park));
56
-      SERIAL_ECHOPAIR_P(SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x));
57
-      SERIAL_ECHOPAIR_P(SP_Y_STR, LINEAR_UNIT(toolchange_settings.change_point.y));
58
-    #endif
59
-
60
-    #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
61
-      SERIAL_ECHOPAIR(" V", LINEAR_UNIT(enable_first_prime));
62
-    #endif
63
-
64
-  #else
65
-
66
-    UNUSED(eeprom);
67
-
68
-  #endif
69
-
70
-  SERIAL_ECHOPAIR_P(SP_Z_STR, LINEAR_UNIT(toolchange_settings.z_raise));
71
-  SERIAL_EOL();
72
-}
73
-
74 36
 /**
75 37
  * M217 - Set SINGLENOZZLE toolchange parameters
76 38
  *
@@ -168,4 +130,39 @@ void GcodeSuite::M217() {
168 130
   M217_report();
169 131
 }
170 132
 
133
+void GcodeSuite::M217_report(const bool forReplay/*=true*/) {
134
+  report_heading_etc(forReplay, PSTR(STR_TOOL_CHANGING));
135
+
136
+  SERIAL_ECHOPGM("  M217");
137
+
138
+  #if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
139
+    SERIAL_ECHOPAIR(" S", LINEAR_UNIT(toolchange_settings.swap_length));
140
+    SERIAL_ECHOPAIR_P(SP_B_STR, LINEAR_UNIT(toolchange_settings.extra_resume),
141
+                      SP_E_STR, LINEAR_UNIT(toolchange_settings.extra_prime),
142
+                      SP_P_STR, LINEAR_UNIT(toolchange_settings.prime_speed));
143
+    SERIAL_ECHOPAIR(" R", LINEAR_UNIT(toolchange_settings.retract_speed),
144
+                    " U", LINEAR_UNIT(toolchange_settings.unretract_speed),
145
+                    " F", toolchange_settings.fan_speed,
146
+                    " G", toolchange_settings.fan_time);
147
+
148
+    #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
149
+      SERIAL_ECHOPAIR(" A", migration.automode);
150
+      SERIAL_ECHOPAIR(" L", LINEAR_UNIT(migration.last));
151
+    #endif
152
+
153
+    #if ENABLED(TOOLCHANGE_PARK)
154
+      SERIAL_ECHOPAIR(" W", LINEAR_UNIT(toolchange_settings.enable_park));
155
+      SERIAL_ECHOPAIR_P(SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x));
156
+      SERIAL_ECHOPAIR_P(SP_Y_STR, LINEAR_UNIT(toolchange_settings.change_point.y));
157
+    #endif
158
+
159
+    #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
160
+      SERIAL_ECHOPAIR(" V", LINEAR_UNIT(enable_first_prime));
161
+    #endif
162
+
163
+  #endif
164
+
165
+  SERIAL_ECHOLNPAIR_P(SP_Z_STR, LINEAR_UNIT(toolchange_settings.z_raise));
166
+}
167
+
171 168
 #endif // HAS_MULTI_EXTRUDER

+ 15
- 14
Marlin/src/gcode/config/M218.cpp View File

@@ -41,6 +41,8 @@
41 41
  */
42 42
 void GcodeSuite::M218() {
43 43
 
44
+  if (!parser.seen_any()) return M218_report();
45
+
44 46
   const int8_t target_extruder = get_target_extruder_from_command();
45 47
   if (target_extruder < 0) return;
46 48
 
@@ -48,24 +50,23 @@ void GcodeSuite::M218() {
48 50
   if (parser.seenval('Y')) hotend_offset[target_extruder].y = parser.value_linear_units();
49 51
   if (parser.seenval('Z')) hotend_offset[target_extruder].z = parser.value_linear_units();
50 52
 
51
-  if (!parser.seen("XYZ")) {
52
-    SERIAL_ECHO_START();
53
-    SERIAL_ECHOPGM(STR_HOTEND_OFFSET);
54
-    HOTEND_LOOP() {
55
-      SERIAL_CHAR(' ');
56
-      SERIAL_ECHO(hotend_offset[e].x);
57
-      SERIAL_CHAR(',');
58
-      SERIAL_ECHO(hotend_offset[e].y);
59
-      SERIAL_CHAR(',');
60
-      SERIAL_ECHO_F(hotend_offset[e].z, 3);
61
-    }
62
-    SERIAL_EOL();
63
-  }
64
-
65 53
   #if ENABLED(DELTA)
66 54
     if (target_extruder == active_extruder)
67 55
       do_blocking_move_to_xy(current_position, planner.settings.max_feedrate_mm_s[X_AXIS]);
68 56
   #endif
69 57
 }
70 58
 
59
+void GcodeSuite::M218_report(const bool forReplay/*=true*/) {
60
+  report_heading_etc(forReplay, PSTR(STR_HOTEND_OFFSETS));
61
+  LOOP_S_L_N(e, 1, HOTENDS) {
62
+    report_echo_start(forReplay);
63
+    SERIAL_ECHOPAIR_P(
64
+      PSTR("  M218 T"), e,
65
+      SP_X_STR, LINEAR_UNIT(hotend_offset[e].x),
66
+      SP_Y_STR, LINEAR_UNIT(hotend_offset[e].y)
67
+    );
68
+    SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, LINEAR_UNIT(hotend_offset[e].z), 3);
69
+  }
70
+}
71
+
71 72
 #endif // HAS_HOTEND_OFFSET

+ 23
- 14
Marlin/src/gcode/config/M281.cpp View File

@@ -34,6 +34,7 @@
34 34
  *  U<angle> - Stowed Angle
35 35
  */
36 36
 void GcodeSuite::M281() {
37
+  if (!parser.seen_any()) return M281_report();
37 38
 
38 39
   if (!parser.seenval('P')) return;
39 40
 
@@ -45,24 +46,32 @@ void GcodeSuite::M281() {
45 46
         return;
46 47
       }
47 48
     #endif
48
-    bool angle_change = false;
49
-    if (parser.seen('L')) {
50
-      servo_angles[servo_index][0] = parser.value_int();
51
-      angle_change = true;
52
-    }
53
-    if (parser.seen('U')) {
54
-      servo_angles[servo_index][1] = parser.value_int();
55
-      angle_change = true;
56
-    }
57
-    if (!angle_change) {
58
-      SERIAL_ECHO_MSG(" Servo ", servo_index,
59
-                      " L", servo_angles[servo_index][0],
60
-                      " U", servo_angles[servo_index][1]);
61
-    }
49
+    if (parser.seen('L')) servo_angles[servo_index][0] = parser.value_int();
50
+    if (parser.seen('U')) servo_angles[servo_index][1] = parser.value_int();
62 51
   }
63 52
   else
64 53
     SERIAL_ERROR_MSG("Servo ", servo_index, " out of range");
54
+}
65 55
 
56
+void GcodeSuite::M281_report(const bool forReplay/*=true*/) {
57
+  report_heading_etc(forReplay, PSTR(STR_SERVO_ANGLES));
58
+  LOOP_L_N(i, NUM_SERVOS) {
59
+    switch (i) {
60
+      default: break;
61
+      #if ENABLED(SWITCHING_EXTRUDER)
62
+        case SWITCHING_EXTRUDER_SERVO_NR:
63
+        #if EXTRUDERS > 3
64
+          case SWITCHING_EXTRUDER_E23_SERVO_NR:
65
+        #endif
66
+      #elif ENABLED(SWITCHING_NOZZLE)
67
+        case SWITCHING_NOZZLE_SERVO_NR:
68
+      #elif ENABLED(BLTOUCH) || (HAS_Z_SERVO_PROBE && defined(Z_SERVO_ANGLES))
69
+        case Z_PROBE_SERVO_NR:
70
+      #endif
71
+          report_echo_start(forReplay);
72
+          SERIAL_ECHOLNPAIR("  M281 P", i, " L", servo_angles[i][0], " U", servo_angles[i][1]);
73
+    }
74
+  }
66 75
 }
67 76
 
68 77
 #endif // EDITABLE_SERVO_ANGLES

+ 40
- 23
Marlin/src/gcode/config/M301.cpp View File

@@ -46,46 +46,63 @@
46 46
  *   F[float] Kf term
47 47
  */
48 48
 void GcodeSuite::M301() {
49
-
50 49
   // multi-extruder PID patch: M301 updates or prints a single extruder's PID values
51 50
   // default behavior (omitting E parameter) is to update for extruder 0 only
52
-  const uint8_t e = parser.byteval('E'); // extruder being updated
51
+  int8_t e = parser.byteval('E', -1); // extruder being updated
52
+
53
+  if (!parser.seen("PID" TERN_(PID_EXTRUSION_SCALING, "CL") TERN_(PID_FAN_SCALING, "F")))
54
+    return M301_report(true, e);
55
+
56
+  if (e == -1) e = 0;
53 57
 
54 58
   if (e < HOTENDS) { // catch bad input value
55
-    if (parser.seen('P')) PID_PARAM(Kp, e) = parser.value_float();
56
-    if (parser.seen('I')) PID_PARAM(Ki, e) = scalePID_i(parser.value_float());
57
-    if (parser.seen('D')) PID_PARAM(Kd, e) = scalePID_d(parser.value_float());
59
+
60
+    if (parser.seenval('P')) PID_PARAM(Kp, e) = parser.value_float();
61
+    if (parser.seenval('I')) PID_PARAM(Ki, e) = scalePID_i(parser.value_float());
62
+    if (parser.seenval('D')) PID_PARAM(Kd, e) = scalePID_d(parser.value_float());
63
+
58 64
     #if ENABLED(PID_EXTRUSION_SCALING)
59
-      if (parser.seen('C')) PID_PARAM(Kc, e) = parser.value_float();
65
+      if (parser.seenval('C')) PID_PARAM(Kc, e) = parser.value_float();
60 66
       if (parser.seenval('L')) thermalManager.lpq_len = parser.value_int();
61 67
       NOMORE(thermalManager.lpq_len, LPQ_MAX_LEN);
62 68
       NOLESS(thermalManager.lpq_len, 0);
63 69
     #endif
64 70
 
65 71
     #if ENABLED(PID_FAN_SCALING)
66
-      if (parser.seen('F')) PID_PARAM(Kf, e) = parser.value_float();
72
+      if (parser.seenval('F')) PID_PARAM(Kf, e) = parser.value_float();
67 73
     #endif
68 74
 
69 75
     thermalManager.updatePID();
70
-
71
-    SERIAL_ECHO_START();
72
-    #if ENABLED(PID_PARAMS_PER_HOTEND)
73
-      SERIAL_ECHOPAIR(" e:", e); // specify extruder in serial output
74
-    #endif
75
-    SERIAL_ECHOPAIR(" p:", PID_PARAM(Kp, e),
76
-                    " i:", unscalePID_i(PID_PARAM(Ki, e)),
77
-                    " d:", unscalePID_d(PID_PARAM(Kd, e)));
78
-    #if ENABLED(PID_EXTRUSION_SCALING)
79
-      SERIAL_ECHOPAIR(" c:", PID_PARAM(Kc, e));
80
-    #endif
81
-    #if ENABLED(PID_FAN_SCALING)
82
-      SERIAL_ECHOPAIR(" f:", PID_PARAM(Kf, e));
83
-    #endif
84
-
85
-    SERIAL_EOL();
86 76
   }
87 77
   else
88 78
     SERIAL_ERROR_MSG(STR_INVALID_EXTRUDER);
89 79
 }
90 80
 
81
+void GcodeSuite::M301_report(const bool forReplay/*=true*/, const int8_t eindex/*=-1*/) {
82
+  report_heading(forReplay, PSTR(STR_HOTEND_PID));
83
+  HOTEND_LOOP() {
84
+    if (e == eindex || eindex == -1) {
85
+      report_echo_start(forReplay);
86
+      SERIAL_ECHOPAIR_P(
87
+        #if ENABLED(PID_PARAMS_PER_HOTEND)
88
+          PSTR("  M301 E"), e, SP_P_STR
89
+        #else
90
+          PSTR("  M301 P")
91
+        #endif
92
+        ,                          PID_PARAM(Kp, e)
93
+        , PSTR(" I"), unscalePID_i(PID_PARAM(Ki, e))
94
+        , PSTR(" D"), unscalePID_d(PID_PARAM(Kd, e))
95
+      );
96
+      #if ENABLED(PID_EXTRUSION_SCALING)
97
+        SERIAL_ECHOPAIR_P(SP_C_STR, PID_PARAM(Kc, e));
98
+        if (e == 0) SERIAL_ECHOPAIR(" L", thermalManager.lpq_len);
99
+      #endif
100
+      #if ENABLED(PID_FAN_SCALING)
101
+        SERIAL_ECHOPAIR(" F", PID_PARAM(Kf, e));
102
+      #endif
103
+      SERIAL_EOL();
104
+    }
105
+  }
106
+}
107
+
91 108
 #endif // PIDTEMP

+ 9
- 5
Marlin/src/gcode/config/M304.cpp View File

@@ -35,15 +35,19 @@
35 35
  *  D<dval> - Set the D value
36 36
  */
37 37
 void GcodeSuite::M304() {
38
-
38
+  if (!parser.seen("PID")) return M304_report();
39 39
   if (parser.seen('P')) thermalManager.temp_bed.pid.Kp = parser.value_float();
40 40
   if (parser.seen('I')) thermalManager.temp_bed.pid.Ki = scalePID_i(parser.value_float());
41 41
   if (parser.seen('D')) thermalManager.temp_bed.pid.Kd = scalePID_d(parser.value_float());
42
+}
42 43
 
43
-  SERIAL_ECHO_MSG(" p:", thermalManager.temp_bed.pid.Kp,
44
-                  " i:", unscalePID_i(thermalManager.temp_bed.pid.Ki),
45
-                  " d:", unscalePID_d(thermalManager.temp_bed.pid.Kd));
46
-
44
+void GcodeSuite::M304_report(const bool forReplay/*=true*/) {
45
+  report_heading_etc(forReplay, PSTR(STR_BED_PID));
46
+  SERIAL_ECHO_MSG(
47
+      "  M304 P", thermalManager.temp_bed.pid.Kp
48
+    , " I", unscalePID_i(thermalManager.temp_bed.pid.Ki)
49
+    , " D", unscalePID_d(thermalManager.temp_bed.pid.Kd)
50
+  );
47 51
 }
48 52
 
49 53
 #endif // PIDTEMPBED

+ 2
- 2
Marlin/src/gcode/config/M305.cpp View File

@@ -70,10 +70,10 @@ void GcodeSuite::M305() {
70 70
   }                       // If not setting then report parameters
71 71
   else if (t_index < 0) { // ...all user thermistors
72 72
     LOOP_L_N(i, USER_THERMISTORS)
73
-      thermalManager.log_user_thermistor(i);
73
+      thermalManager.M305_report(i);
74 74
   }
75 75
   else                    // ...one user thermistor
76
-    thermalManager.log_user_thermistor(t_index);
76
+    thermalManager.M305_report(t_index);
77 77
 }
78 78
 
79 79
 #endif // HAS_USER_THERMISTORS

+ 9
- 4
Marlin/src/gcode/config/M309.cpp View File

@@ -35,14 +35,19 @@
35 35
  *  D<dval> - Set the D value
36 36
  */
37 37
 void GcodeSuite::M309() {
38
+  if (!parser.seen("PID")) return M309_report();
38 39
   if (parser.seen('P')) thermalManager.temp_chamber.pid.Kp = parser.value_float();
39 40
   if (parser.seen('I')) thermalManager.temp_chamber.pid.Ki = scalePID_i(parser.value_float());
40 41
   if (parser.seen('D')) thermalManager.temp_chamber.pid.Kd = scalePID_d(parser.value_float());
42
+}
41 43
 
42
-  SERIAL_ECHO_START();
43
-  SERIAL_ECHOLNPAIR(" p:", thermalManager.temp_chamber.pid.Kp,
44
-                    " i:", unscalePID_i(thermalManager.temp_chamber.pid.Ki),
45
-                    " d:", unscalePID_d(thermalManager.temp_chamber.pid.Kd));
44
+void GcodeSuite::M309_report(const bool forReplay/*=true*/) {
45
+  report_heading_etc(forReplay, PSTR(STR_CHAMBER_PID));
46
+  SERIAL_ECHOLNPAIR(
47
+      "  M309 P", thermalManager.temp_chamber.pid.Kp
48
+    , " I", unscalePID_i(thermalManager.temp_chamber.pid.Ki)
49
+    , " D", unscalePID_d(thermalManager.temp_chamber.pid.Kd)
50
+  );
46 51
 }
47 52
 
48 53
 #endif // PIDTEMPCHAMBER

+ 3
- 3
Marlin/src/gcode/config/M575.cpp View File

@@ -53,13 +53,13 @@ void GcodeSuite::M575() {
53 53
     case 115200: case 250000: case 500000: case 1000000: {
54 54
       const int8_t port = parser.intval('P', -99);
55 55
       const bool set1 = (port == -99 || port == 0);
56
-      if (set1) SERIAL_ECHO_MSG(" Serial ", AS_CHAR('0'), " baud rate set to ", baud);
56
+      if (set1) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(0), " baud rate set to ", baud);
57 57
       #if HAS_MULTI_SERIAL
58 58
         const bool set2 = (port == -99 || port == 1);
59
-        if (set2) SERIAL_ECHO_MSG(" Serial ", AS_CHAR('1'), " baud rate set to ", baud);
59
+        if (set2) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(1), " baud rate set to ", baud);
60 60
         #ifdef SERIAL_PORT_3
61 61
           const bool set3 = (port == -99 || port == 2);
62
-          if (set3) SERIAL_ECHO_MSG(" Serial ", AS_CHAR('2'), " baud rate set to ", baud);
62
+          if (set3) SERIAL_ECHO_MSG(" Serial ", AS_DIGIT(2), " baud rate set to ", baud);
63 63
         #endif
64 64
       #endif
65 65
 

+ 37
- 36
Marlin/src/gcode/config/M92.cpp View File

@@ -23,33 +23,6 @@
23 23
 #include "../gcode.h"
24 24
 #include "../../module/planner.h"
25 25
 
26
-void report_M92(const bool echo=true, const int8_t e=-1) {
27
-  if (echo) SERIAL_ECHO_START(); else SERIAL_CHAR(' ');
28
-  SERIAL_ECHOPAIR_P(LIST_N(DOUBLE(LINEAR_AXES),
29
-    PSTR(" M92 X"), LINEAR_UNIT(planner.settings.axis_steps_per_mm[X_AXIS]),
30
-    SP_Y_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Y_AXIS]),
31
-    SP_Z_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Z_AXIS]),
32
-    SP_I_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[I_AXIS]),
33
-    SP_J_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[J_AXIS]),
34
-    SP_K_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[K_AXIS]))
35
-  );
36
-  #if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
37
-    SERIAL_ECHOPAIR_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS]));
38
-  #endif
39
-  SERIAL_EOL();
40
-
41
-  #if ENABLED(DISTINCT_E_FACTORS)
42
-    LOOP_L_N(i, E_STEPPERS) {
43
-      if (e >= 0 && i != e) continue;
44
-      if (echo) SERIAL_ECHO_START(); else SERIAL_CHAR(' ');
45
-      SERIAL_ECHOLNPAIR_P(PSTR(" M92 T"), i,
46
-                        SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS_N(i)]));
47
-    }
48
-  #endif
49
-
50
-  UNUSED(e);
51
-}
52
-
53 26
 /**
54 27
  * M92: Set axis steps-per-unit for one or more axes, X, Y, Z, and E.
55 28
  *      (Follows the same syntax as G92)
@@ -58,10 +31,11 @@ void report_M92(const bool echo=true, const int8_t e=-1) {
58 31
  *
59 32
  *      If no argument is given print the current values.
60 33
  *
61
- *    With MAGIC_NUMBERS_GCODE:
62
- *      Use 'H' and/or 'L' to get ideal layer-height information.
63
- *      'H' specifies micro-steps to use. We guess if it's not supplied.
64
- *      'L' specifies a desired layer height. Nearest good heights are shown.
34
+ * With MAGIC_NUMBERS_GCODE:
35
+ *
36
+ *   Use 'H' and/or 'L' to get ideal layer-height information.
37
+ *   H<microsteps> - Specify micro-steps to use. Best guess if not supplied.
38
+ *   L<linear>     - Desired layer height in current units. Nearest good heights are shown.
65 39
  */
66 40
 void GcodeSuite::M92() {
67 41
 
@@ -69,10 +43,8 @@ void GcodeSuite::M92() {
69 43
   if (target_extruder < 0) return;
70 44
 
71 45
   // No arguments? Show M92 report.
72
-  if (!parser.seen(
73
-    LOGICAL_AXIS_GANG("E", "X", "Y", "Z", AXIS4_STR, AXIS5_STR, AXIS6_STR)
74
-    TERN_(MAGIC_NUMBERS_GCODE, "HL")
75
-  )) return report_M92(true, target_extruder);
46
+  if (!parser.seen(LOGICAL_AXES_STRING TERN_(MAGIC_NUMBERS_GCODE, "HL")))
47
+    return M92_report(true, target_extruder);
76 48
 
77 49
   LOOP_LOGICAL_AXES(i) {
78 50
     if (parser.seenval(axis_codes[i])) {
@@ -100,7 +72,7 @@ void GcodeSuite::M92() {
100 72
     #ifndef Z_MICROSTEPS
101 73
       #define Z_MICROSTEPS 16
102 74
     #endif
103
-    const float wanted = parser.floatval('L');
75
+    const float wanted = parser.linearval('L');
104 76
     if (parser.seen('H') || wanted) {
105 77
       const uint16_t argH = parser.ushortval('H'),
106 78
                      micro_steps = argH ?: Z_MICROSTEPS;
@@ -117,3 +89,32 @@ void GcodeSuite::M92() {
117 89
     }
118 90
   #endif
119 91
 }
92
+
93
+void GcodeSuite::M92_report(const bool forReplay/*=true*/, const int8_t e/*=-1*/) {
94
+  report_heading_etc(forReplay, PSTR(STR_STEPS_PER_UNIT));
95
+  SERIAL_ECHOPAIR_P(LIST_N(DOUBLE(LINEAR_AXES),
96
+    PSTR("  M92 X"), LINEAR_UNIT(planner.settings.axis_steps_per_mm[X_AXIS]),
97
+    SP_Y_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Y_AXIS]),
98
+    SP_Z_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Z_AXIS]),
99
+    SP_I_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[I_AXIS]),
100
+    SP_J_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[J_AXIS]),
101
+    SP_K_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[K_AXIS]))
102
+  );
103
+  #if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
104
+    SERIAL_ECHOPAIR_P(SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS]));
105
+  #endif
106
+  SERIAL_EOL();
107
+
108
+  #if ENABLED(DISTINCT_E_FACTORS)
109
+    LOOP_L_N(i, E_STEPPERS) {
110
+      if (e >= 0 && i != e) continue;
111
+      report_echo_start(forReplay);
112
+      SERIAL_ECHOLNPAIR_P(
113
+        PSTR("  M92 T"), i,
114
+        SP_E_STR, VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS_N(i)])
115
+      );
116
+    }
117
+  #else
118
+    UNUSED(e);
119
+  #endif
120
+}

+ 2
- 2
Marlin/src/gcode/control/M17_M18_M84.cpp View File

@@ -33,7 +33,7 @@
33 33
  * M17: Enable stepper motors
34 34
  */
35 35
 void GcodeSuite::M17() {
36
-  if (parser.seen(LOGICAL_AXIS_GANG("E", "X", "Y", "Z", AXIS4_STR, AXIS5_STR, AXIS6_STR))) {
36
+  if (parser.seen_axis()) {
37 37
     LOGICAL_AXIS_CODE(
38 38
       if (TERN0(HAS_E_STEPPER_ENABLE, parser.seen_test('E'))) enable_e_steppers(),
39 39
       if (parser.seen_test('X'))        ENABLE_AXIS_X(),
@@ -59,7 +59,7 @@ void GcodeSuite::M18_M84() {
59 59
     stepper_inactive_time = parser.value_millis_from_seconds();
60 60
   }
61 61
   else {
62
-    if (parser.seen(LOGICAL_AXIS_GANG("E", "X", "Y", "Z", AXIS4_STR, AXIS5_STR, AXIS6_STR))) {
62
+    if (parser.seen_axis()) {
63 63
       planner.synchronize();
64 64
       LOGICAL_AXIS_CODE(
65 65
         if (TERN0(HAS_E_STEPPER_ENABLE, parser.seen_test('E'))) disable_e_steppers(),

+ 13
- 5
Marlin/src/gcode/control/M211.cpp View File

@@ -33,14 +33,22 @@
33 33
  * Usage: M211 S1 to enable, M211 S0 to disable, M211 alone for report
34 34
  */
35 35
 void GcodeSuite::M211() {
36
+  if (parser.seen('S'))
37
+    soft_endstop._enabled = parser.value_bool();
38
+  else
39
+    M211_report();
40
+}
41
+
42
+void GcodeSuite::M211_report(const bool forReplay/*=true*/) {
43
+  report_heading_etc(forReplay, PSTR(STR_SOFT_ENDSTOPS));
44
+  SERIAL_ECHOPAIR("  M211 S", AS_DIGIT(soft_endstop._enabled), " ; ");
45
+  serialprintln_onoff(soft_endstop._enabled);
46
+
47
+  report_echo_start(forReplay);
36 48
   const xyz_pos_t l_soft_min = soft_endstop.min.asLogical(),
37 49
                   l_soft_max = soft_endstop.max.asLogical();
38
-  SERIAL_ECHO_START();
39
-  SERIAL_ECHOPGM(STR_SOFT_ENDSTOPS);
40
-  if (parser.seen('S')) soft_endstop._enabled = parser.value_bool();
41
-  serialprint_onoff(soft_endstop._enabled);
42 50
   print_pos(l_soft_min, PSTR(STR_SOFT_MIN), PSTR(" "));
43 51
   print_pos(l_soft_max, PSTR(STR_SOFT_MAX));
44 52
 }
45 53
 
46
-#endif
54
+#endif // HAS_SOFTWARE_ENDSTOPS

+ 13
- 0
Marlin/src/gcode/feature/advance/M900.cpp View File

@@ -144,4 +144,17 @@ void GcodeSuite::M900() {
144 144
 
145 145
 }
146 146
 
147
+void GcodeSuite::M900_report(const bool forReplay/*=true*/) {
148
+  report_heading(forReplay, PSTR(STR_LINEAR_ADVANCE));
149
+  #if EXTRUDERS < 2
150
+    report_echo_start(forReplay);
151
+    SERIAL_ECHOLNPAIR("  M900 K", planner.extruder_advance_K[0]);
152
+  #else
153
+    LOOP_L_N(i, EXTRUDERS) {
154
+      report_echo_start(forReplay);
155
+      SERIAL_ECHOLNPAIR("  M900 T", i, " K", planner.extruder_advance_K[i]);
156
+    }
157
+  #endif
158
+}
159
+
147 160
 #endif // LIN_ADVANCE

+ 12
- 12
Marlin/src/gcode/feature/controllerfan/M710.cpp View File

@@ -27,18 +27,6 @@
27 27
 #include "../../gcode.h"
28 28
 #include "../../../feature/controllerfan.h"
29 29
 
30
-void M710_report(const bool forReplay=true) {
31
-  if (!forReplay) { SERIAL_ECHOLNPGM("; Controller Fan"); SERIAL_ECHO_START(); }
32
-  SERIAL_ECHOLNPAIR("  M710"
33
-    " S", int(controllerFan.settings.active_speed),
34
-    " I", int(controllerFan.settings.idle_speed),
35
-    " A", int(controllerFan.settings.auto_mode),
36
-    " D", controllerFan.settings.duration,
37
-    " ; (", (int(controllerFan.settings.active_speed) * 100) / 255, "%"
38
-    " ", (int(controllerFan.settings.idle_speed) * 100) / 255, "%)"
39
-  );
40
-}
41
-
42 30
 /**
43 31
  * M710: Set controller fan settings
44 32
  *
@@ -78,4 +66,16 @@ void GcodeSuite::M710() {
78 66
     M710_report();
79 67
 }
80 68
 
69
+void GcodeSuite::M710_report(const bool forReplay/*=true*/) {
70
+  report_heading_etc(forReplay, PSTR(STR_CONTROLLER_FAN));
71
+  SERIAL_ECHOLNPAIR("  M710"
72
+    " S", int(controllerFan.settings.active_speed),
73
+    " I", int(controllerFan.settings.idle_speed),
74
+    " A", int(controllerFan.settings.auto_mode),
75
+    " D", controllerFan.settings.duration,
76
+    " ; (", (int(controllerFan.settings.active_speed) * 100) / 255, "%"
77
+    " ", (int(controllerFan.settings.idle_speed) * 100) / 255, "%)"
78
+  );
79
+}
80
+
81 81
 #endif // CONTROLLER_FAN_EDITABLE

+ 40
- 2
Marlin/src/gcode/feature/digipot/M907-M910.cpp View File

@@ -22,7 +22,7 @@
22 22
 
23 23
 #include "../../../inc/MarlinConfig.h"
24 24
 
25
-#if ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_PWM, HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC)
25
+#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM || HAS_MOTOR_CURRENT_I2C || HAS_MOTOR_CURRENT_DAC
26 26
 
27 27
 #include "../../gcode.h"
28 28
 
@@ -44,12 +44,27 @@
44 44
 void GcodeSuite::M907() {
45 45
   #if HAS_MOTOR_CURRENT_SPI
46 46
 
47
+    if (!parser.seen("BS" LOGICAL_AXES_STRING))
48
+      return M907_report();
49
+
47 50
     LOOP_LOGICAL_AXES(i) if (parser.seenval(axis_codes[i])) stepper.set_digipot_current(i, parser.value_int());
48 51
     if (parser.seenval('B')) stepper.set_digipot_current(4, parser.value_int());
49 52
     if (parser.seenval('S')) LOOP_LE_N(i, 4) stepper.set_digipot_current(i, parser.value_int());
50 53
 
51 54
   #elif HAS_MOTOR_CURRENT_PWM
52 55
 
56
+    if (!parser.seen(
57
+      #if ANY_PIN(MOTOR_CURRENT_PWM_X, MOTOR_CURRENT_PWM_Y, MOTOR_CURRENT_PWM_XY)
58
+        "XY"
59
+      #endif
60
+      #if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
61
+        "Z"
62
+      #endif
63
+      #if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
64
+        "E"
65
+      #endif
66
+    )) return M907_report();
67
+
53 68
     #if ANY_PIN(MOTOR_CURRENT_PWM_X, MOTOR_CURRENT_PWM_Y, MOTOR_CURRENT_PWM_XY)
54 69
       if (parser.seenval('X') || parser.seenval('Y')) stepper.set_digipot_current(0, parser.value_int());
55 70
     #endif
@@ -82,7 +97,30 @@ void GcodeSuite::M907() {
82 97
   #endif
83 98
 }
84 99
 
85
-#if EITHER(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_DAC)
100
+#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
101
+
102
+  void GcodeSuite::M907_report(const bool forReplay/*=true*/) {
103
+    report_heading_etc(forReplay, PSTR(STR_STEPPER_MOTOR_CURRENTS));
104
+    #if HAS_MOTOR_CURRENT_PWM
105
+      SERIAL_ECHOLNPAIR_P(                                    // PWM-based has 3 values:
106
+          PSTR("  M907 X"), stepper.motor_current_setting[0]  // X and Y
107
+        , SP_Z_STR,         stepper.motor_current_setting[1]  // Z
108
+        , SP_E_STR,         stepper.motor_current_setting[2]  // E
109
+      );
110
+    #elif HAS_MOTOR_CURRENT_SPI
111
+      SERIAL_ECHOPGM("  M907");                               // SPI-based has 5 values:
112
+      LOOP_LOGICAL_AXES(q) {                                  // X Y Z (I J K) E (map to X Y Z (I J K) E0 by default)
113
+        SERIAL_CHAR(' ', axis_codes[q]);
114
+        SERIAL_ECHO(stepper.motor_current_setting[q]);
115
+      }
116
+      SERIAL_CHAR(' ', 'B');                                  // B (maps to E1 by default)
117
+      SERIAL_ECHOLN(stepper.motor_current_setting[4]);
118
+    #endif
119
+  }
120
+
121
+#endif // HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
122
+
123
+#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_DAC
86 124
 
87 125
   /**
88 126
    * M908: Control digital trimpot directly (M908 P<pin> S<current>)

+ 25
- 0
Marlin/src/gcode/feature/fwretract/M207-M209.cpp View File

@@ -29,14 +29,34 @@
29 29
 
30 30
 /**
31 31
  * M207: Set firmware retraction values
32
+ *
33
+ *   S[+units]    retract_length
34
+ *   W[+units]    swap_retract_length (multi-extruder)
35
+ *   F[units/min] retract_feedrate_mm_s
36
+ *   Z[units]     retract_zraise
32 37
  */
33 38
 void GcodeSuite::M207() { fwretract.M207(); }
34 39
 
40
+void GcodeSuite::M207_report(const bool forReplay/*=true*/) {
41
+  report_heading_etc(forReplay, PSTR(STR_RETRACT_S_F_Z));
42
+  fwretract.M207_report();
43
+}
44
+
35 45
 /**
36 46
  * M208: Set firmware un-retraction values
47
+ *
48
+ *   S[+units]    retract_recover_extra (in addition to M207 S*)
49
+ *   W[+units]    swap_retract_recover_extra (multi-extruder)
50
+ *   F[units/min] retract_recover_feedrate_mm_s
51
+ *   R[units/min] swap_retract_recover_feedrate_mm_s
37 52
  */
38 53
 void GcodeSuite::M208() { fwretract.M208(); }
39 54
 
55
+void GcodeSuite::M208_report(const bool forReplay/*=true*/) {
56
+  report_heading_etc(forReplay, PSTR(STR_RECOVER_S_F));
57
+  fwretract.M208_report();
58
+}
59
+
40 60
 #if ENABLED(FWRETRACT_AUTORETRACT)
41 61
 
42 62
   /**
@@ -47,6 +67,11 @@ void GcodeSuite::M208() { fwretract.M208(); }
47 67
    */
48 68
   void GcodeSuite::M209() { fwretract.M209(); }
49 69
 
70
+  void GcodeSuite::M209_report(const bool forReplay/*=true*/) {
71
+    report_heading_etc(forReplay, PSTR(STR_AUTO_RETRACT_S));
72
+    fwretract.M209_report();
73
+  }
74
+
50 75
 #endif
51 76
 
52 77
 #endif // FWRETRACT

+ 21
- 15
Marlin/src/gcode/feature/network/M552-M554.cpp View File

@@ -64,17 +64,7 @@ void ip_report(const uint16_t cmd, PGM_P const post, const IPAddress &ipo) {
64 64
     if (i < 3) SERIAL_CHAR('.');
65 65
   }
66 66
   SERIAL_ECHOPGM(" ; ");
67
-  SERIAL_ECHOPGM_P(post);
68
-  SERIAL_EOL();
69
-}
70
-void M552_report() {
71
-  ip_report(552, PSTR("ip address"), Ethernet.linkStatus() == LinkON ? Ethernet.localIP() : ethernet.ip);
72
-}
73
-void M553_report() {
74
-  ip_report(553, PSTR("subnet mask"), Ethernet.linkStatus() == LinkON ? Ethernet.subnetMask() : ethernet.subnet);
75
-}
76
-void M554_report() {
77
-  ip_report(554, PSTR("gateway"), Ethernet.linkStatus() == LinkON ? Ethernet.gatewayIP() : ethernet.gateway);
67
+  SERIAL_ECHOLNPGM_P(post);
78 68
 }
79 69
 
80 70
 /**
@@ -107,20 +97,36 @@ void GcodeSuite::M552() {
107 97
   if (nopar || seenP) M552_report();
108 98
 }
109 99
 
100
+void GcodeSuite::M552_report() {
101
+  ip_report(552, PSTR("ip address"), Ethernet.linkStatus() == LinkON ? Ethernet.localIP() : ethernet.ip);
102
+}
103
+
110 104
 /**
111 105
  * M553 Pnnn - Set netmask
112 106
  */
113 107
 void GcodeSuite::M553() {
114
-  if (parser.seenval('P')) ethernet.subnet.fromString(parser.value_string());
115
-  M553_report();
108
+  if (parser.seenval('P'))
109
+    ethernet.subnet.fromString(parser.value_string());
110
+  else
111
+    M553_report();
112
+}
113
+
114
+void GcodeSuite::M553_report() {
115
+  ip_report(553, PSTR("subnet mask"), Ethernet.linkStatus() == LinkON ? Ethernet.subnetMask() : ethernet.subnet);
116 116
 }
117 117
 
118 118
 /**
119 119
  * M554 Pnnn - Set Gateway
120 120
  */
121 121
 void GcodeSuite::M554() {
122
-  if (parser.seenval('P')) ethernet.gateway.fromString(parser.value_string());
123
-  M554_report();
122
+  if (parser.seenval('P'))
123
+    ethernet.gateway.fromString(parser.value_string());
124
+  else
125
+    M554_report();
126
+}
127
+
128
+void GcodeSuite::M554_report() {
129
+  ip_report(554, PSTR("gateway"), Ethernet.linkStatus() == LinkON ? Ethernet.gatewayIP() : ethernet.gateway);
124 130
 }
125 131
 
126 132
 #endif // HAS_ETHERNET

+ 18
- 0
Marlin/src/gcode/feature/pause/M603.cpp View File

@@ -42,6 +42,8 @@
42 42
  */
43 43
 void GcodeSuite::M603() {
44 44
 
45
+  if (!parser.seen("TUL")) return M603_report();
46
+
45 47
   const int8_t target_extruder = get_target_extruder_from_command();
46 48
   if (target_extruder < 0) return;
47 49
 
@@ -62,4 +64,20 @@ void GcodeSuite::M603() {
62 64
   }
63 65
 }
64 66
 
67
+void GcodeSuite::M603_report(const bool forReplay/*=true*/) {
68
+  report_heading(forReplay, PSTR(STR_FILAMENT_LOAD_UNLOAD));
69
+
70
+  #if EXTRUDERS == 1
71
+    report_echo_start(forReplay);
72
+    SERIAL_ECHOPAIR("  M603 L", LINEAR_UNIT(fc_settings[0].load_length), " U", LINEAR_UNIT(fc_settings[0].unload_length), " ;");
73
+    say_units();
74
+  #else
75
+    LOOP_L_N(e, EXTRUDERS) {
76
+      report_echo_start(forReplay);
77
+      SERIAL_ECHOPAIR("  M603 T", e, " L", LINEAR_UNIT(fc_settings[e].load_length), " U", LINEAR_UNIT(fc_settings[e].unload_length), " ;");
78
+      say_units();
79
+    }
80
+  #endif
81
+}
82
+
65 83
 #endif // ADVANCED_PAUSE_FEATURE

+ 8
- 5
Marlin/src/gcode/feature/powerloss/M413.cpp View File

@@ -40,11 +40,8 @@ void GcodeSuite::M413() {
40 40
 
41 41
   if (parser.seen('S'))
42 42
     recovery.enable(parser.value_bool());
43
-  else {
44
-    SERIAL_ECHO_START();
45
-    SERIAL_ECHOPGM("Power-loss recovery ");
46
-    serialprintln_onoff(recovery.enabled);
47
-  }
43
+  else
44
+    M413_report();
48 45
 
49 46
   #if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
50 47
     if (parser.seen("RL")) recovery.load();
@@ -59,4 +56,10 @@ void GcodeSuite::M413() {
59 56
   #endif
60 57
 }
61 58
 
59
+void GcodeSuite::M413_report(const bool forReplay/*=true*/) {
60
+  report_heading_etc(forReplay, PSTR(STR_POWER_LOSS_RECOVERY));
61
+  SERIAL_ECHOPAIR("  M413 S", AS_DIGIT(recovery.enabled), " ; ");
62
+  serialprintln_onoff(recovery.enabled);
63
+}
64
+
62 65
 #endif // POWER_LOSS_RECOVERY

+ 12
- 0
Marlin/src/gcode/feature/runout/M412.cpp View File

@@ -66,4 +66,16 @@ void GcodeSuite::M412() {
66 66
   }
67 67
 }
68 68
 
69
+void GcodeSuite::M412_report(const bool forReplay/*=true*/) {
70
+  report_heading_etc(forReplay, PSTR(STR_FILAMENT_RUNOUT_SENSOR));
71
+  SERIAL_ECHOLNPAIR(
72
+    "  M412 S", runout.enabled
73
+    #if HAS_FILAMENT_RUNOUT_DISTANCE
74
+      , " D", LINEAR_UNIT(runout.runout_distance())
75
+    #endif
76
+    , " ; Sensor "
77
+  );
78
+  serialprintln_onoff(runout.enabled);
79
+}
80
+
69 81
 #endif // HAS_FILAMENT_SENSOR

+ 62
- 0
Marlin/src/gcode/feature/trinamic/M569.cpp View File

@@ -138,4 +138,66 @@ void GcodeSuite::M569() {
138 138
     say_stealth_status();
139 139
 }
140 140
 
141
+void GcodeSuite::M569_report(const bool forReplay/*=true*/) {
142
+  report_heading(forReplay, PSTR(STR_DRIVER_STEPPING_MODE));
143
+
144
+  auto say_M569 = [](const bool forReplay, const char * const etc=nullptr, const bool eol=false) {
145
+    if (!forReplay) SERIAL_ECHO_START();
146
+    SERIAL_ECHOPGM("  M569 S1");
147
+    if (etc) {
148
+      SERIAL_CHAR(' ');
149
+      SERIAL_ECHOPGM_P(etc);
150
+    }
151
+    if (eol) SERIAL_EOL();
152
+  };
153
+
154
+  const bool chop_x = TERN0(X_HAS_STEALTHCHOP, stepperX.get_stored_stealthChop()),
155
+             chop_y = TERN0(Y_HAS_STEALTHCHOP, stepperY.get_stored_stealthChop()),
156
+             chop_z = TERN0(Z_HAS_STEALTHCHOP, stepperZ.get_stored_stealthChop()),
157
+             chop_i = TERN0(I_HAS_STEALTHCHOP, stepperI.get_stored_stealthChop()),
158
+             chop_j = TERN0(J_HAS_STEALTHCHOP, stepperJ.get_stored_stealthChop()),
159
+             chop_k = TERN0(K_HAS_STEALTHCHOP, stepperK.get_stored_stealthChop());
160
+
161
+  if (chop_x || chop_y || chop_z || chop_i || chop_j || chop_k) {
162
+    say_M569(forReplay);
163
+    LINEAR_AXIS_CODE(
164
+      if (chop_x) SERIAL_ECHOPGM_P(SP_X_STR),
165
+      if (chop_y) SERIAL_ECHOPGM_P(SP_Y_STR),
166
+      if (chop_z) SERIAL_ECHOPGM_P(SP_Z_STR),
167
+      if (chop_i) SERIAL_ECHOPGM_P(SP_I_STR),
168
+      if (chop_j) SERIAL_ECHOPGM_P(SP_J_STR),
169
+      if (chop_k) SERIAL_ECHOPGM_P(SP_K_STR)
170
+    );
171
+    SERIAL_EOL();
172
+  }
173
+
174
+  const bool chop_x2 = TERN0(X2_HAS_STEALTHCHOP, stepperX2.get_stored_stealthChop()),
175
+             chop_y2 = TERN0(Y2_HAS_STEALTHCHOP, stepperY2.get_stored_stealthChop()),
176
+             chop_z2 = TERN0(Z2_HAS_STEALTHCHOP, stepperZ2.get_stored_stealthChop());
177
+
178
+  if (chop_x2 || chop_y2 || chop_z2) {
179
+    say_M569(forReplay, PSTR("I1"));
180
+    if (chop_x2) SERIAL_ECHOPGM_P(SP_X_STR);
181
+    if (chop_y2) SERIAL_ECHOPGM_P(SP_Y_STR);
182
+    if (chop_z2) SERIAL_ECHOPGM_P(SP_Z_STR);
183
+    SERIAL_EOL();
184
+  }
185
+
186
+  if (TERN0(Z3_HAS_STEALTHCHOP, stepperZ3.get_stored_stealthChop())) { say_M569(forReplay, PSTR("I2 Z"), true); }
187
+  if (TERN0(Z4_HAS_STEALTHCHOP, stepperZ4.get_stored_stealthChop())) { say_M569(forReplay, PSTR("I3 Z"), true); }
188
+
189
+  if (TERN0( I_HAS_STEALTHCHOP, stepperI.get_stored_stealthChop()))  { say_M569(forReplay, SP_I_STR, true); }
190
+  if (TERN0( J_HAS_STEALTHCHOP, stepperJ.get_stored_stealthChop()))  { say_M569(forReplay, SP_J_STR, true); }
191
+  if (TERN0( K_HAS_STEALTHCHOP, stepperK.get_stored_stealthChop()))  { say_M569(forReplay, SP_K_STR, true); }
192
+
193
+  if (TERN0(E0_HAS_STEALTHCHOP, stepperE0.get_stored_stealthChop())) { say_M569(forReplay, PSTR("T0 E"), true); }
194
+  if (TERN0(E1_HAS_STEALTHCHOP, stepperE1.get_stored_stealthChop())) { say_M569(forReplay, PSTR("T1 E"), true); }
195
+  if (TERN0(E2_HAS_STEALTHCHOP, stepperE2.get_stored_stealthChop())) { say_M569(forReplay, PSTR("T2 E"), true); }
196
+  if (TERN0(E3_HAS_STEALTHCHOP, stepperE3.get_stored_stealthChop())) { say_M569(forReplay, PSTR("T3 E"), true); }
197
+  if (TERN0(E4_HAS_STEALTHCHOP, stepperE4.get_stored_stealthChop())) { say_M569(forReplay, PSTR("T4 E"), true); }
198
+  if (TERN0(E5_HAS_STEALTHCHOP, stepperE5.get_stored_stealthChop())) { say_M569(forReplay, PSTR("T5 E"), true); }
199
+  if (TERN0(E6_HAS_STEALTHCHOP, stepperE6.get_stored_stealthChop())) { say_M569(forReplay, PSTR("T6 E"), true); }
200
+  if (TERN0(E7_HAS_STEALTHCHOP, stepperE7.get_stored_stealthChop())) { say_M569(forReplay, PSTR("T7 E"), true); }
201
+}
202
+
141 203
 #endif // HAS_STEALTHCHOP

+ 95
- 0
Marlin/src/gcode/feature/trinamic/M906.cpp View File

@@ -198,4 +198,99 @@ void GcodeSuite::M906() {
198 198
   }
199 199
 }
200 200
 
201
+void GcodeSuite::M906_report(const bool forReplay/*=true*/) {
202
+  report_heading(forReplay, PSTR(STR_STEPPER_DRIVER_CURRENT));
203
+
204
+  auto say_M906 = [](const bool forReplay) {
205
+    report_echo_start(forReplay);
206
+    SERIAL_ECHOPGM("  M906");
207
+  };
208
+
209
+  #if AXIS_IS_TMC(X) || AXIS_IS_TMC(Y) || AXIS_IS_TMC(Z)
210
+    say_M906(forReplay);
211
+    #if AXIS_IS_TMC(X)
212
+      SERIAL_ECHOPAIR_P(SP_X_STR, stepperX.getMilliamps());
213
+    #endif
214
+    #if AXIS_IS_TMC(Y)
215
+      SERIAL_ECHOPAIR_P(SP_Y_STR, stepperY.getMilliamps());
216
+    #endif
217
+    #if AXIS_IS_TMC(Z)
218
+      SERIAL_ECHOPAIR_P(SP_Z_STR, stepperZ.getMilliamps());
219
+    #endif
220
+    SERIAL_EOL();
221
+  #endif
222
+
223
+  #if AXIS_IS_TMC(X2) || AXIS_IS_TMC(Y2) || AXIS_IS_TMC(Z2)
224
+    say_M906(forReplay);
225
+    SERIAL_ECHOPGM(" I1");
226
+    #if AXIS_IS_TMC(X2)
227
+      SERIAL_ECHOPAIR_P(SP_X_STR, stepperX2.getMilliamps());
228
+    #endif
229
+    #if AXIS_IS_TMC(Y2)
230
+      SERIAL_ECHOPAIR_P(SP_Y_STR, stepperY2.getMilliamps());
231
+    #endif
232
+    #if AXIS_IS_TMC(Z2)
233
+      SERIAL_ECHOPAIR_P(SP_Z_STR, stepperZ2.getMilliamps());
234
+    #endif
235
+    SERIAL_EOL();
236
+  #endif
237
+
238
+  #if AXIS_IS_TMC(Z3)
239
+    say_M906(forReplay);
240
+    SERIAL_ECHOLNPAIR(" I2 Z", stepperZ3.getMilliamps());
241
+  #endif
242
+
243
+  #if AXIS_IS_TMC(Z4)
244
+    say_M906(forReplay);
245
+    SERIAL_ECHOLNPAIR(" I3 Z", stepperZ4.getMilliamps());
246
+  #endif
247
+
248
+  #if AXIS_IS_TMC(I)
249
+    say_M906(forReplay);
250
+    SERIAL_ECHOLNPAIR_P(SP_I_STR, stepperI.getMilliamps());
251
+  #endif
252
+  #if AXIS_IS_TMC(J)
253
+    say_M906(forReplay);
254
+    SERIAL_ECHOLNPAIR_P(SP_J_STR, stepperJ.getMilliamps());
255
+  #endif
256
+  #if AXIS_IS_TMC(K)
257
+    say_M906(forReplay);
258
+    SERIAL_ECHOLNPAIR_P(SP_K_STR, stepperK.getMilliamps());
259
+  #endif
260
+
261
+  #if AXIS_IS_TMC(E0)
262
+    say_M906(forReplay);
263
+    SERIAL_ECHOLNPAIR(" T0 E", stepperE0.getMilliamps());
264
+  #endif
265
+  #if AXIS_IS_TMC(E1)
266
+    say_M906(forReplay);
267
+    SERIAL_ECHOLNPAIR(" T1 E", stepperE1.getMilliamps());
268
+  #endif
269
+  #if AXIS_IS_TMC(E2)
270
+    say_M906(forReplay);
271
+    SERIAL_ECHOLNPAIR(" T2 E", stepperE2.getMilliamps());
272
+  #endif
273
+  #if AXIS_IS_TMC(E3)
274
+    say_M906(forReplay);
275
+    SERIAL_ECHOLNPAIR(" T3 E", stepperE3.getMilliamps());
276
+  #endif
277
+  #if AXIS_IS_TMC(E4)
278
+    say_M906(forReplay);
279
+    SERIAL_ECHOLNPAIR(" T4 E", stepperE4.getMilliamps());
280
+  #endif
281
+  #if AXIS_IS_TMC(E5)
282
+    say_M906(forReplay);
283
+    SERIAL_ECHOLNPAIR(" T5 E", stepperE5.getMilliamps());
284
+  #endif
285
+  #if AXIS_IS_TMC(E6)
286
+    say_M906(forReplay);
287
+    SERIAL_ECHOLNPAIR(" T6 E", stepperE6.getMilliamps());
288
+  #endif
289
+  #if AXIS_IS_TMC(E7)
290
+    say_M906(forReplay);
291
+    SERIAL_ECHOLNPAIR(" T7 E", stepperE7.getMilliamps());
292
+  #endif
293
+  SERIAL_EOL();
294
+}
295
+
201 296
 #endif // HAS_TRINAMIC_CONFIG

+ 160
- 0
Marlin/src/gcode/feature/trinamic/M911-M914.cpp View File

@@ -227,6 +227,7 @@
227 227
  * M913: Set HYBRID_THRESHOLD speed.
228 228
  */
229 229
 #if ENABLED(HYBRID_THRESHOLD)
230
+
230 231
   void GcodeSuite::M913() {
231 232
     #define TMC_SAY_PWMTHRS(A,Q) tmc_print_pwmthrs(stepper##Q)
232 233
     #define TMC_SET_PWMTHRS(A,Q) stepper##Q.set_pwm_thrs(value)
@@ -308,12 +309,109 @@
308 309
       TERN_(E7_HAS_STEALTHCHOP, TMC_SAY_PWMTHRS_E(7));
309 310
     }
310 311
   }
312
+
313
+  void GcodeSuite::M913_report(const bool forReplay/*=true*/) {
314
+    report_heading(forReplay, PSTR(STR_HYBRID_THRESHOLD));
315
+
316
+    auto say_M913 = [](const bool forReplay) {
317
+      report_echo_start(forReplay);
318
+      SERIAL_ECHOPGM("  M913");
319
+    };
320
+
321
+    #if X_HAS_STEALTHCHOP || Y_HAS_STEALTHCHOP || Z_HAS_STEALTHCHOP
322
+      say_M913(forReplay);
323
+      #if X_HAS_STEALTHCHOP
324
+        SERIAL_ECHOPAIR_P(SP_X_STR, stepperX.get_pwm_thrs());
325
+      #endif
326
+      #if Y_HAS_STEALTHCHOP
327
+        SERIAL_ECHOPAIR_P(SP_Y_STR, stepperY.get_pwm_thrs());
328
+      #endif
329
+      #if Z_HAS_STEALTHCHOP
330
+        SERIAL_ECHOPAIR_P(SP_Z_STR, stepperZ.get_pwm_thrs());
331
+      #endif
332
+      SERIAL_EOL();
333
+    #endif
334
+
335
+    #if X2_HAS_STEALTHCHOP || Y2_HAS_STEALTHCHOP || Z2_HAS_STEALTHCHOP
336
+      say_M913(forReplay);
337
+      SERIAL_ECHOPGM(" I1");
338
+      #if X2_HAS_STEALTHCHOP
339
+        SERIAL_ECHOPAIR_P(SP_X_STR, stepperX2.get_pwm_thrs());
340
+      #endif
341
+      #if Y2_HAS_STEALTHCHOP
342
+        SERIAL_ECHOPAIR_P(SP_Y_STR, stepperY2.get_pwm_thrs());
343
+      #endif
344
+      #if Z2_HAS_STEALTHCHOP
345
+        SERIAL_ECHOPAIR_P(SP_Z_STR, stepperZ2.get_pwm_thrs());
346
+      #endif
347
+      SERIAL_EOL();
348
+    #endif
349
+
350
+    #if Z3_HAS_STEALTHCHOP
351
+      say_M913(forReplay);
352
+      SERIAL_ECHOLNPAIR(" I2 Z", stepperZ3.get_pwm_thrs());
353
+    #endif
354
+
355
+    #if Z4_HAS_STEALTHCHOP
356
+      say_M913(forReplay);
357
+      SERIAL_ECHOLNPAIR(" I3 Z", stepperZ4.get_pwm_thrs());
358
+    #endif
359
+
360
+    #if I_HAS_STEALTHCHOP
361
+      say_M913(forReplay);
362
+      SERIAL_ECHOLNPAIR_P(SP_I_STR, stepperI.get_pwm_thrs());
363
+    #endif
364
+    #if J_HAS_STEALTHCHOP
365
+      say_M913(forReplay);
366
+      SERIAL_ECHOLNPAIR_P(SP_J_STR, stepperJ.get_pwm_thrs());
367
+    #endif
368
+    #if K_HAS_STEALTHCHOP
369
+      say_M913(forReplay);
370
+      SERIAL_ECHOLNPAIR_P(SP_K_STR, stepperK.get_pwm_thrs());
371
+    #endif
372
+
373
+    #if E0_HAS_STEALTHCHOP
374
+      say_M913(forReplay);
375
+      SERIAL_ECHOLNPAIR(" T0 E", stepperE0.get_pwm_thrs());
376
+    #endif
377
+    #if E1_HAS_STEALTHCHOP
378
+      say_M913(forReplay);
379
+      SERIAL_ECHOLNPAIR(" T1 E", stepperE1.get_pwm_thrs());
380
+    #endif
381
+    #if E2_HAS_STEALTHCHOP
382
+      say_M913(forReplay);
383
+      SERIAL_ECHOLNPAIR(" T2 E", stepperE2.get_pwm_thrs());
384
+    #endif
385
+    #if E3_HAS_STEALTHCHOP
386
+      say_M913(forReplay);
387
+      SERIAL_ECHOLNPAIR(" T3 E", stepperE3.get_pwm_thrs());
388
+    #endif
389
+    #if E4_HAS_STEALTHCHOP
390
+      say_M913(forReplay);
391
+      SERIAL_ECHOLNPAIR(" T4 E", stepperE4.get_pwm_thrs());
392
+    #endif
393
+    #if E5_HAS_STEALTHCHOP
394
+      say_M913(forReplay);
395
+      SERIAL_ECHOLNPAIR(" T5 E", stepperE5.get_pwm_thrs());
396
+    #endif
397
+    #if E6_HAS_STEALTHCHOP
398
+      say_M913(forReplay);
399
+      SERIAL_ECHOLNPAIR(" T6 E", stepperE6.get_pwm_thrs());
400
+    #endif
401
+    #if E7_HAS_STEALTHCHOP
402
+      say_M913(forReplay);
403
+      SERIAL_ECHOLNPAIR(" T7 E", stepperE7.get_pwm_thrs());
404
+    #endif
405
+    SERIAL_EOL();
406
+  }
407
+
311 408
 #endif // HYBRID_THRESHOLD
312 409
 
313 410
 /**
314 411
  * M914: Set StallGuard sensitivity.
315 412
  */
316 413
 #if USE_SENSORLESS
414
+
317 415
   void GcodeSuite::M914() {
318 416
 
319 417
     bool report = true;
@@ -412,6 +510,68 @@
412 510
       #endif
413 511
     }
414 512
   }
513
+
514
+  void GcodeSuite::M914_report(const bool forReplay/*=true*/) {
515
+    report_heading(forReplay, PSTR(STR_STALLGUARD_THRESHOLD));
516
+
517
+    auto say_M914 = [](const bool forReplay) {
518
+      report_echo_start(forReplay);
519
+      SERIAL_ECHOPGM("  M914");
520
+    };
521
+
522
+    #if X_SENSORLESS || Y_SENSORLESS || Z_SENSORLESS
523
+      say_M914(forReplay);
524
+      #if X_SENSORLESS
525
+        SERIAL_ECHOPAIR_P(SP_X_STR, stepperX.homing_threshold());
526
+      #endif
527
+      #if Y_SENSORLESS
528
+        SERIAL_ECHOPAIR_P(SP_Y_STR, stepperY.homing_threshold());
529
+      #endif
530
+      #if Z_SENSORLESS
531
+        SERIAL_ECHOPAIR_P(SP_Z_STR, stepperZ.homing_threshold());
532
+      #endif
533
+      SERIAL_EOL();
534
+    #endif
535
+
536
+    #if X2_SENSORLESS || Y2_SENSORLESS || Z2_SENSORLESS
537
+      say_M914(forReplay);
538
+      SERIAL_ECHOPGM(" I1");
539
+      #if X2_SENSORLESS
540
+        SERIAL_ECHOPAIR_P(SP_X_STR, stepperX2.homing_threshold());
541
+      #endif
542
+      #if Y2_SENSORLESS
543
+        SERIAL_ECHOPAIR_P(SP_Y_STR, stepperY2.homing_threshold());
544
+      #endif
545
+      #if Z2_SENSORLESS
546
+        SERIAL_ECHOPAIR_P(SP_Z_STR, stepperZ2.homing_threshold());
547
+      #endif
548
+      SERIAL_EOL();
549
+    #endif
550
+
551
+    #if Z3_SENSORLESS
552
+      say_M914(forReplay);
553
+      SERIAL_ECHOLNPAIR(" I2 Z", stepperZ3.homing_threshold());
554
+    #endif
555
+
556
+    #if Z4_SENSORLESS
557
+      say_M914(forReplay);
558
+      SERIAL_ECHOLNPAIR(" I3 Z", stepperZ4.homing_threshold());
559
+    #endif
560
+
561
+    #if I_SENSORLESS
562
+      say_M914(forReplay);
563
+      SERIAL_ECHOLNPAIR_P(SP_I_STR, stepperI.homing_threshold());
564
+    #endif
565
+    #if J_SENSORLESS
566
+      say_M914(forReplay);
567
+      SERIAL_ECHOLNPAIR_P(SP_J_STR, stepperJ.homing_threshold());
568
+    #endif
569
+    #if K_SENSORLESS
570
+      say_M914(forReplay);
571
+      SERIAL_ECHOLNPAIR_P(SP_K_STR, stepperK.homing_threshold());
572
+    #endif
573
+  }
574
+
415 575
 #endif // USE_SENSORLESS
416 576
 
417 577
 #endif // HAS_TRINAMIC_CONFIG

+ 19
- 1
Marlin/src/gcode/gcode.cpp View File

@@ -102,6 +102,24 @@ uint8_t GcodeSuite::axis_relative = 0 LOGICAL_AXIS_GANG(
102 102
   xyz_pos_t GcodeSuite::coordinate_system[MAX_COORDINATE_SYSTEMS];
103 103
 #endif
104 104
 
105
+void GcodeSuite::report_echo_start(const bool forReplay) { if (!forReplay) SERIAL_ECHO_START(); }
106
+void GcodeSuite::report_heading(const bool forReplay, PGM_P const pstr, const bool eol/*=true*/) {
107
+  if (forReplay) return;
108
+  if (pstr) {
109
+    SERIAL_ECHO_START();
110
+    SERIAL_ECHOPGM("; ");
111
+    SERIAL_ECHOPGM_P(pstr);
112
+  }
113
+  if (eol) { SERIAL_CHAR(':'); SERIAL_EOL(); }
114
+}
115
+
116
+void GcodeSuite::say_units() {
117
+  SERIAL_ECHOLNPGM_P(
118
+    TERN_(INCH_MODE_SUPPORT, parser.linear_unit_factor != 1.0 ? PSTR(" (in)") :)
119
+    PSTR(" (mm)")
120
+  );
121
+}
122
+
105 123
 /**
106 124
  * Get the target extruder from the T parameter or the active_extruder
107 125
  * Return -1 if the T parameter is out of range
@@ -180,7 +198,7 @@ void GcodeSuite::get_destination_from_command() {
180 198
       recovery.save();
181 199
   #endif
182 200
 
183
-  if (parser.linearval('F') > 0)
201
+  if (parser.floatval('F') > 0)
184 202
     feedrate_mm_s = parser.value_feedrate();
185 203
 
186 204
   #if ENABLED(PRINTCOUNTER)

+ 69
- 12
Marlin/src/gcode/gcode.h View File

@@ -383,6 +383,14 @@ public:
383 383
     return ELAPSED(ms, previous_move_ms + stepper_inactive_time);
384 384
   }
385 385
 
386
+  static void report_echo_start(const bool forReplay);
387
+  static void report_heading(const bool forReplay, PGM_P const pstr, const bool eol=true);
388
+  static inline void report_heading_etc(const bool forReplay, PGM_P const pstr, const bool eol=true) {
389
+    report_heading(forReplay, pstr, eol);
390
+    report_echo_start(forReplay);
391
+  }
392
+  static void say_units();
393
+
386 394
   static int8_t get_target_extruder_from_command();
387 395
   static int8_t get_target_e_stepper_from_command();
388 396
   static void get_destination_from_command();
@@ -438,6 +446,8 @@ public:
438 446
 
439 447
 private:
440 448
 
449
+  friend class MarlinSettings;
450
+
441 451
   #if ENABLED(MARLIN_DEV_MODE)
442 452
     static void D(const int16_t dcode);
443 453
   #endif
@@ -518,6 +528,7 @@ private:
518 528
 
519 529
   #if ENABLED(Z_STEPPER_AUTO_ALIGN)
520 530
     static void M422();
531
+    static void M422_report(const bool forReplay=true);
521 532
   #endif
522 533
 
523 534
   #if ENABLED(ASSISTED_TRAMMING)
@@ -662,6 +673,7 @@ private:
662 673
 
663 674
   static void M85();
664 675
   static void M92();
676
+  static void M92_report(const bool forReplay=true, const int8_t e=-1);
665 677
 
666 678
   #if ENABLED(M100_FREE_MEMORY_WATCHER)
667 679
     static void M100();
@@ -741,10 +753,12 @@ private:
741 753
 
742 754
   #if PREHEAT_COUNT
743 755
     static void M145();
756
+    static void M145_report(const bool forReplay=true);
744 757
   #endif
745 758
 
746 759
   #if ENABLED(TEMPERATURE_UNITS_SUPPORT)
747 760
     static void M149();
761
+    static void M149_report(const bool forReplay=true);
748 762
   #endif
749 763
 
750 764
   #if HAS_COLOR_LEDS
@@ -770,37 +784,51 @@ private:
770 784
     #endif
771 785
   #endif
772 786
 
773
-  static void M200();
787
+  #if DISABLED(NO_VOLUMETRICS)
788
+    static void M200();
789
+    static void M200_report(const bool forReplay=true);
790
+  #endif
774 791
   static void M201();
792
+  static void M201_report(const bool forReplay=true);
775 793
 
776 794
   #if 0
777 795
     static void M202(); // Not used for Sprinter/grbl gen6
778 796
   #endif
779 797
 
780 798
   static void M203();
799
+  static void M203_report(const bool forReplay=true);
781 800
   static void M204();
801
+  static void M204_report(const bool forReplay=true);
782 802
   static void M205();
803
+  static void M205_report(const bool forReplay=true);
783 804
 
784 805
   #if HAS_M206_COMMAND
785 806
     static void M206();
807
+    static void M206_report(const bool forReplay=true);
786 808
   #endif
787 809
 
788 810
   #if ENABLED(FWRETRACT)
789 811
     static void M207();
812
+    static void M207_report(const bool forReplay=true);
790 813
     static void M208();
814
+    static void M208_report(const bool forReplay=true);
791 815
     #if ENABLED(FWRETRACT_AUTORETRACT)
792 816
       static void M209();
817
+      static void M209_report(const bool forReplay=true);
793 818
     #endif
794 819
   #endif
795 820
 
796 821
   static void M211();
822
+  static void M211_report(const bool forReplay=true);
797 823
 
798 824
   #if HAS_MULTI_EXTRUDER
799 825
     static void M217();
826
+    static void M217_report(const bool forReplay=true);
800 827
   #endif
801 828
 
802 829
   #if HAS_HOTEND_OFFSET
803 830
     static void M218();
831
+    static void M218_report(const bool forReplay=true);
804 832
   #endif
805 833
 
806 834
   static void M220();
@@ -819,10 +847,12 @@ private:
819 847
 
820 848
   #if HAS_LCD_CONTRAST
821 849
     static void M250();
850
+    static void M250_report(const bool forReplay=true);
822 851
   #endif
823 852
 
824 853
   #if HAS_LCD_BRIGHTNESS
825 854
     static void M256();
855
+    static void M256_report(const bool forReplay=true);
826 856
   #endif
827 857
 
828 858
   #if ENABLED(EXPERIMENTAL_I2CBUS)
@@ -834,6 +864,7 @@ private:
834 864
     static void M280();
835 865
     #if ENABLED(EDITABLE_SERVO_ANGLES)
836 866
       static void M281();
867
+      static void M281_report(const bool forReplay=true);
837 868
     #endif
838 869
   #endif
839 870
 
@@ -847,6 +878,7 @@ private:
847 878
 
848 879
   #if ENABLED(PIDTEMP)
849 880
     static void M301();
881
+    static void M301_report(const bool forReplay=true, const int8_t eindex=-1);
850 882
   #endif
851 883
 
852 884
   #if ENABLED(PREVENT_COLD_EXTRUSION)
@@ -859,6 +891,7 @@ private:
859 891
 
860 892
   #if ENABLED(PIDTEMPBED)
861 893
     static void M304();
894
+    static void M304_report(const bool forReplay=true);
862 895
   #endif
863 896
 
864 897
   #if HAS_USER_THERMISTORS
@@ -867,6 +900,7 @@ private:
867 900
 
868 901
   #if ENABLED(PIDTEMPCHAMBER)
869 902
     static void M309();
903
+    static void M309_report(const bool forReplay=true);
870 904
   #endif
871 905
 
872 906
   #if HAS_MICROSTEPS
@@ -915,19 +949,23 @@ private:
915 949
 
916 950
   #if HAS_FILAMENT_SENSOR
917 951
     static void M412();
952
+    static void M412_report(const bool forReplay=true);
918 953
   #endif
919 954
 
920 955
   #if HAS_MULTI_LANGUAGE
921 956
     static void M414();
957
+    static void M414_report(const bool forReplay=true);
922 958
   #endif
923 959
 
924 960
   #if HAS_LEVELING
925 961
     static void M420();
962
+    static void M420_report(const bool forReplay=true);
926 963
     static void M421();
927 964
   #endif
928 965
 
929 966
   #if ENABLED(BACKLASH_GCODE)
930 967
     static void M425();
968
+    static void M425_report(const bool forReplay=true);
931 969
   #endif
932 970
 
933 971
   #if HAS_M206_COMMAND
@@ -972,8 +1010,16 @@ private:
972 1010
 
973 1011
   #if HAS_ETHERNET
974 1012
     static void M552();
1013
+    static void M552_report();
975 1014
     static void M553();
1015
+    static void M553_report();
976 1016
     static void M554();
1017
+    static void M554_report();
1018
+  #endif
1019
+
1020
+  #if HAS_STEALTHCHOP
1021
+    static void M569();
1022
+    static void M569_report(const bool forReplay=true);
977 1023
   #endif
978 1024
 
979 1025
   #if ENABLED(BAUD_RATE_GCODE)
@@ -983,6 +1029,7 @@ private:
983 1029
   #if ENABLED(ADVANCED_PAUSE_FEATURE)
984 1030
     static void M600();
985 1031
     static void M603();
1032
+    static void M603_report(const bool forReplay=true);
986 1033
   #endif
987 1034
 
988 1035
   #if HAS_DUPLICATION_MODE
@@ -991,10 +1038,12 @@ private:
991 1038
 
992 1039
   #if IS_KINEMATIC
993 1040
     static void M665();
1041
+    static void M665_report(const bool forReplay=true);
994 1042
   #endif
995 1043
 
996
-  #if ENABLED(DELTA) || HAS_EXTRA_ENDSTOPS
1044
+  #if EITHER(DELTA, HAS_EXTRA_ENDSTOPS)
997 1045
     static void M666();
1046
+    static void M666_report(const bool forReplay=true);
998 1047
   #endif
999 1048
 
1000 1049
   #if ENABLED(DUET_SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD)
@@ -1016,10 +1065,12 @@ private:
1016 1065
 
1017 1066
   #if HAS_BED_PROBE
1018 1067
     static void M851();
1068
+    static void M851_report(const bool forReplay=true);
1019 1069
   #endif
1020 1070
 
1021 1071
   #if ENABLED(SKEW_CORRECTION_GCODE)
1022 1072
     static void M852();
1073
+    static void M852_report(const bool forReplay=true);
1023 1074
   #endif
1024 1075
 
1025 1076
   #if ENABLED(I2C_POSITION_ENCODERS)
@@ -1042,23 +1093,24 @@ private:
1042 1093
 
1043 1094
   #if ENABLED(LIN_ADVANCE)
1044 1095
     static void M900();
1096
+    static void M900_report(const bool forReplay=true);
1045 1097
   #endif
1046 1098
 
1047 1099
   #if HAS_TRINAMIC_CONFIG
1048 1100
     static void M122();
1049 1101
     static void M906();
1050
-    #if HAS_STEALTHCHOP
1051
-      static void M569();
1052
-    #endif
1102
+    static void M906_report(const bool forReplay=true);
1053 1103
     #if ENABLED(MONITOR_DRIVER_STATUS)
1054 1104
       static void M911();
1055 1105
       static void M912();
1056 1106
     #endif
1057 1107
     #if ENABLED(HYBRID_THRESHOLD)
1058 1108
       static void M913();
1109
+      static void M913_report(const bool forReplay=true);
1059 1110
     #endif
1060 1111
     #if ENABLED(USE_SENSORLESS)
1061 1112
       static void M914();
1113
+      static void M914_report(const bool forReplay=true);
1062 1114
     #endif
1063 1115
   #endif
1064 1116
 
@@ -1070,16 +1122,19 @@ private:
1070 1122
     static void M918();
1071 1123
   #endif
1072 1124
 
1073
-  #if ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_PWM, HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC)
1125
+  #if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM || HAS_MOTOR_CURRENT_I2C || HAS_MOTOR_CURRENT_DAC
1074 1126
     static void M907();
1075
-    #if EITHER(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_DAC)
1076
-      static void M908();
1077
-      #if HAS_MOTOR_CURRENT_DAC
1078
-        static void M909();
1079
-        static void M910();
1080
-      #endif
1127
+    #if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
1128
+      static void M907_report(const bool forReplay=true);
1081 1129
     #endif
1082 1130
   #endif
1131
+  #if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_DAC
1132
+    static void M908();
1133
+  #endif
1134
+  #if HAS_MOTOR_CURRENT_DAC
1135
+    static void M909();
1136
+    static void M910();
1137
+  #endif
1083 1138
 
1084 1139
   #if ENABLED(SDSUPPORT)
1085 1140
     static void M928();
@@ -1106,6 +1161,7 @@ private:
1106 1161
 
1107 1162
   #if ENABLED(POWER_LOSS_RECOVERY)
1108 1163
     static void M413();
1164
+    static void M413_report(const bool forReplay=true);
1109 1165
     static void M1000();
1110 1166
   #endif
1111 1167
 
@@ -1127,6 +1183,7 @@ private:
1127 1183
 
1128 1184
   #if ENABLED(CONTROLLER_FAN_EDITABLE)
1129 1185
     static void M710();
1186
+    static void M710_report(const bool forReplay=true);
1130 1187
   #endif
1131 1188
 
1132 1189
   static void T(const int8_t tool_index);

+ 21
- 17
Marlin/src/gcode/geometry/M206_M428.cpp View File

@@ -30,19 +30,6 @@
30 30
 #include "../../libs/buzzer.h"
31 31
 #include "../../MarlinCore.h"
32 32
 
33
-void M206_report() {
34
-  SERIAL_ECHOLNPAIR_P(
35
-    LIST_N(DOUBLE(LINEAR_AXES),
36
-      PSTR("M206 X"), home_offset.x,
37
-      SP_Y_STR, home_offset.y,
38
-      SP_Z_STR, home_offset.z,
39
-      SP_I_STR, home_offset.i,
40
-      SP_J_STR, home_offset.j,
41
-      SP_K_STR, home_offset.k,
42
-    )
43
-  );
44
-}
45
-
46 33
 /**
47 34
  * M206: Set Additional Homing Offset (X Y Z). SCARA aliases T=X, P=Y
48 35
  *
@@ -51,6 +38,8 @@ void M206_report() {
51 38
  * ***              In the 2.0 release, it will simply be disabled by default.
52 39
  */
53 40
 void GcodeSuite::M206() {
41
+  if (!parser.seen_any()) return M206_report();
42
+
54 43
   LOOP_LINEAR_AXES(i)
55 44
     if (parser.seen(AXIS_CHAR(i)))
56 45
       set_home_offset((AxisEnum)i, parser.value_linear_units());
@@ -60,10 +49,25 @@ void GcodeSuite::M206() {
60 49
     if (parser.seen('P')) set_home_offset(B_AXIS, parser.value_float()); // Psi
61 50
   #endif
62 51
 
63
-  if (!parser.seen(LINEAR_AXIS_GANG("X", "Y", "Z", "I", "J", "K")))
64
-    M206_report();
65
-  else
66
-    report_current_position();
52
+  report_current_position();
53
+}
54
+
55
+void GcodeSuite::M206_report(const bool forReplay/*=true*/) {
56
+  report_heading_etc(forReplay, PSTR(STR_HOME_OFFSET));
57
+  SERIAL_ECHOLNPAIR_P(
58
+    #if IS_CARTESIAN
59
+      LIST_N(DOUBLE(LINEAR_AXES),
60
+        PSTR("  M206 X"), LINEAR_UNIT(home_offset.x),
61
+        SP_Y_STR, LINEAR_UNIT(home_offset.y),
62
+        SP_Z_STR, LINEAR_UNIT(home_offset.z),
63
+        SP_I_STR, LINEAR_UNIT(home_offset.i),
64
+        SP_J_STR, LINEAR_UNIT(home_offset.j),
65
+        SP_K_STR, LINEAR_UNIT(home_offset.k)
66
+      )
67
+    #else
68
+      PSTR("  M206 Z"), LINEAR_UNIT(home_offset.z)
69
+    #endif
70
+  );
67 71
 }
68 72
 
69 73
 /**

+ 19
- 0
Marlin/src/gcode/lcd/M145.cpp View File

@@ -60,4 +60,23 @@ void GcodeSuite::M145() {
60 60
   }
61 61
 }
62 62
 
63
+void GcodeSuite::M145_report(const bool forReplay/*=true*/) {
64
+  report_heading(forReplay, PSTR(STR_MATERIAL_HEATUP));
65
+  LOOP_L_N(i, PREHEAT_COUNT) {
66
+    report_echo_start(forReplay);
67
+    SERIAL_ECHOLNPAIR_P(
68
+      PSTR("  M145 S"), i
69
+      #if HAS_HOTEND
70
+        , PSTR(" H"), parser.to_temp_units(ui.material_preset[i].hotend_temp)
71
+      #endif
72
+      #if HAS_HEATED_BED
73
+        , SP_B_STR, parser.to_temp_units(ui.material_preset[i].bed_temp)
74
+      #endif
75
+      #if HAS_FAN
76
+        , PSTR(" F"), ui.material_preset[i].fan_speed
77
+      #endif
78
+    );
79
+  }
80
+}
81
+
63 82
 #endif // PREHEAT_COUNT

+ 9
- 3
Marlin/src/gcode/lcd/M250.cpp View File

@@ -19,7 +19,6 @@
19 19
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20 20
  *
21 21
  */
22
-
23 22
 #include "../../inc/MarlinConfig.h"
24 23
 
25 24
 #if HAS_LCD_CONTRAST
@@ -31,8 +30,15 @@
31 30
  * M250: Read and optionally set the LCD contrast
32 31
  */
33 32
 void GcodeSuite::M250() {
34
-  if (parser.seen('C')) ui.set_contrast(parser.value_int());
35
-  SERIAL_ECHOLNPAIR("LCD Contrast: ", ui.contrast);
33
+  if (parser.seenval('C'))
34
+    ui.set_contrast(parser.value_int());
35
+  else
36
+    M250_report();
37
+}
38
+
39
+void GcodeSuite::M250_report(const bool forReplay/*=true*/) {
40
+  report_heading_etc(forReplay, PSTR(STR_LCD_CONTRAST));
41
+  SERIAL_ECHOLNPAIR("  M250 C", ui.contrast);
36 42
 }
37 43
 
38 44
 #endif // HAS_LCD_CONTRAST

+ 9
- 2
Marlin/src/gcode/lcd/M256.cpp View File

@@ -30,8 +30,15 @@
30 30
  * M256: Set the LCD brightness
31 31
  */
32 32
 void GcodeSuite::M256() {
33
-  if (parser.seenval('B')) ui.set_brightness(parser.value_int());
34
-  SERIAL_ECHOLNPAIR("LCD Brightness: ", ui.brightness);
33
+  if (parser.seenval('B'))
34
+    ui.set_brightness(parser.value_int());
35
+  else
36
+    M256_report();
37
+}
38
+
39
+void GcodeSuite::M256_report(const bool forReplay/*=true*/) {
40
+  report_heading_etc(forReplay, PSTR(STR_LCD_BRIGHTNESS));
41
+  SERIAL_ECHOLNPAIR("  M256 B", ui.brightness);
35 42
 }
36 43
 
37 44
 #endif // HAS_LCD_BRIGHTNESS

+ 7
- 0
Marlin/src/gcode/lcd/M414.cpp View File

@@ -38,7 +38,14 @@ void GcodeSuite::M414() {
38 38
 
39 39
   if (parser.seenval('S'))
40 40
     ui.set_language(parser.value_byte());
41
+  else
42
+    M414_report();
41 43
 
42 44
 }
43 45
 
46
+void GcodeSuite::M414_report(const bool forReplay/*=true*/) {
47
+  report_heading_etc(forReplay, PSTR(STR_UI_LANGUAGE));
48
+  SERIAL_ECHOLNPAIR("  M414 S", ui.language);
49
+}
50
+
44 51
 #endif // HAS_MULTI_LANGUAGE

+ 8
- 9
Marlin/src/gcode/parser.h View File

@@ -225,9 +225,7 @@ public:
225 225
   #endif // !FASTER_GCODE_PARSER
226 226
 
227 227
   // Seen any axis parameter
228
-  static inline bool seen_axis() {
229
-    return seen(LOGICAL_AXIS_GANG("E", "X", "Y", "Z", AXIS4_STR, AXIS5_STR, AXIS6_STR));
230
-  }
228
+  static inline bool seen_axis() { return seen(LOGICAL_AXES_STRING); }
231 229
 
232 230
   #if ENABLED(GCODE_QUOTED_STRINGS)
233 231
     static char* unescape_string(char* &src);
@@ -350,14 +348,15 @@ public:
350 348
 
351 349
     static inline void set_input_temp_units(const TempUnit units) { input_temp_units = units; }
352 350
 
351
+    static inline char temp_units_code() {
352
+      return input_temp_units == TEMPUNIT_K ? 'K' : input_temp_units == TEMPUNIT_F ? 'F' : 'C';
353
+    }
354
+    static inline PGM_P temp_units_name() {
355
+      return input_temp_units == TEMPUNIT_K ? PSTR("Kelvin") : input_temp_units == TEMPUNIT_F ? PSTR("Fahrenheit") : PSTR("Celsius");
356
+    }
357
+
353 358
     #if HAS_LCD_MENU && DISABLED(DISABLE_M503)
354 359
 
355
-      static inline char temp_units_code() {
356
-        return input_temp_units == TEMPUNIT_K ? 'K' : input_temp_units == TEMPUNIT_F ? 'F' : 'C';
357
-      }
358
-      static inline PGM_P temp_units_name() {
359
-        return input_temp_units == TEMPUNIT_K ? PSTR("Kelvin") : input_temp_units == TEMPUNIT_F ? PSTR("Fahrenheit") : PSTR("Celsius");
360
-      }
361 360
       static inline float to_temp_units(celsius_t c) {
362 361
         switch (input_temp_units) {
363 362
           default:

+ 18
- 13
Marlin/src/gcode/probe/M851.cpp View File

@@ -32,19 +32,8 @@
32 32
  * M851: Set the nozzle-to-probe offsets in current units
33 33
  */
34 34
 void GcodeSuite::M851() {
35
-
36
-  // Show usage with no parameters
37
-  if (!parser.seen("XYZ")) {
38
-    SERIAL_ECHOLNPAIR_P(
39
-      #if HAS_PROBE_XY_OFFSET
40
-        PSTR(STR_PROBE_OFFSET " X"), probe.offset_xy.x, SP_Y_STR, probe.offset_xy.y, SP_Z_STR
41
-      #else
42
-        PSTR(STR_PROBE_OFFSET " X0 Y0 Z")
43
-      #endif
44
-      , probe.offset.z
45
-    );
46
-    return;
47
-  }
35
+  // No parameters? Show current state.
36
+  if (!parser.seen("XYZ")) return M851_report();
48 37
 
49 38
   // Start with current offsets and modify
50 39
   xyz_pos_t offs = probe.offset;
@@ -94,4 +83,20 @@ void GcodeSuite::M851() {
94 83
   if (ok) probe.offset = offs;
95 84
 }
96 85
 
86
+void GcodeSuite::M851_report(const bool forReplay/*=true*/) {
87
+  report_heading_etc(forReplay, PSTR(STR_Z_PROBE_OFFSET));
88
+  SERIAL_ECHOPAIR_P(
89
+    #if HAS_PROBE_XY_OFFSET
90
+      PSTR("  M851 X"), LINEAR_UNIT(probe.offset_xy.x),
91
+              SP_Y_STR, LINEAR_UNIT(probe.offset_xy.y),
92
+              SP_Z_STR
93
+    #else
94
+      PSTR("  M851 X0 Y0 Z")
95
+    #endif
96
+    , LINEAR_UNIT(probe.offset.z)
97
+    , " ;"
98
+  );
99
+  say_units();
100
+}
101
+
97 102
 #endif // HAS_BED_PROBE

+ 7
- 0
Marlin/src/gcode/units/M149.cpp View File

@@ -33,6 +33,13 @@ void GcodeSuite::M149() {
33 33
        if (parser.seenval('C')) parser.set_input_temp_units(TEMPUNIT_C);
34 34
   else if (parser.seenval('K')) parser.set_input_temp_units(TEMPUNIT_K);
35 35
   else if (parser.seenval('F')) parser.set_input_temp_units(TEMPUNIT_F);
36
+  else M149_report();
37
+}
38
+
39
+void GcodeSuite::M149_report(const bool forReplay/*=true*/) {
40
+  report_heading_etc(forReplay, PSTR(STR_TEMPERATURE_UNITS));
41
+  SERIAL_ECHOPAIR("  M149 ", AS_CHAR(parser.temp_units_code()), " ; Units in ");
42
+  SERIAL_ECHOLNPGM_P(parser.temp_units_name());
36 43
 }
37 44
 
38 45
 #endif // TEMPERATURE_UNITS_SUPPORT

+ 2
- 2
Marlin/src/module/endstops.cpp View File

@@ -578,13 +578,13 @@ void _O2 Endstops::report_states() {
578 578
         default: continue;
579 579
         REPEAT_1(NUM_RUNOUT_SENSORS, _CASE_RUNOUT)
580 580
       }
581
-      SERIAL_ECHOPGM(STR_FILAMENT_RUNOUT_SENSOR);
581
+      SERIAL_ECHOPGM(STR_FILAMENT);
582 582
       if (i > 1) SERIAL_CHAR(' ', '0' + i);
583 583
       print_es_state(extDigitalRead(pin) != state);
584 584
     }
585 585
     #undef _CASE_RUNOUT
586 586
   #elif HAS_FILAMENT_SENSOR
587
-    print_es_state(READ(FIL_RUNOUT1_PIN) != FIL_RUNOUT1_STATE, PSTR(STR_FILAMENT_RUNOUT_SENSOR));
587
+    print_es_state(READ(FIL_RUNOUT1_PIN) != FIL_RUNOUT1_STATE, PSTR(STR_FILAMENT));
588 588
   #endif
589 589
 
590 590
   TERN_(BLTOUCH, bltouch._reset_SW_mode());

+ 164
- 828
Marlin/src/module/settings.cpp
File diff suppressed because it is too large
View File


+ 14
- 17
Marlin/src/module/temperature.cpp View File

@@ -59,6 +59,10 @@
59 59
   #include "../feature/host_actions.h"
60 60
 #endif
61 61
 
62
+#if HAS_TEMP_SENSOR
63
+  #include "../gcode/gcode.h"
64
+#endif
65
+
62 66
 // MAX TC related macros
63 67
 #define TEMP_SENSOR_IS_MAX(n, M) (ENABLED(TEMP_SENSOR_##n##_IS_MAX##M) || (ENABLED(TEMP_SENSOR_REDUNDANT_IS_MAX##M) && REDUNDANT_TEMP_MATCH(SOURCE, E##n)))
64 68
 #define TEMP_SENSOR_IS_ANY_MAX_TC(n) (ENABLED(TEMP_SENSOR_##n##_IS_MAX_TC) || (ENABLED(TEMP_SENSOR_REDUNDANT_IS_MAX_TC) && REDUNDANT_TEMP_MATCH(SOURCE, E##n)))
@@ -1722,13 +1726,9 @@ void Temperature::manage_heater() {
1722 1726
     COPY(user_thermistor, default_user_thermistor);
1723 1727
   }
1724 1728
 
1725
-  void Temperature::log_user_thermistor(const uint8_t t_index, const bool eprom/*=false*/) {
1726
-
1727
-    if (eprom)
1728
-      SERIAL_ECHOPGM("  M305 ");
1729
-    else
1730
-      SERIAL_ECHO_START();
1731
-    SERIAL_CHAR('P', '0' + t_index);
1729
+  void Temperature::M305_report(const uint8_t t_index, const bool forReplay/*=true*/) {
1730
+    gcode.report_heading_etc(forReplay, PSTR(STR_USER_THERMISTORS));
1731
+    SERIAL_ECHOPAIR("  M305 P", AS_DIGIT(t_index));
1732 1732
 
1733 1733
     const user_thermistor_t &t = user_thermistor[t_index];
1734 1734
 
@@ -1794,13 +1794,13 @@ void Temperature::manage_heater() {
1794 1794
   // Derived from RepRap FiveD extruder::getTemperature()
1795 1795
   // For hot end temperature measurement.
1796 1796
   celsius_float_t Temperature::analog_to_celsius_hotend(const int16_t raw, const uint8_t e) {
1797
-      if (e >= HOTENDS) {
1798
-        SERIAL_ERROR_START();
1799
-        SERIAL_ECHO(e);
1800
-        SERIAL_ECHOLNPGM(STR_INVALID_EXTRUDER_NUM);
1801
-        kill();
1802
-        return 0;
1803
-      }
1797
+    if (e >= HOTENDS) {
1798
+      SERIAL_ERROR_START();
1799
+      SERIAL_ECHO(e);
1800
+      SERIAL_ECHOLNPGM(STR_INVALID_EXTRUDER_NUM);
1801
+      kill();
1802
+      return 0;
1803
+    }
1804 1804
 
1805 1805
     switch (e) {
1806 1806
       case 0:
@@ -3490,9 +3490,6 @@ void Temperature::isr() {
3490 3490
 }
3491 3491
 
3492 3492
 #if HAS_TEMP_SENSOR
3493
-
3494
-  #include "../gcode/gcode.h"
3495
-
3496 3493
   /**
3497 3494
    * Print a single heater state in the form:
3498 3495
    *        Bed: " B:nnn.nn /nnn.nn"

+ 1
- 1
Marlin/src/module/temperature.h View File

@@ -527,7 +527,7 @@ class Temperature {
527 527
 
528 528
     #if HAS_USER_THERMISTORS
529 529
       static user_thermistor_t user_thermistor[USER_THERMISTORS];
530
-      static void log_user_thermistor(const uint8_t t_index, const bool eprom=false);
530
+      static void M305_report(const uint8_t t_index, const bool forReplay=true);
531 531
       static void reset_user_thermistors();
532 532
       static celsius_float_t user_thermistor_to_deg_c(const uint8_t t_index, const int16_t raw);
533 533
       static inline bool set_pull_up_res(int8_t t_index, float value) {

Loading…
Cancel
Save