Browse Source

G-code queue singleton, front injection (#14236)

Scott Lahteine 6 years ago
parent
commit
4c872a01f2
No account linked to committer's email address

+ 8
- 10
Marlin/src/Marlin.cpp View File

@@ -369,7 +369,7 @@ void disable_all_steppers() {
369 369
     #endif // HOST_ACTION_COMMANDS
370 370
 
371 371
     if (run_runout_script)
372
-      enqueue_and_echo_commands_front_P(PSTR(FILAMENT_RUNOUT_SCRIPT));
372
+      queue.inject_P(PSTR(FILAMENT_RUNOUT_SCRIPT));
373 373
   }
374 374
 
375 375
 #endif // HAS_FILAMENT_SENSOR
@@ -425,7 +425,7 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
425 425
     runout.run();
426 426
   #endif
427 427
 
428
-  if (commands_in_queue < BUFSIZE) get_available_commands();
428
+  if (queue.length < BUFSIZE) queue.get_available_commands();
429 429
 
430 430
   const millis_t ms = millis();
431 431
 
@@ -508,7 +508,7 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
508 508
     const int HOME_DEBOUNCE_DELAY = 2500;
509 509
     if (!IS_SD_PRINTING() && !READ(HOME_PIN)) {
510 510
       if (!homeDebounceCount) {
511
-        enqueue_and_echo_commands_P(PSTR("G28"));
511
+        queue.inject_P(PSTR("G28"));
512 512
         LCD_MESSAGEPGM(MSG_AUTO_HOME);
513 513
       }
514 514
       if (homeDebounceCount < HOME_DEBOUNCE_DELAY)
@@ -797,7 +797,7 @@ void stop() {
797 797
   #endif
798 798
 
799 799
   if (IsRunning()) {
800
-    Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart
800
+    queue.stop();
801 801
     SERIAL_ERROR_MSG(MSG_ERR_STOPPED);
802 802
     LCD_MESSAGEPGM(MSG_STOPPED);
803 803
     safe_delay(350);       // allow enough time for messages to get out before stopping
@@ -926,8 +926,6 @@ void setup() {
926 926
   SERIAL_ECHO_START();
927 927
   SERIAL_ECHOLNPAIR(MSG_FREE_MEMORY, freeMemory(), MSG_PLANNER_BUFFER_BYTES, (int)sizeof(block_t) * (BLOCK_BUFFER_SIZE));
928 928
 
929
-  queue_setup();
930
-
931 929
   // UI must be initialized before EEPROM
932 930
   // (because EEPROM code calls the UI).
933 931
   ui.init();
@@ -1135,7 +1133,7 @@ void loop() {
1135 1133
             true
1136 1134
           #endif
1137 1135
         );
1138
-        clear_command_queue();
1136
+        queue.clear();
1139 1137
         quickstop_stepper();
1140 1138
         print_job_timer.stop();
1141 1139
         #if DISABLED(SD_ABORT_NO_COOLDOWN)
@@ -1147,14 +1145,14 @@ void loop() {
1147 1145
           card.removeJobRecoveryFile();
1148 1146
         #endif
1149 1147
         #ifdef EVENT_GCODE_SD_STOP
1150
-          enqueue_and_echo_commands_P(PSTR(EVENT_GCODE_SD_STOP));
1148
+          queue.inject_P(PSTR(EVENT_GCODE_SD_STOP));
1151 1149
         #endif
1152 1150
       }
1153 1151
 
1154 1152
     #endif // SDSUPPORT
1155 1153
 
1156
-    if (commands_in_queue < BUFSIZE) get_available_commands();
1157
-    advance_command_queue();
1154
+    if (queue.length < BUFSIZE) queue.get_available_commands();
1155
+    queue.advance();
1158 1156
     endstops.event_handler();
1159 1157
     idle();
1160 1158
   }

+ 3
- 1
Marlin/src/core/macros.h View File

@@ -56,7 +56,9 @@
56 56
 #define NANOSECONDS_PER_CYCLE (1000000000.0 / F_CPU)
57 57
 
58 58
 // Remove compiler warning on an unused variable
59
-#define UNUSED(X) (void)X
59
+#ifndef UNUSED
60
+  #define UNUSED(x) ((void)(x))
61
+#endif
60 62
 
61 63
 // Macros to make a string from a macro
62 64
 #define STRINGIFY_(M) #M

+ 1
- 1
Marlin/src/feature/host_actions.cpp View File

@@ -142,7 +142,7 @@ void host_action(const char * const pstr, const bool eol) {
142 142
         break;
143 143
       case PROMPT_PAUSE_RESUME:
144 144
         msg = PSTR("LCD_PAUSE_RESUME");
145
-        enqueue_and_echo_commands_P(PSTR("M24"));
145
+        queue.inject_P(PSTR("M24"));
146 146
         break;
147 147
       case PROMPT_INFO:
148 148
         msg = PSTR("GCODE_INFO");

+ 9
- 9
Marlin/src/feature/power_loss_recovery.cpp View File

@@ -98,7 +98,7 @@ void PrintJobRecovery::check() {
98 98
     if (card.isDetected()) {
99 99
       load();
100 100
       if (!valid()) return purge();
101
-      enqueue_and_echo_commands_P(PSTR("M1000 S"));
101
+      queue.inject_P(PSTR("M1000 S"));
102 102
     }
103 103
   }
104 104
 }
@@ -209,9 +209,9 @@ void PrintJobRecovery::save(const bool force/*=false*/, const bool save_queue/*=
209 209
     info.relative_modes_e = gcode.axis_relative_modes[E_AXIS];
210 210
 
211 211
     // Commands in the queue
212
-    info.commands_in_queue = save_queue ? commands_in_queue : 0;
213
-    info.cmd_queue_index_r = cmd_queue_index_r;
214
-    COPY(info.command_queue, command_queue);
212
+    info.queue_length = save_queue ? queue.length : 0;
213
+    info.queue_index_r = queue.index_r;
214
+    COPY(info.queue_buffer, queue.buffer);
215 215
 
216 216
     // Elapsed print job time
217 217
     info.print_job_elapsed = print_job_timer.duration();
@@ -402,9 +402,9 @@ void PrintJobRecovery::resume() {
402 402
   #endif
403 403
 
404 404
   // Process commands from the old pending queue
405
-  uint8_t c = info.commands_in_queue, r = info.cmd_queue_index_r;
405
+  uint8_t c = info.queue_length, r = info.queue_index_r;
406 406
   for (; c--; r = (r + 1) % BUFSIZE)
407
-    gcode.process_subcommands_now(info.command_queue[r]);
407
+    gcode.process_subcommands_now(info.queue_buffer[r]);
408 408
 
409 409
   // Resume the SD file from the last position
410 410
   char *fn = info.sd_filename;
@@ -484,9 +484,9 @@ void PrintJobRecovery::resume() {
484 484
           DEBUG_EOL();
485 485
           DEBUG_ECHOLNPAIR("retract_hop: ", info.retract_hop);
486 486
         #endif
487
-        DEBUG_ECHOLNPAIR("cmd_queue_index_r: ", int(info.cmd_queue_index_r));
488
-        DEBUG_ECHOLNPAIR("commands_in_queue: ", int(info.commands_in_queue));
489
-        for (uint8_t i = 0; i < info.commands_in_queue; i++) DEBUG_ECHOLNPAIR("> ", info.command_queue[i]);
487
+        DEBUG_ECHOLNPAIR("queue_index_r: ", int(info.queue_index_r));
488
+        DEBUG_ECHOLNPAIR("queue_length: ", int(info.queue_length));
489
+        for (uint8_t i = 0; i < info.queue_length; i++) DEBUG_ECHOLNPAIR("> ", info.queue_buffer[i]);
490 490
         DEBUG_ECHOLNPAIR("sd_filename: ", info.sd_filename);
491 491
         DEBUG_ECHOLNPAIR("sdpos: ", info.sdpos);
492 492
         DEBUG_ECHOLNPAIR("print_job_elapsed: ", info.print_job_elapsed);

+ 2
- 2
Marlin/src/feature/power_loss_recovery.h View File

@@ -87,8 +87,8 @@ typedef struct {
87 87
   bool relative_mode, relative_modes_e;
88 88
 
89 89
   // Command queue
90
-  uint8_t commands_in_queue, cmd_queue_index_r;
91
-  char command_queue[BUFSIZE][MAX_CMD_SIZE];
90
+  uint8_t queue_length, queue_index_r;
91
+  char queue_buffer[BUFSIZE][MAX_CMD_SIZE];
92 92
 
93 93
   // SD Filename and position
94 94
   char sd_filename[MAXPATHNAMELENGTH];

+ 1
- 1
Marlin/src/feature/prusa_MMU2/mmu2.cpp View File

@@ -650,7 +650,7 @@ void MMU2::set_filament_type(uint8_t index, uint8_t filamentType) {
650 650
 }
651 651
 
652 652
 void MMU2::filament_runout() {
653
-  enqueue_and_echo_commands_P(PSTR(MMU2_FILAMENT_RUNOUT_SCRIPT));
653
+  queue.inject_P(PSTR(MMU2_FILAMENT_RUNOUT_SCRIPT));
654 654
   planner.synchronize();
655 655
 }
656 656
 

+ 1
- 1
Marlin/src/gcode/bedlevel/abl/G29.cpp View File

@@ -966,7 +966,7 @@ G29_TYPE GcodeSuite::G29() {
966 966
     #ifdef Z_PROBE_END_SCRIPT
967 967
       if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Z Probe End Script: ", Z_PROBE_END_SCRIPT);
968 968
       planner.synchronize();
969
-      enqueue_and_echo_commands_P(PSTR(Z_PROBE_END_SCRIPT));
969
+      queue.inject_P(PSTR(Z_PROBE_END_SCRIPT));
970 970
     #endif
971 971
 
972 972
     // Auto Bed Leveling is complete! Enable if possible.

+ 1
- 1
Marlin/src/gcode/bedlevel/mbl/G29.cpp View File

@@ -85,7 +85,7 @@ void GcodeSuite::G29() {
85 85
       mbl.reset();
86 86
       mbl_probe_index = 0;
87 87
       if (!ui.wait_for_bl_move) {
88
-        enqueue_and_echo_commands_P(PSTR("G28\nG29 S2"));
88
+        queue.inject_P(PSTR("G28\nG29 S2"));
89 89
         return;
90 90
       }
91 91
       state = MeshNext;

+ 1
- 1
Marlin/src/gcode/calibrate/M100.cpp View File

@@ -153,7 +153,7 @@ inline int32_t count_test_bytes(const char * const start_free_memory) {
153 153
       SERIAL_CHAR('|');                   // Point out non test bytes
154 154
       for (uint8_t i = 0; i < 16; i++) {
155 155
         char ccc = (char)start_free_memory[i]; // cast to char before automatically casting to char on assignment, in case the compiler is broken
156
-        if (&start_free_memory[i] >= (char*)command_queue && &start_free_memory[i] < (char*)command_queue + sizeof(command_queue)) { // Print out ASCII in the command buffer area
156
+        if (&start_free_memory[i] >= (char*)queue.buffer && &start_free_memory[i] < (char*)queue.buffer + sizeof(queue.buffer)) { // Print out ASCII in the command buffer area
157 157
           if (!WITHIN(ccc, ' ', 0x7E)) ccc = ' ';
158 158
         }
159 159
         else { // If not in the command buffer area, flag bytes that don't match the test byte

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

@@ -42,6 +42,5 @@ void GcodeSuite::M999() {
42 42
 
43 43
   if (parser.boolval('S')) return;
44 44
 
45
-  // gcode_LastN = Stopped_gcode_LastN;
46
-  flush_and_request_resend();
45
+  queue.flush_and_request_resend();
47 46
 }

+ 6
- 6
Marlin/src/gcode/gcode.cpp View File

@@ -187,7 +187,7 @@ void GcodeSuite::dwell(millis_t time) {
187 187
 /**
188 188
  * Process the parsed command and dispatch it to its handler
189 189
  */
190
-void GcodeSuite::process_parsed_command(const bool no_ok) {
190
+void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
191 191
   KEEPALIVE_STATE(IN_HANDLER);
192 192
 
193 193
   // Handle a known G, M, or T
@@ -798,7 +798,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok) {
798 798
 
799 799
   KEEPALIVE_STATE(NOT_BUSY);
800 800
 
801
-  if (!no_ok) ok_to_send();
801
+  if (!no_ok) queue.ok_to_send();
802 802
 }
803 803
 
804 804
 /**
@@ -806,16 +806,16 @@ void GcodeSuite::process_parsed_command(const bool no_ok) {
806 806
  * This is called from the main loop()
807 807
  */
808 808
 void GcodeSuite::process_next_command() {
809
-  char * const current_command = command_queue[cmd_queue_index_r];
809
+  char * const current_command = queue.buffer[queue.index_r];
810 810
 
811
-  PORT_REDIRECT(command_queue_port[cmd_queue_index_r]);
811
+  PORT_REDIRECT(queue.port[queue.index_r]);
812 812
 
813 813
   if (DEBUGGING(ECHO)) {
814 814
     SERIAL_ECHO_START();
815 815
     SERIAL_ECHOLN(current_command);
816 816
     #if ENABLED(M100_FREE_MEMORY_DUMPER)
817
-      SERIAL_ECHOPAIR("slot:", cmd_queue_index_r);
818
-      M100_dump_routine(PSTR("   Command Queue:"), (const char*)command_queue, (const char*)(command_queue) + sizeof(command_queue));
817
+      SERIAL_ECHOPAIR("slot:", queue.index_r);
818
+      M100_dump_routine(PSTR("   Command Queue:"), queue.buffer, queue.buffer + sizeof(queue.buffer));
819 819
     #endif
820 820
   }
821 821
 

+ 1
- 1
Marlin/src/gcode/gcode.h View File

@@ -315,7 +315,7 @@ public:
315 315
   static void process_parsed_command(const bool no_ok=false);
316 316
   static void process_next_command();
317 317
 
318
-  // Execute G-code as a macro, preserving parser state
318
+  // Execute G-code in-place, preserving current G-code parameters
319 319
   static void process_subcommands_now_P(PGM_P pgcode);
320 320
   static void process_subcommands_now(char * gcode);
321 321
 

+ 2
- 2
Marlin/src/gcode/host/M110.cpp View File

@@ -21,11 +21,11 @@
21 21
  */
22 22
 
23 23
 #include "../gcode.h"
24
-#include "../queue.h" // for gcode_LastN
24
+#include "../queue.h" // for last_N
25 25
 
26 26
 /**
27 27
  * M110: Set Current Line Number
28 28
  */
29 29
 void GcodeSuite::M110() {
30
-  if (parser.seenval('N')) gcode_LastN = parser.value_long();
30
+  if (parser.seenval('N')) queue.last_N = parser.value_long();
31 31
 }

+ 116
- 150
Marlin/src/gcode/queue.cpp View File

@@ -25,6 +25,8 @@
25 25
  */
26 26
 
27 27
 #include "queue.h"
28
+GCodeQueue queue;
29
+
28 30
 #include "gcode.h"
29 31
 
30 32
 #include "../lcd/ultralcd.h"
@@ -42,7 +44,7 @@
42 44
  * sending commands to Marlin, and lines will be checked for sequentiality.
43 45
  * M110 N<int> sets the current line number.
44 46
  */
45
-long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0;
47
+long gcode_N, GCodeQueue::last_N, GCodeQueue::stopped_N = 0;
46 48
 
47 49
 /**
48 50
  * GCode Command Queue
@@ -53,17 +55,17 @@ long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0;
53 55
  * the main loop. The gcode.process_next_command method parses the next
54 56
  * command and hands off execution to individual handler functions.
55 57
  */
56
-uint8_t commands_in_queue = 0, // Count of commands in the queue
57
-        cmd_queue_index_r = 0, // Ring buffer read position
58
-        cmd_queue_index_w = 0; // Ring buffer write position
58
+uint8_t GCodeQueue::length = 0,  // Count of commands in the queue
59
+        GCodeQueue::index_r = 0, // Ring buffer read position
60
+        GCodeQueue::index_w = 0; // Ring buffer write position
59 61
 
60
-char command_queue[BUFSIZE][MAX_CMD_SIZE];
62
+char GCodeQueue::buffer[BUFSIZE][MAX_CMD_SIZE];
61 63
 
62 64
 /*
63 65
  * The port that the command was received on
64 66
  */
65 67
 #if NUM_SERIAL > 1
66
-  int16_t command_queue_port[BUFSIZE];
68
+  int16_t GCodeQueue::port[BUFSIZE];
67 69
 #endif
68 70
 
69 71
 /**
@@ -82,7 +84,7 @@ bool send_ok[BUFSIZE];
82 84
  */
83 85
 static PGM_P injected_commands_P = nullptr;
84 86
 
85
-void queue_setup() {
87
+GCodeQueue::GCodeQueue() {
86 88
   // Send "ok" after commands by default
87 89
   for (uint8_t i = 0; i < COUNT(send_ok); i++) send_ok[i] = true;
88 90
 }
@@ -90,24 +92,24 @@ void queue_setup() {
90 92
 /**
91 93
  * Clear the Marlin command queue
92 94
  */
93
-void clear_command_queue() {
94
-  cmd_queue_index_r = cmd_queue_index_w = commands_in_queue = 0;
95
+void GCodeQueue::clear() {
96
+  index_r = index_w = length = 0;
95 97
 }
96 98
 
97 99
 /**
98 100
  * Once a new command is in the ring buffer, call this to commit it
99 101
  */
100
-inline void _commit_command(bool say_ok
102
+void GCodeQueue::_commit_command(bool say_ok
101 103
   #if NUM_SERIAL > 1
102
-    , int16_t port = -1
104
+    , int16_t p/*=-1*/
103 105
   #endif
104 106
 ) {
105
-  send_ok[cmd_queue_index_w] = say_ok;
107
+  send_ok[index_w] = say_ok;
106 108
   #if NUM_SERIAL > 1
107
-    command_queue_port[cmd_queue_index_w] = port;
109
+    port[index_w] = p;
108 110
   #endif
109
-  if (++cmd_queue_index_w >= BUFSIZE) cmd_queue_index_w = 0;
110
-  commands_in_queue++;
111
+  if (++index_w >= BUFSIZE) index_w = 0;
112
+  length++;
111 113
 }
112 114
 
113 115
 /**
@@ -115,16 +117,16 @@ inline void _commit_command(bool say_ok
115 117
  * Return true if the command was successfully added.
116 118
  * Return false for a full buffer, or if the 'command' is a comment.
117 119
  */
118
-inline bool _enqueuecommand(const char* cmd, bool say_ok=false
120
+bool GCodeQueue::_enqueue(const char* cmd, bool say_ok/*=false*/
119 121
   #if NUM_SERIAL > 1
120
-    , int16_t port = -1
122
+    , int16_t pn/*=-1*/
121 123
   #endif
122 124
 ) {
123
-  if (*cmd == ';' || commands_in_queue >= BUFSIZE) return false;
124
-  strcpy(command_queue[cmd_queue_index_w], cmd);
125
+  if (*cmd == ';' || length >= BUFSIZE) return false;
126
+  strcpy(buffer[index_w], cmd);
125 127
   _commit_command(say_ok
126 128
     #if NUM_SERIAL > 1
127
-      , port
129
+      , pn
128 130
     #endif
129 131
   );
130 132
   return true;
@@ -134,15 +136,15 @@ inline bool _enqueuecommand(const char* cmd, bool say_ok=false
134 136
  * Enqueue with Serial Echo
135 137
  * Return true if the command was consumed
136 138
  */
137
-bool enqueue_and_echo_command(const char* cmd) {
139
+bool GCodeQueue::enqueue_one(const char* cmd) {
138 140
 
139
-  //SERIAL_ECHOPGM("enqueue_and_echo_command(\"");
141
+  //SERIAL_ECHOPGM("enqueue_one(\"");
140 142
   //SERIAL_ECHO(cmd);
141 143
   //SERIAL_ECHOPGM("\") \n");
142 144
 
143 145
   if (*cmd == 0 || *cmd == '\n' || *cmd == '\r') return true;
144 146
 
145
-  if (_enqueuecommand(cmd)) {
147
+  if (_enqueue(cmd)) {
146 148
     SERIAL_ECHO_START();
147 149
     SERIAL_ECHOLNPAIR(MSG_ENQUEUEING, cmd, "\"");
148 150
     return true;
@@ -150,104 +152,67 @@ bool enqueue_and_echo_command(const char* cmd) {
150 152
   return false;
151 153
 }
152 154
 
153
-#if HAS_QUEUE_FRONT
155
+/**
156
+ * Process the next "immediate" command.
157
+ */
158
+bool GCodeQueue::process_injected_command() {
159
+  if (injected_commands_P == nullptr) return false;
154 160
 
155
-  bool early_cmd; // = false
161
+  char c;
162
+  size_t i = 0;
163
+  while ((c = pgm_read_byte(&injected_commands_P[i])) && c != '\n') i++;
164
+  if (!i) return false;
156 165
 
157
-  /**
158
-   * Insert a high Priority command from RAM into the main command buffer.
159
-   * Return true if the command was consumed
160
-   * Return false for a full buffer, or if the 'command' is a comment.
161
-   */
162
-  inline bool _enqueuecommand_front(const char* cmd) {
163
-    if (*cmd == 0 || *cmd == '\n' || *cmd == '\r') return true;
164
-    if (*cmd == ';' || commands_in_queue >= BUFSIZE) return false;
165
-    if (cmd_queue_index_r == 0) cmd_queue_index_r = BUFSIZE;
166
-    --cmd_queue_index_r;
167
-    strcpy(command_queue[cmd_queue_index_r], cmd);
168
-    send_ok[cmd_queue_index_r] = false;
169
-    #if NUM_SERIAL > 1
170
-      command_queue_port[cmd_queue_index_r] = -1;
171
-    #endif
172
-    commands_in_queue++;
173
-    return true;
174
-  }
166
+  char cmd[i + 1];
167
+  memcpy_P(cmd, injected_commands_P, i);
168
+  cmd[i] = '\0';
175 169
 
176
-  /**
177
-   * Insert in the front of queue, one or many commands to run from program memory.
178
-   * Aborts the current queue, if any.
179
-   * Note: drain_injected_commands_P() must be called repeatedly to drain the commands afterwards
180
-   */
181
-  void enqueue_and_echo_commands_front_P(PGM_P const pgcode) {
182
-    early_cmd = true;
183
-    enqueue_and_echo_commands_P(pgcode);
184
-  }
170
+  injected_commands_P = c ? injected_commands_P + i + 1 : nullptr;
185 171
 
186
-#endif
172
+  parser.parse(cmd);
173
+  PORT_REDIRECT(SERIAL_PORT);
174
+  gcode.process_parsed_command();
175
+  PORT_RESTORE();
187 176
 
188
-/**
189
- * Inject the next "immediate" command, when possible, onto the front of the queue.
190
- * Return true if any immediate commands remain to inject.
191
- * Do not inject a comment or use leading space!.
192
- */
193
-static bool drain_injected_commands_P() {
194
-  while (injected_commands_P != nullptr) {
195
-    size_t i = 0;
196
-    char c, cmd[60];
197
-    strncpy_P(cmd, injected_commands_P, sizeof(cmd) - 1);
198
-    cmd[sizeof(cmd) - 1] = '\0';
199
-    while ((c = cmd[i]) && c != '\n') i++; // find the end of this gcode command
200
-    cmd[i] = '\0';
201
-
202
-    if (
203
-      #if HAS_QUEUE_FRONT
204
-        early_cmd ? _enqueuecommand_front(cmd) :
205
-      #endif
206
-      enqueue_and_echo_command(cmd)
207
-    ) {
208
-      injected_commands_P = c ? injected_commands_P + i + 1 : nullptr; // next command or done
209
-      #if HAS_QUEUE_FRONT
210
-        if (!c) early_cmd = false;
211
-      #endif
212
-    }
213
-    else
214
-      return true; // buffer is full (or command is comment);
215
-  }
216
-  return false;   // return whether any more remain
177
+  return true;
217 178
 }
218 179
 
219 180
 /**
220 181
  * Enqueue one or many commands to run from program memory.
182
+ * Do not inject a comment or use leading spaces!
221 183
  * Aborts the current queue, if any.
222
- * Note: drain_injected_commands_P() must be called repeatedly to drain the commands afterwards
184
+ * Note: process_injected_command() will be called to drain any commands afterwards
223 185
  */
224
-void enqueue_and_echo_commands_P(PGM_P const pgcode) {
225
-  #if HAS_QUEUE_FRONT
226
-    early_cmd = false;
227
-  #endif
186
+void GCodeQueue::inject_P(PGM_P const pgcode) {
228 187
   injected_commands_P = pgcode;
229
-  (void)drain_injected_commands_P(); // first command executed asap (when possible)
230 188
 }
231 189
 
232
-#if HAS_QUEUE_NOW
233
-  /**
234
-   * Enqueue and return only when commands are actually enqueued.
235
-   * Never call this from a G-code handler!
236
-   */
237
-  void enqueue_and_echo_command_now(const char* cmd) {
238
-    while (!enqueue_and_echo_command(cmd)) idle();
190
+/**
191
+ * Enqueue and return only when commands are actually enqueued.
192
+ * Never call this from a G-code handler!
193
+ */
194
+void GCodeQueue::enqueue_one_now(const char* cmd) {
195
+  while (!enqueue_one(cmd)) idle();
196
+}
197
+
198
+/**
199
+ * Enqueue from program memory and return only when commands are actually enqueued
200
+ * Never call this from a G-code handler!
201
+ */
202
+void GCodeQueue::enqueue_now_P(PGM_P const pgcode) {
203
+  size_t i = 0;
204
+  PGM_P p = pgcode;
205
+  for (;;) {
206
+    char c;
207
+    while ((c = p[i]) && c != '\n') i++;
208
+    char cmd[i + 1];
209
+    memcpy_P(cmd, p, i);
210
+    cmd[i] = '\0';
211
+    enqueue_one_now(cmd);
212
+    if (!c) break;
213
+    p += i + 1;
239 214
   }
240
-  #if HAS_LCD_QUEUE_NOW
241
-    /**
242
-     * Enqueue from program memory and return only when commands are actually enqueued
243
-     * Never call this from a G-code handler!
244
-     */
245
-    void enqueue_and_echo_commands_now_P(PGM_P const pgcode) {
246
-      enqueue_and_echo_commands_P(pgcode);
247
-      while (drain_injected_commands_P()) idle();
248
-    }
249
-  #endif
250
-#endif
215
+}
251 216
 
252 217
 /**
253 218
  * Send an "ok" message to the host, indicating
@@ -258,16 +223,16 @@ void enqueue_and_echo_commands_P(PGM_P const pgcode) {
258 223
  *   P<int>  Planner space remaining
259 224
  *   B<int>  Block queue space remaining
260 225
  */
261
-void ok_to_send() {
226
+void GCodeQueue::ok_to_send() {
262 227
   #if NUM_SERIAL > 1
263
-    const int16_t port = command_queue_port[cmd_queue_index_r];
264
-    if (port < 0) return;
265
-    PORT_REDIRECT(port);
228
+    const int16_t p = port[index_r];
229
+    if (p < 0) return;
230
+    PORT_REDIRECT(p);
266 231
   #endif
267
-  if (!send_ok[cmd_queue_index_r]) return;
232
+  if (!send_ok[index_r]) return;
268 233
   SERIAL_ECHOPGM(MSG_OK);
269 234
   #if ENABLED(ADVANCED_OK)
270
-    char* p = command_queue[cmd_queue_index_r];
235
+    char* p = buffer[index_r];
271 236
     if (*p == 'N') {
272 237
       SERIAL_ECHO(' ');
273 238
       SERIAL_ECHO(*p++);
@@ -275,7 +240,7 @@ void ok_to_send() {
275 240
         SERIAL_ECHO(*p++);
276 241
     }
277 242
     SERIAL_ECHOPGM(" P"); SERIAL_ECHO(int(BLOCK_BUFFER_SIZE - planner.movesplanned() - 1));
278
-    SERIAL_ECHOPGM(" B"); SERIAL_ECHO(BUFSIZE - commands_in_queue);
243
+    SERIAL_ECHOPGM(" B"); SERIAL_ECHO(BUFSIZE - length);
279 244
   #endif
280 245
   SERIAL_EOL();
281 246
 }
@@ -284,15 +249,15 @@ void ok_to_send() {
284 249
  * Send a "Resend: nnn" message to the host to
285 250
  * indicate that a command needs to be re-sent.
286 251
  */
287
-void flush_and_request_resend() {
252
+void GCodeQueue::flush_and_request_resend() {
288 253
   #if NUM_SERIAL > 1
289
-    const int16_t port = command_queue_port[cmd_queue_index_r];
290
-    if (port < 0) return;
291
-    PORT_REDIRECT(port);
254
+    const int16_t p = port[index_r];
255
+    if (p < 0) return;
256
+    PORT_REDIRECT(p);
292 257
   #endif
293 258
   SERIAL_FLUSH();
294 259
   SERIAL_ECHOPGM(MSG_RESEND);
295
-  SERIAL_ECHOLN(gcode_LastN + 1);
260
+  SERIAL_ECHOLN(last_N + 1);
296 261
   ok_to_send();
297 262
 }
298 263
 
@@ -315,16 +280,6 @@ inline int read_serial(const uint8_t index) {
315 280
   }
316 281
 }
317 282
 
318
-void gcode_line_error(PGM_P const err, const int8_t port) {
319
-  PORT_REDIRECT(port);
320
-  SERIAL_ERROR_START();
321
-  serialprintPGM(err);
322
-  SERIAL_ECHOLN(gcode_LastN);
323
-  while (read_serial(port) != -1);           // clear out the RX buffer
324
-  flush_and_request_resend();
325
-  serial_count[port] = 0;
326
-}
327
-
328 283
 #if ENABLED(BINARY_FILE_TRANSFER)
329 284
 
330 285
   inline bool serial_data_available(const uint8_t index) {
@@ -575,6 +530,16 @@ void gcode_line_error(PGM_P const err, const int8_t port) {
575 530
 
576 531
 #endif // BINARY_FILE_TRANSFER
577 532
 
533
+void GCodeQueue::gcode_line_error(PGM_P const err, const int8_t port) {
534
+  PORT_REDIRECT(port);
535
+  SERIAL_ERROR_START();
536
+  serialprintPGM(err);
537
+  SERIAL_ECHOLN(last_N);
538
+  while (read_serial(port) != -1);           // clear out the RX buffer
539
+  flush_and_request_resend();
540
+  serial_count[port] = 0;
541
+}
542
+
578 543
 FORCE_INLINE bool is_M29(const char * const cmd) {  // matches "M29" & "M29 ", but not "M290", etc
579 544
   const char * const m29 = strstr_P(cmd, PSTR("M29"));
580 545
   return m29 && !NUMERIC(m29[3]);
@@ -585,7 +550,7 @@ FORCE_INLINE bool is_M29(const char * const cmd) {  // matches "M29" & "M29 ", b
585 550
  * Exit when the buffer is full or when no more characters are
586 551
  * left on the serial port.
587 552
  */
588
-inline void get_serial_commands() {
553
+void GCodeQueue::get_serial_commands() {
589 554
   static char serial_line_buffer[NUM_SERIAL][MAX_CMD_SIZE];
590 555
   static bool serial_comment_mode[NUM_SERIAL] = { false }
591 556
               #if ENABLED(PAREN_COMMENTS)
@@ -610,7 +575,7 @@ inline void get_serial_commands() {
610 575
   #if NO_TIMEOUTS > 0
611 576
     static millis_t last_command_time = 0;
612 577
     const millis_t ms = millis();
613
-    if (commands_in_queue == 0 && !serial_data_available() && ELAPSED(ms, last_command_time + NO_TIMEOUTS)) {
578
+    if (length == 0 && !serial_data_available() && ELAPSED(ms, last_command_time + NO_TIMEOUTS)) {
614 579
       SERIAL_ECHOLNPGM(MSG_WAIT);
615 580
       last_command_time = ms;
616 581
     }
@@ -619,7 +584,7 @@ inline void get_serial_commands() {
619 584
   /**
620 585
    * Loop while serial characters are incoming and the queue is not full
621 586
    */
622
-  while (commands_in_queue < BUFSIZE && serial_data_available()) {
587
+  while (length < BUFSIZE && serial_data_available()) {
623 588
     for (uint8_t i = 0; i < NUM_SERIAL; ++i) {
624 589
       int c;
625 590
       if ((c = read_serial(i)) < 0) continue;
@@ -659,7 +624,7 @@ inline void get_serial_commands() {
659 624
 
660 625
           gcode_N = strtol(npos + 1, nullptr, 10);
661 626
 
662
-          if (gcode_N != gcode_LastN + 1 && !M110)
627
+          if (gcode_N != last_N + 1 && !M110)
663 628
             return gcode_line_error(PSTR(MSG_ERR_LINE_NO), i);
664 629
 
665 630
           char *apos = strrchr(command, '*');
@@ -672,7 +637,7 @@ inline void get_serial_commands() {
672 637
           else
673 638
             return gcode_line_error(PSTR(MSG_ERR_NO_CHECKSUM), i);
674 639
 
675
-          gcode_LastN = gcode_N;
640
+          last_N = gcode_N;
676 641
         }
677 642
         #if ENABLED(SDSUPPORT)
678 643
           // Pronterface "M29" and "M29 " has no line number
@@ -718,7 +683,7 @@ inline void get_serial_commands() {
718 683
         #endif
719 684
 
720 685
         // Add the command to the queue
721
-        _enqueuecommand(serial_line_buffer[i], true
686
+        _enqueue(serial_line_buffer[i], true
722 687
           #if NUM_SERIAL > 1
723 688
             , i
724 689
           #endif
@@ -760,7 +725,7 @@ inline void get_serial_commands() {
760 725
    * or until the end of the file is reached. The special character '#'
761 726
    * can also interrupt buffering.
762 727
    */
763
-  inline void get_sdcard_commands() {
728
+  inline void GCodeQueue::get_sdcard_commands() {
764 729
     static bool stop_buffering = false,
765 730
                 sd_comment_mode = false
766 731
                 #if ENABLED(PAREN_COMMENTS)
@@ -777,11 +742,11 @@ inline void get_serial_commands() {
777 742
      * due to checksums, however, no checksums are used in SD printing.
778 743
      */
779 744
 
780
-    if (commands_in_queue == 0) stop_buffering = false;
745
+    if (length == 0) stop_buffering = false;
781 746
 
782 747
     uint16_t sd_count = 0;
783 748
     bool card_eof = card.eof();
784
-    while (commands_in_queue < BUFSIZE && !card_eof && !stop_buffering) {
749
+    while (length < BUFSIZE && !card_eof && !stop_buffering) {
785 750
       const int16_t n = card.get();
786 751
       char sd_char = (char)n;
787 752
       card_eof = card.eof();
@@ -804,7 +769,7 @@ inline void get_serial_commands() {
804 769
             #if ENABLED(PRINTER_EVENT_LEDS)
805 770
               printerEventLEDs.onPrintCompleted();
806 771
               #if HAS_RESUME_CONTINUE
807
-                enqueue_and_echo_commands_P(PSTR("M0 S"
772
+                inject_P(PSTR("M0 S"
808 773
                   #if HAS_LCD_MENU
809 774
                     "1800"
810 775
                   #else
@@ -828,7 +793,7 @@ inline void get_serial_commands() {
828 793
         // Skip empty lines and comments
829 794
         if (!sd_count) { thermalManager.manage_heater(); continue; }
830 795
 
831
-        command_queue[cmd_queue_index_w][sd_count] = '\0'; // terminate string
796
+        buffer[index_w][sd_count] = '\0'; // terminate string
832 797
         sd_count = 0; // clear sd line buffer
833 798
 
834 799
         _commit_command(false);
@@ -849,7 +814,7 @@ inline void get_serial_commands() {
849 814
           #if ENABLED(PAREN_COMMENTS)
850 815
             && ! sd_comment_paren_mode
851 816
           #endif
852
-        ) command_queue[cmd_queue_index_w][sd_count++] = sd_char;
817
+        ) buffer[index_w][sd_count++] = sd_char;
853 818
       }
854 819
     }
855 820
   }
@@ -862,10 +827,7 @@ inline void get_serial_commands() {
862 827
  *  - The active serial input (usually USB)
863 828
  *  - The SD card file being actively printed
864 829
  */
865
-void get_available_commands() {
866
-
867
-  // if any immediate commands remain, don't get other commands yet
868
-  if (drain_injected_commands_P()) return;
830
+void GCodeQueue::get_available_commands() {
869 831
 
870 832
   get_serial_commands();
871 833
 
@@ -877,14 +839,18 @@ void get_available_commands() {
877 839
 /**
878 840
  * Get the next command in the queue, optionally log it to SD, then dispatch it
879 841
  */
880
-void advance_command_queue() {
842
+void GCodeQueue::advance() {
843
+
844
+  // Process immediate commands
845
+  if (process_injected_command()) return;
881 846
 
882
-  if (!commands_in_queue) return;
847
+  // Return if the G-code buffer is empty
848
+  if (!length) return;
883 849
 
884 850
   #if ENABLED(SDSUPPORT)
885 851
 
886 852
     if (card.flag.saving) {
887
-      char* command = command_queue[cmd_queue_index_r];
853
+      char* command = buffer[index_r];
888 854
       if (is_M29(command)) {
889 855
         // M29 closes the file
890 856
         card.closefile();
@@ -921,9 +887,9 @@ void advance_command_queue() {
921 887
   #endif // SDSUPPORT
922 888
 
923 889
   // The queue may be reset by a command handler or by code invoked by idle() within a handler
924
-  if (commands_in_queue) {
925
-    --commands_in_queue;
926
-    if (++cmd_queue_index_r >= BUFSIZE) cmd_queue_index_r = 0;
890
+  if (length) {
891
+    --length;
892
+    if (++index_r >= BUFSIZE) index_r = 0;
927 893
   }
928 894
 
929 895
 }

+ 103
- 87
Marlin/src/gcode/queue.h View File

@@ -28,109 +28,125 @@
28 28
 
29 29
 #include "../inc/MarlinConfig.h"
30 30
 
31
-/**
32
- * GCode line number handling. Hosts may include line numbers when sending
33
- * commands to Marlin, and lines will be checked for sequentiality.
34
- * M110 N<int> sets the current line number.
35
- */
36
-extern long gcode_LastN, Stopped_gcode_LastN;
37
-
38
-/**
39
- * GCode Command Queue
40
- * A simple ring buffer of BUFSIZE command strings.
41
- *
42
- * Commands are copied into this buffer by the command injectors
43
- * (immediate, serial, sd card) and they are processed sequentially by
44
- * the main loop. The gcode.process_next_command method parses the next
45
- * command and hands off execution to individual handler functions.
46
- */
47
-extern uint8_t commands_in_queue, // Count of commands in the queue
48
-               cmd_queue_index_r; // Ring buffer read position
31
+class GCodeQueue {
32
+public:
33
+  /**
34
+   * GCode line number handling. Hosts may include line numbers when sending
35
+   * commands to Marlin, and lines will be checked for sequentiality.
36
+   * M110 N<int> sets the current line number.
37
+   */
38
+  static long last_N, stopped_N;
49 39
 
50
-extern char command_queue[BUFSIZE][MAX_CMD_SIZE];
40
+  static inline void stop() { stopped_N = last_N; }
51 41
 
52
-/*
53
- * The port that the command was received on
54
- */
55
-#if NUM_SERIAL > 1
56
-  extern int16_t command_queue_port[BUFSIZE];
57
-#endif
42
+  /**
43
+   * GCode Command Queue
44
+   * A simple ring buffer of BUFSIZE command strings.
45
+   *
46
+   * Commands are copied into this buffer by the command injectors
47
+   * (immediate, serial, sd card) and they are processed sequentially by
48
+   * the main loop. The gcode.process_next_command method parses the next
49
+   * command and hands off execution to individual handler functions.
50
+   */
51
+  static uint8_t length,  // Count of commands in the queue
52
+                 index_r; // Ring buffer read position
58 53
 
59
-/**
60
- * Initialization of queue for setup()
61
- */
62
-void queue_setup();
54
+  static char buffer[BUFSIZE][MAX_CMD_SIZE];
63 55
 
64
-/**
65
- * Clear the Marlin command queue
66
- */
67
-void clear_command_queue();
56
+  /*
57
+   * The port that the command was received on
58
+   */
59
+  #if NUM_SERIAL > 1
60
+    static int16_t port[BUFSIZE];
61
+  #endif
68 62
 
69
-/**
70
- * Clear the serial line and request a resend of
71
- * the next expected line number.
72
- */
73
-void flush_and_request_resend();
63
+  GCodeQueue();
74 64
 
75
-/**
76
- * Send an "ok" message to the host, indicating
77
- * that a command was successfully processed.
78
- *
79
- * If ADVANCED_OK is enabled also include:
80
- *   N<int>  Line number of the command, if any
81
- *   P<int>  Planner space remaining
82
- *   B<int>  Block queue space remaining
83
- */
84
-void ok_to_send();
65
+  /**
66
+   * Clear the Marlin command queue
67
+   */
68
+  static void clear();
85 69
 
86
-#if ENABLED(ADVANCED_PAUSE_FEATURE)
87 70
   /**
88
-   * Insert in the front of queue, one or many commands to run from program memory.
71
+   * Enqueue one or many commands to run from program memory.
89 72
    * Aborts the current queue, if any.
90
-   * Note: drain_injected_commands_P() must be called repeatedly to drain the commands afterwards
73
+   * Note: process_injected_command() will process them.
91 74
    */
92
-  void enqueue_and_echo_commands_front_P(PGM_P const pgcode);
93
-#endif
75
+  static void inject_P(PGM_P const pgcode);
94 76
 
95
-/**
96
- * Enqueue one or many commands to run from program memory.
97
- * Aborts the current queue, if any.
98
- * Note: drain_injected_commands_P() must be called repeatedly to drain the commands afterwards
99
- */
100
-void enqueue_and_echo_commands_P(PGM_P const pgcode);
77
+  /**
78
+   * Enqueue and return only when commands are actually enqueued
79
+   */
80
+  static void enqueue_one_now(const char* cmd);
101 81
 
102
-/**
103
- * Enqueue with Serial Echo
104
- * Return true on success
105
- */
106
-bool enqueue_and_echo_command(const char* cmd);
82
+  /**
83
+   * Enqueue from program memory and return only when commands are actually enqueued
84
+   */
85
+  static void enqueue_now_P(PGM_P const cmd);
107 86
 
108
-#define HAS_LCD_QUEUE_NOW (ENABLED(MALYAN_LCD) || (HAS_LCD_MENU && ANY(AUTO_BED_LEVELING_UBL, PID_AUTOTUNE_MENU, ADVANCED_PAUSE_FEATURE)))
109
-#define HAS_QUEUE_NOW (ENABLED(SDSUPPORT) || HAS_LCD_QUEUE_NOW)
110
-#define HAS_QUEUE_FRONT ENABLED(ADVANCED_PAUSE_FEATURE)
87
+  /**
88
+   * Get the next command in the queue, optionally log it to SD, then dispatch it
89
+   */
90
+  static void advance();
111 91
 
112
-#if HAS_QUEUE_NOW
113 92
   /**
114
-   * Enqueue and return only when commands are actually enqueued
93
+   * Add to the circular command queue the next command from:
94
+   *  - The command-injection queue (injected_commands_P)
95
+   *  - The active serial input (usually USB)
96
+   *  - The SD card file being actively printed
115 97
    */
116
-  void enqueue_and_echo_command_now(const char* cmd);
117
-  #if HAS_LCD_QUEUE_NOW
118
-    /**
119
-     * Enqueue from program memory and return only when commands are actually enqueued
120
-     */
121
-    void enqueue_and_echo_commands_now_P(PGM_P const cmd);
98
+  static void get_available_commands();
99
+
100
+  /**
101
+   * Send an "ok" message to the host, indicating
102
+   * that a command was successfully processed.
103
+   *
104
+   * If ADVANCED_OK is enabled also include:
105
+   *   N<int>  Line number of the command, if any
106
+   *   P<int>  Planner space remaining
107
+   *   B<int>  Block queue space remaining
108
+   */
109
+  static void ok_to_send();
110
+
111
+  /**
112
+   * Clear the serial line and request a resend of
113
+   * the next expected line number.
114
+   */
115
+  static void flush_and_request_resend();
116
+
117
+private:
118
+
119
+  static uint8_t index_w;  // Ring buffer write position
120
+
121
+  static void get_serial_commands();
122
+
123
+  #if ENABLED(SDSUPPORT)
124
+    static void get_sdcard_commands();
122 125
   #endif
123
-#endif
124 126
 
125
-/**
126
- * Add to the circular command queue the next command from:
127
- *  - The command-injection queue (injected_commands_P)
128
- *  - The active serial input (usually USB)
129
- *  - The SD card file being actively printed
130
- */
131
-void get_available_commands();
127
+  static void _commit_command(bool say_ok
128
+    #if NUM_SERIAL > 1
129
+      , int16_t p=-1
130
+    #endif
131
+  );
132 132
 
133
-/**
134
- * Get the next command in the queue, optionally log it to SD, then dispatch it
135
- */
136
-void advance_command_queue();
133
+  static bool _enqueue(const char* cmd, bool say_ok=false
134
+    #if NUM_SERIAL > 1
135
+      , int16_t p=-1
136
+    #endif
137
+  );
138
+
139
+  // Process the next "immediate" command
140
+  static bool process_injected_command();
141
+
142
+  /**
143
+   * Enqueue with Serial Echo
144
+   * Return true on success
145
+   */
146
+  static bool enqueue_one(const char* cmd);
147
+
148
+  static void gcode_line_error(PGM_P const err, const int8_t port);
149
+
150
+};
151
+
152
+extern GCodeQueue queue;

+ 1
- 1
Marlin/src/gcode/sdcard/M28_M29.cpp View File

@@ -53,7 +53,7 @@ void GcodeSuite::M28() {
53 53
       SERIAL_ECHOLN(p);
54 54
       card.openFile(p, false);
55 55
       #if NUM_SERIAL > 1
56
-        card.transfer_port_index = command_queue_port[cmd_queue_index_r];
56
+        card.transfer_port_index = queue.port[queue.index_r];
57 57
       #endif
58 58
     }
59 59
     else

+ 2
- 2
Marlin/src/lcd/extensible_ui/ui_api.cpp View File

@@ -777,10 +777,10 @@ namespace ExtUI {
777 777
   float getFeedrate_percent() { return feedrate_percentage; }
778 778
 
779 779
   void enqueueCommands_P(PGM_P const gcode) {
780
-    enqueue_and_echo_commands_P(gcode);
780
+    queue.inject_P(gcode);
781 781
   }
782 782
 
783
-  bool commandsInQueue() { return (planner.movesplanned() || commands_in_queue); }
783
+  bool commandsInQueue() { return (planner.movesplanned() || queue.length); }
784 784
 
785 785
   bool isAxisPositionKnown(const axis_t axis) {
786 786
     return TEST(axis_known_position, axis);

+ 6
- 6
Marlin/src/lcd/malyanlcd.cpp View File

@@ -190,8 +190,8 @@ void process_lcd_j_command(const char* command) {
190 190
     case 'E':
191 191
       // enable or disable steppers
192 192
       // switch to relative
193
-      enqueue_and_echo_commands_now_P(PSTR("G91"));
194
-      enqueue_and_echo_commands_now_P(steppers_enabled ? PSTR("M18") : PSTR("M17"));
193
+      queue.enqueue_now_P(PSTR("G91"));
194
+      queue.enqueue_now_P(steppers_enabled ? PSTR("M18") : PSTR("M17"));
195 195
       steppers_enabled = !steppers_enabled;
196 196
       break;
197 197
     case 'A':
@@ -204,7 +204,7 @@ void process_lcd_j_command(const char* command) {
204 204
       // The M200 class UI seems to send movement in .1mm values.
205 205
       char cmd[20];
206 206
       sprintf_P(cmd, PSTR("G1 %c%03.1f"), axis, atof(command + 1) / 10.0);
207
-      enqueue_and_echo_command_now(cmd);
207
+      queue.enqueue_one_now(cmd);
208 208
     } break;
209 209
     default:
210 210
       SERIAL_ECHOLNPAIR("UNKNOWN J COMMAND", command);
@@ -247,7 +247,7 @@ void process_lcd_p_command(const char* command) {
247 247
             true
248 248
           #endif
249 249
         );
250
-        clear_command_queue();
250
+        queue.clear();
251 251
         quickstop_stepper();
252 252
         print_job_timer.stop();
253 253
         thermalManager.disable_all_heaters();
@@ -258,7 +258,7 @@ void process_lcd_p_command(const char* command) {
258 258
       break;
259 259
     case 'H':
260 260
       // Home all axis
261
-      enqueue_and_echo_commands_now_P(PSTR("G28"));
261
+      queue.enqueue_now_P(PSTR("G28"));
262 262
       break;
263 263
     default: {
264 264
       #if ENABLED(SDSUPPORT)
@@ -321,7 +321,7 @@ void process_lcd_s_command(const char* command) {
321 321
 
322 322
     case 'H':
323 323
       // Home all axis
324
-      enqueue_and_echo_command("G28");
324
+      queue.inject_P(PSTR("G28"));
325 325
       break;
326 326
 
327 327
     case 'L': {

+ 5
- 5
Marlin/src/lcd/menu/menu.cpp View File

@@ -99,7 +99,7 @@ void MarlinUI::goto_previous_screen() {
99 99
 /////////// Common Menu Actions ////////////
100 100
 ////////////////////////////////////////////
101 101
 
102
-void MenuItem_gcode::action(PGM_P pgcode) { enqueue_and_echo_commands_P(pgcode); }
102
+void MenuItem_gcode::action(PGM_P pgcode) { queue.inject_P(pgcode); }
103 103
 
104 104
 ////////////////////////////////////////////
105 105
 /////////// Menu Editing Actions ///////////
@@ -410,15 +410,15 @@ void MarlinUI::completion_feedback(const bool good/*=true*/) {
410 410
 
411 411
 #if ANY(AUTO_BED_LEVELING_UBL, PID_AUTOTUNE_MENU, ADVANCED_PAUSE_FEATURE)
412 412
 
413
-  void lcd_enqueue_command(const char * const cmd) {
413
+  void lcd_enqueue_one_now(const char * const cmd) {
414 414
     no_reentry = true;
415
-    enqueue_and_echo_command_now(cmd);
415
+    queue.enqueue_one_now(cmd);
416 416
     no_reentry = false;
417 417
   }
418 418
 
419
-  void lcd_enqueue_commands_P(PGM_P const cmd) {
419
+  void lcd_enqueue_one_now_P(PGM_P const cmd) {
420 420
     no_reentry = true;
421
-    enqueue_and_echo_commands_now_P(cmd);
421
+    queue.enqueue_now_P(cmd);
422 422
     no_reentry = false;
423 423
   }
424 424
 

+ 2
- 2
Marlin/src/lcd/menu/menu.h View File

@@ -375,8 +375,8 @@ void _lcd_draw_homing();
375 375
 #endif
376 376
 
377 377
 #if ANY(AUTO_BED_LEVELING_UBL, PID_AUTOTUNE_MENU, ADVANCED_PAUSE_FEATURE)
378
-  void lcd_enqueue_command(const char * const cmd);
379
-  void lcd_enqueue_commands_P(PGM_P const cmd);
378
+  void lcd_enqueue_one_now(const char * const cmd);
379
+  void lcd_enqueue_one_now_P(PGM_P const cmd);
380 380
 #endif
381 381
 
382 382
 #if ENABLED(LEVEL_BED_CORNERS)

+ 2
- 2
Marlin/src/lcd/menu/menu_advanced.cpp View File

@@ -101,7 +101,7 @@ void menu_backlash();
101 101
   // Set the home offset based on the current_position
102 102
   //
103 103
   void _lcd_set_home_offsets() {
104
-    enqueue_and_echo_commands_P(PSTR("M428"));
104
+    queue.inject_P(PSTR("M428"));
105 105
     ui.return_to_status();
106 106
   }
107 107
 #endif
@@ -255,7 +255,7 @@ void menu_backlash();
255 255
         autotune_temp[e]
256 256
       #endif
257 257
     );
258
-    lcd_enqueue_command(cmd);
258
+    lcd_enqueue_one_now(cmd);
259 259
   }
260 260
 
261 261
 #endif // PID_AUTOTUNE_MENU

+ 1
- 1
Marlin/src/lcd/menu/menu_bed_corners.cpp View File

@@ -120,7 +120,7 @@ void _lcd_level_bed_corners() {
120 120
   ui.defer_status_screen();
121 121
   if (!all_axes_known()) {
122 122
     set_all_unhomed();
123
-    enqueue_and_echo_commands_P(PSTR("G28"));
123
+    queue.inject_P(PSTR("G28"));
124 124
   }
125 125
 
126 126
   // Disable leveling so the planner won't mess with us

+ 5
- 5
Marlin/src/lcd/menu/menu_bed_leveling.cpp View File

@@ -105,9 +105,9 @@
105 105
         ui.wait_for_bl_move = true;
106 106
         ui.goto_screen(_lcd_level_bed_done);
107 107
         #if ENABLED(MESH_BED_LEVELING)
108
-          enqueue_and_echo_commands_P(PSTR("G29 S2"));
108
+          queue.inject_P(PSTR("G29 S2"));
109 109
         #elif ENABLED(PROBE_MANUALLY)
110
-          enqueue_and_echo_commands_P(PSTR("G29 V1"));
110
+          queue.inject_P(PSTR("G29 V1"));
111 111
         #endif
112 112
       }
113 113
       else
@@ -157,9 +157,9 @@
157 157
     // G29 Records Z, moves, and signals when it pauses
158 158
     ui.wait_for_bl_move = true;
159 159
     #if ENABLED(MESH_BED_LEVELING)
160
-      enqueue_and_echo_commands_P(manual_probe_index ? PSTR("G29 S2") : PSTR("G29 S1"));
160
+      queue.inject_P(manual_probe_index ? PSTR("G29 S2") : PSTR("G29 S1"));
161 161
     #elif ENABLED(PROBE_MANUALLY)
162
-      enqueue_and_echo_commands_P(PSTR("G29 V1"));
162
+      queue.inject_P(PSTR("G29 V1"));
163 163
     #endif
164 164
   }
165 165
 
@@ -194,7 +194,7 @@
194 194
     ui.defer_status_screen();
195 195
     set_all_unhomed();
196 196
     ui.goto_screen(_lcd_level_bed_homing);
197
-    enqueue_and_echo_commands_P(PSTR("G28"));
197
+    queue.inject_P(PSTR("G28"));
198 198
   }
199 199
 
200 200
 #endif // PROBE_MANUALLY || MESH_BED_LEVELING

+ 1
- 1
Marlin/src/lcd/menu/menu_configuration.cpp View File

@@ -127,7 +127,7 @@ static void lcd_factory_settings() {
127 127
 
128 128
     auto _recalc_offsets = []{
129 129
       if (active_extruder && all_axes_known()) {  // For the 2nd extruder re-home so the next tool-change gets the new offsets.
130
-        enqueue_and_echo_commands_P(PSTR("G28")); // In future, we can babystep the 2nd extruder (if active), making homing unnecessary.
130
+        queue.inject_P(PSTR("G28")); // In future, we can babystep the 2nd extruder (if active), making homing unnecessary.
131 131
         active_extruder = 0;
132 132
       }
133 133
     };

+ 1
- 1
Marlin/src/lcd/menu/menu_custom.cpp View File

@@ -38,7 +38,7 @@
38 38
 #endif
39 39
 
40 40
 void _lcd_user_gcode(PGM_P const cmd) {
41
-  enqueue_and_echo_commands_P(cmd);
41
+  queue.inject_P(cmd);
42 42
   #if ENABLED(USER_SCRIPT_AUDIBLE_FEEDBACK)
43 43
     ui.completion_feedback();
44 44
   #endif

+ 1
- 1
Marlin/src/lcd/menu/menu_delta_calibrate.cpp View File

@@ -73,7 +73,7 @@ void _man_probe_pt(const float &rx, const float &ry) {
73 73
   }
74 74
 
75 75
   void _lcd_delta_calibrate_home() {
76
-    enqueue_and_echo_commands_P(PSTR("G28"));
76
+    queue.inject_P(PSTR("G28"));
77 77
     ui.goto_screen(_lcd_calibrate_homing);
78 78
   }
79 79
 

+ 1
- 1
Marlin/src/lcd/menu/menu_filament.cpp View File

@@ -58,7 +58,7 @@ static void _change_filament_temp(const uint16_t temperature) {
58 58
   char cmd[11];
59 59
   sprintf_P(cmd, _change_filament_temp_command(), _change_filament_temp_extruder);
60 60
   thermalManager.setTargetHotend(temperature, _change_filament_temp_extruder);
61
-  lcd_enqueue_command(cmd);
61
+  lcd_enqueue_one_now(cmd);
62 62
 }
63 63
 inline void _lcd_change_filament_temp_1_func()    { _change_filament_temp(ui.preheat_hotend_temp[0]); }
64 64
 inline void _lcd_change_filament_temp_2_func()    { _change_filament_temp(ui.preheat_hotend_temp[1]); }

+ 1
- 1
Marlin/src/lcd/menu/menu_job_recovery.cpp View File

@@ -35,7 +35,7 @@
35 35
 
36 36
 static void lcd_power_loss_recovery_resume() {
37 37
   ui.return_to_status();
38
-  enqueue_and_echo_commands_P(PSTR("M1000"));
38
+  queue.inject_P(PSTR("M1000"));
39 39
 }
40 40
 
41 41
 static void lcd_power_loss_recovery_cancel() {

+ 35
- 35
Marlin/src/lcd/menu/menu_ubl.cpp View File

@@ -107,15 +107,15 @@ void lcd_z_offset_edit_setup(const float &initial) {
107 107
  * UBL Build Custom Mesh Command
108 108
  */
109 109
 void _lcd_ubl_build_custom_mesh() {
110
-  char UBL_LCD_GCODE[20];
111
-  enqueue_and_echo_commands_P(PSTR("G28"));
110
+  char ubl_lcd_gcode[20];
111
+  queue.inject_P(PSTR("G28"));
112 112
   #if HAS_HEATED_BED
113
-    sprintf_P(UBL_LCD_GCODE, PSTR("M190 S%i"), custom_bed_temp);
114
-    lcd_enqueue_command(UBL_LCD_GCODE);
113
+    sprintf_P(ubl_lcd_gcode, PSTR("M190 S%i"), custom_bed_temp);
114
+    lcd_enqueue_one_now(ubl_lcd_gcode);
115 115
   #endif
116
-  sprintf_P(UBL_LCD_GCODE, PSTR("M109 S%i"), custom_hotend_temp);
117
-  lcd_enqueue_command(UBL_LCD_GCODE);
118
-  enqueue_and_echo_commands_P(PSTR("G29 P1"));
116
+  sprintf_P(ubl_lcd_gcode, PSTR("M109 S%i"), custom_hotend_temp);
117
+  lcd_enqueue_one_now(ubl_lcd_gcode);
118
+  queue.inject_P(PSTR("G29 P1"));
119 119
 }
120 120
 
121 121
 /**
@@ -141,11 +141,11 @@ void _lcd_ubl_custom_mesh() {
141 141
  * UBL Adjust Mesh Height Command
142 142
  */
143 143
 void _lcd_ubl_adjust_height_cmd() {
144
-  char UBL_LCD_GCODE[16];
144
+  char ubl_lcd_gcode[16];
145 145
   const int ind = ubl_height_amount > 0 ? 9 : 10;
146
-  strcpy_P(UBL_LCD_GCODE, PSTR("G29 P6 C -"));
147
-  sprintf_P(&UBL_LCD_GCODE[ind], PSTR(".%i"), ABS(ubl_height_amount));
148
-  lcd_enqueue_command(UBL_LCD_GCODE);
146
+  strcpy_P(ubl_lcd_gcode, PSTR("G29 P6 C -"));
147
+  sprintf_P(&ubl_lcd_gcode[ind], PSTR(".%i"), ABS(ubl_height_amount));
148
+  lcd_enqueue_one_now(ubl_lcd_gcode);
149 149
 }
150 150
 
151 151
 /**
@@ -187,7 +187,7 @@ void _lcd_ubl_edit_mesh() {
187 187
  * UBL Validate Custom Mesh Command
188 188
  */
189 189
 void _lcd_ubl_validate_custom_mesh() {
190
-  char UBL_LCD_GCODE[24];
190
+  char ubl_lcd_gcode[24];
191 191
   const int temp =
192 192
     #if HAS_HEATED_BED
193 193
       custom_bed_temp
@@ -195,9 +195,9 @@ void _lcd_ubl_validate_custom_mesh() {
195 195
       0
196 196
     #endif
197 197
   ;
198
-  sprintf_P(UBL_LCD_GCODE, PSTR("G26 C B%i H%i P"), temp, custom_hotend_temp);
199
-  lcd_enqueue_commands_P(PSTR("G28"));
200
-  lcd_enqueue_command(UBL_LCD_GCODE);
198
+  sprintf_P(ubl_lcd_gcode, PSTR("G26 C B%i H%i P"), temp, custom_hotend_temp);
199
+  lcd_enqueue_one_now_P(PSTR("G28"));
200
+  lcd_enqueue_one_now(ubl_lcd_gcode);
201 201
 }
202 202
 
203 203
 /**
@@ -228,9 +228,9 @@ void _lcd_ubl_validate_mesh() {
228 228
  * UBL Grid Leveling Command
229 229
  */
230 230
 void _lcd_ubl_grid_level_cmd() {
231
-  char UBL_LCD_GCODE[12];
232
-  sprintf_P(UBL_LCD_GCODE, PSTR("G29 J%i"), side_points);
233
-  lcd_enqueue_command(UBL_LCD_GCODE);
231
+  char ubl_lcd_gcode[12];
232
+  sprintf_P(ubl_lcd_gcode, PSTR("G29 J%i"), side_points);
233
+  lcd_enqueue_one_now(ubl_lcd_gcode);
234 234
 }
235 235
 
236 236
 /**
@@ -269,9 +269,9 @@ void _lcd_ubl_mesh_leveling() {
269 269
  * UBL Fill-in Amount Mesh Command
270 270
  */
271 271
 void _lcd_ubl_fillin_amount_cmd() {
272
-  char UBL_LCD_GCODE[18];
273
-  sprintf_P(UBL_LCD_GCODE, PSTR("G29 P3 R C.%i"), ubl_fillin_amount);
274
-  lcd_enqueue_command(UBL_LCD_GCODE);
272
+  char ubl_lcd_gcode[18];
273
+  sprintf_P(ubl_lcd_gcode, PSTR("G29 P3 R C.%i"), ubl_fillin_amount);
274
+  lcd_enqueue_one_now(ubl_lcd_gcode);
275 275
 }
276 276
 
277 277
 /**
@@ -361,22 +361,22 @@ void _lcd_ubl_build_mesh() {
361 361
  * UBL Load Mesh Command
362 362
  */
363 363
 void _lcd_ubl_load_mesh_cmd() {
364
-  char UBL_LCD_GCODE[25];
365
-  sprintf_P(UBL_LCD_GCODE, PSTR("G29 L%i"), ubl_storage_slot);
366
-  lcd_enqueue_command(UBL_LCD_GCODE);
367
-  sprintf_P(UBL_LCD_GCODE, PSTR("M117 " MSG_MESH_LOADED), ubl_storage_slot);
368
-  lcd_enqueue_command(UBL_LCD_GCODE);
364
+  char ubl_lcd_gcode[25];
365
+  sprintf_P(ubl_lcd_gcode, PSTR("G29 L%i"), ubl_storage_slot);
366
+  lcd_enqueue_one_now(ubl_lcd_gcode);
367
+  sprintf_P(ubl_lcd_gcode, PSTR("M117 " MSG_MESH_LOADED), ubl_storage_slot);
368
+  lcd_enqueue_one_now(ubl_lcd_gcode);
369 369
 }
370 370
 
371 371
 /**
372 372
  * UBL Save Mesh Command
373 373
  */
374 374
 void _lcd_ubl_save_mesh_cmd() {
375
-  char UBL_LCD_GCODE[25];
376
-  sprintf_P(UBL_LCD_GCODE, PSTR("G29 S%i"), ubl_storage_slot);
377
-  lcd_enqueue_command(UBL_LCD_GCODE);
378
-  sprintf_P(UBL_LCD_GCODE, PSTR("M117 " MSG_MESH_SAVED), ubl_storage_slot);
379
-  lcd_enqueue_command(UBL_LCD_GCODE);
375
+  char ubl_lcd_gcode[25];
376
+  sprintf_P(ubl_lcd_gcode, PSTR("G29 S%i"), ubl_storage_slot);
377
+  lcd_enqueue_one_now(ubl_lcd_gcode);
378
+  sprintf_P(ubl_lcd_gcode, PSTR("M117 " MSG_MESH_SAVED), ubl_storage_slot);
379
+  lcd_enqueue_one_now(ubl_lcd_gcode);
380 380
 }
381 381
 
382 382
 /**
@@ -420,11 +420,11 @@ void _lcd_ubl_map_homing() {
420 420
  * UBL LCD "radar" map point editing
421 421
  */
422 422
 void _lcd_ubl_map_lcd_edit_cmd() {
423
-  char UBL_LCD_GCODE[50], str[10], str2[10];
423
+  char ubl_lcd_gcode[50], str[10], str2[10];
424 424
   dtostrf(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]), 0, 2, str);
425 425
   dtostrf(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]), 0, 2, str2);
426
-  snprintf_P(UBL_LCD_GCODE, sizeof(UBL_LCD_GCODE), PSTR("G29 P4 X%s Y%s R%i"), str, str2, n_edit_pts);
427
-  lcd_enqueue_command(UBL_LCD_GCODE);
426
+  snprintf_P(ubl_lcd_gcode, sizeof(ubl_lcd_gcode), PSTR("G29 P4 X%s Y%s R%i"), str, str2, n_edit_pts);
427
+  lcd_enqueue_one_now(ubl_lcd_gcode);
428 428
 }
429 429
 
430 430
 /**
@@ -529,7 +529,7 @@ void _lcd_ubl_output_map_lcd() {
529 529
 void _lcd_ubl_output_map_lcd_cmd() {
530 530
   if (!all_axes_known()) {
531 531
     set_all_unhomed();
532
-    enqueue_and_echo_commands_P(PSTR("G28"));
532
+    queue.inject_P(PSTR("G28"));
533 533
   }
534 534
   ui.goto_screen(_lcd_ubl_map_homing);
535 535
 }

+ 4
- 4
Marlin/src/lcd/ultralcd.cpp View File

@@ -441,7 +441,7 @@ bool MarlinUI::get_blink() {
441 441
 
442 442
         #endif // HAS_LCD_MENU
443 443
 
444
-        if (!homed && RRK(EN_KEYPAD_F1)) enqueue_and_echo_commands_P(PSTR("G28"));
444
+        if (!homed && RRK(EN_KEYPAD_F1)) queue.inject_P(PSTR("G28"));
445 445
         return true;
446 446
       }
447 447
 
@@ -1461,9 +1461,9 @@ void MarlinUI::update() {
1461 1461
       #if HAS_SPI_LCD
1462 1462
         lcd_pause_show_message(PAUSE_MESSAGE_PAUSING, PAUSE_MODE_PAUSE_PRINT);  // Show message immediately to let user know about pause in progress
1463 1463
       #endif
1464
-      enqueue_and_echo_commands_front_P(PSTR("M25 P\nM24"));
1464
+      queue.inject_P(PSTR("M25 P\nM24"));
1465 1465
     #elif ENABLED(SDSUPPORT)
1466
-      enqueue_and_echo_commands_P(PSTR("M25"));
1466
+      queue.inject_P(PSTR("M25"));
1467 1467
     #elif defined(ACTION_ON_PAUSE)
1468 1468
       host_action_pause();
1469 1469
     #endif
@@ -1475,7 +1475,7 @@ void MarlinUI::update() {
1475 1475
       wait_for_heatup = wait_for_user = false;
1476 1476
     #endif
1477 1477
     #if ENABLED(SDSUPPORT)
1478
-      if (card.isPaused()) enqueue_and_echo_commands_P(PSTR("M24"));
1478
+      if (card.isPaused()) queue.inject_P(PSTR("M24"));
1479 1479
     #endif
1480 1480
     #ifdef ACTION_ON_RESUME
1481 1481
       host_action_resume();

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

@@ -735,7 +735,7 @@ class Planner {
735 735
       if (cleaning_buffer_counter) {
736 736
         --cleaning_buffer_counter;
737 737
         #if ENABLED(SD_FINISHED_STEPPERRELEASE) && defined(SD_FINISHED_RELEASECOMMAND)
738
-          if (!cleaning_buffer_counter) enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND));
738
+          if (!cleaning_buffer_counter) queue.inject_P(PSTR(SD_FINISHED_RELEASECOMMAND));
739 739
         #endif
740 740
       }
741 741
     }

+ 3
- 3
Marlin/src/sd/cardreader.cpp View File

@@ -367,8 +367,8 @@ void CardReader::openAndPrintFile(const char *name) {
367 367
   char cmd[4 + strlen(name) + 1]; // Room for "M23 ", filename, and null
368 368
   sprintf_P(cmd, PSTR("M23 %s"), name);
369 369
   for (char *c = &cmd[4]; *c; c++) *c = tolower(*c);
370
-  enqueue_and_echo_command_now(cmd);
371
-  enqueue_and_echo_commands_P(PSTR("M24"));
370
+  queue.enqueue_one_now(cmd);
371
+  queue.inject_P(PSTR("M24"));
372 372
 }
373 373
 
374 374
 void CardReader::startFileprint() {
@@ -1001,7 +1001,7 @@ void CardReader::printingHasFinished() {
1001 1001
     #endif
1002 1002
 
1003 1003
     print_job_timer.stop();
1004
-    if (print_job_timer.duration() > 60) enqueue_and_echo_commands_P(PSTR("M31"));
1004
+    if (print_job_timer.duration() > 60) queue.inject_P(PSTR("M31"));
1005 1005
 
1006 1006
     #if ENABLED(SDCARD_SORT_ALPHA)
1007 1007
       presort();

Loading…
Cancel
Save