G-code queue singleton, front injection (#14236)
This commit is contained in:
parent
75aeb41ab7
commit
4c872a01f2
|
@ -369,7 +369,7 @@ void disable_all_steppers() {
|
||||||
#endif // HOST_ACTION_COMMANDS
|
#endif // HOST_ACTION_COMMANDS
|
||||||
|
|
||||||
if (run_runout_script)
|
if (run_runout_script)
|
||||||
enqueue_and_echo_commands_front_P(PSTR(FILAMENT_RUNOUT_SCRIPT));
|
queue.inject_P(PSTR(FILAMENT_RUNOUT_SCRIPT));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HAS_FILAMENT_SENSOR
|
#endif // HAS_FILAMENT_SENSOR
|
||||||
|
@ -425,7 +425,7 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
|
||||||
runout.run();
|
runout.run();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (commands_in_queue < BUFSIZE) get_available_commands();
|
if (queue.length < BUFSIZE) queue.get_available_commands();
|
||||||
|
|
||||||
const millis_t ms = millis();
|
const millis_t ms = millis();
|
||||||
|
|
||||||
|
@ -508,7 +508,7 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
|
||||||
const int HOME_DEBOUNCE_DELAY = 2500;
|
const int HOME_DEBOUNCE_DELAY = 2500;
|
||||||
if (!IS_SD_PRINTING() && !READ(HOME_PIN)) {
|
if (!IS_SD_PRINTING() && !READ(HOME_PIN)) {
|
||||||
if (!homeDebounceCount) {
|
if (!homeDebounceCount) {
|
||||||
enqueue_and_echo_commands_P(PSTR("G28"));
|
queue.inject_P(PSTR("G28"));
|
||||||
LCD_MESSAGEPGM(MSG_AUTO_HOME);
|
LCD_MESSAGEPGM(MSG_AUTO_HOME);
|
||||||
}
|
}
|
||||||
if (homeDebounceCount < HOME_DEBOUNCE_DELAY)
|
if (homeDebounceCount < HOME_DEBOUNCE_DELAY)
|
||||||
|
@ -797,7 +797,7 @@ void stop() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (IsRunning()) {
|
if (IsRunning()) {
|
||||||
Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart
|
queue.stop();
|
||||||
SERIAL_ERROR_MSG(MSG_ERR_STOPPED);
|
SERIAL_ERROR_MSG(MSG_ERR_STOPPED);
|
||||||
LCD_MESSAGEPGM(MSG_STOPPED);
|
LCD_MESSAGEPGM(MSG_STOPPED);
|
||||||
safe_delay(350); // allow enough time for messages to get out before stopping
|
safe_delay(350); // allow enough time for messages to get out before stopping
|
||||||
|
@ -926,8 +926,6 @@ void setup() {
|
||||||
SERIAL_ECHO_START();
|
SERIAL_ECHO_START();
|
||||||
SERIAL_ECHOLNPAIR(MSG_FREE_MEMORY, freeMemory(), MSG_PLANNER_BUFFER_BYTES, (int)sizeof(block_t) * (BLOCK_BUFFER_SIZE));
|
SERIAL_ECHOLNPAIR(MSG_FREE_MEMORY, freeMemory(), MSG_PLANNER_BUFFER_BYTES, (int)sizeof(block_t) * (BLOCK_BUFFER_SIZE));
|
||||||
|
|
||||||
queue_setup();
|
|
||||||
|
|
||||||
// UI must be initialized before EEPROM
|
// UI must be initialized before EEPROM
|
||||||
// (because EEPROM code calls the UI).
|
// (because EEPROM code calls the UI).
|
||||||
ui.init();
|
ui.init();
|
||||||
|
@ -1135,7 +1133,7 @@ void loop() {
|
||||||
true
|
true
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
clear_command_queue();
|
queue.clear();
|
||||||
quickstop_stepper();
|
quickstop_stepper();
|
||||||
print_job_timer.stop();
|
print_job_timer.stop();
|
||||||
#if DISABLED(SD_ABORT_NO_COOLDOWN)
|
#if DISABLED(SD_ABORT_NO_COOLDOWN)
|
||||||
|
@ -1147,14 +1145,14 @@ void loop() {
|
||||||
card.removeJobRecoveryFile();
|
card.removeJobRecoveryFile();
|
||||||
#endif
|
#endif
|
||||||
#ifdef EVENT_GCODE_SD_STOP
|
#ifdef EVENT_GCODE_SD_STOP
|
||||||
enqueue_and_echo_commands_P(PSTR(EVENT_GCODE_SD_STOP));
|
queue.inject_P(PSTR(EVENT_GCODE_SD_STOP));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SDSUPPORT
|
#endif // SDSUPPORT
|
||||||
|
|
||||||
if (commands_in_queue < BUFSIZE) get_available_commands();
|
if (queue.length < BUFSIZE) queue.get_available_commands();
|
||||||
advance_command_queue();
|
queue.advance();
|
||||||
endstops.event_handler();
|
endstops.event_handler();
|
||||||
idle();
|
idle();
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,9 @@
|
||||||
#define NANOSECONDS_PER_CYCLE (1000000000.0 / F_CPU)
|
#define NANOSECONDS_PER_CYCLE (1000000000.0 / F_CPU)
|
||||||
|
|
||||||
// Remove compiler warning on an unused variable
|
// Remove compiler warning on an unused variable
|
||||||
#define UNUSED(X) (void)X
|
#ifndef UNUSED
|
||||||
|
#define UNUSED(x) ((void)(x))
|
||||||
|
#endif
|
||||||
|
|
||||||
// Macros to make a string from a macro
|
// Macros to make a string from a macro
|
||||||
#define STRINGIFY_(M) #M
|
#define STRINGIFY_(M) #M
|
||||||
|
|
|
@ -142,7 +142,7 @@ void host_action(const char * const pstr, const bool eol) {
|
||||||
break;
|
break;
|
||||||
case PROMPT_PAUSE_RESUME:
|
case PROMPT_PAUSE_RESUME:
|
||||||
msg = PSTR("LCD_PAUSE_RESUME");
|
msg = PSTR("LCD_PAUSE_RESUME");
|
||||||
enqueue_and_echo_commands_P(PSTR("M24"));
|
queue.inject_P(PSTR("M24"));
|
||||||
break;
|
break;
|
||||||
case PROMPT_INFO:
|
case PROMPT_INFO:
|
||||||
msg = PSTR("GCODE_INFO");
|
msg = PSTR("GCODE_INFO");
|
||||||
|
|
|
@ -98,7 +98,7 @@ void PrintJobRecovery::check() {
|
||||||
if (card.isDetected()) {
|
if (card.isDetected()) {
|
||||||
load();
|
load();
|
||||||
if (!valid()) return purge();
|
if (!valid()) return purge();
|
||||||
enqueue_and_echo_commands_P(PSTR("M1000 S"));
|
queue.inject_P(PSTR("M1000 S"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,9 +209,9 @@ void PrintJobRecovery::save(const bool force/*=false*/, const bool save_queue/*=
|
||||||
info.relative_modes_e = gcode.axis_relative_modes[E_AXIS];
|
info.relative_modes_e = gcode.axis_relative_modes[E_AXIS];
|
||||||
|
|
||||||
// Commands in the queue
|
// Commands in the queue
|
||||||
info.commands_in_queue = save_queue ? commands_in_queue : 0;
|
info.queue_length = save_queue ? queue.length : 0;
|
||||||
info.cmd_queue_index_r = cmd_queue_index_r;
|
info.queue_index_r = queue.index_r;
|
||||||
COPY(info.command_queue, command_queue);
|
COPY(info.queue_buffer, queue.buffer);
|
||||||
|
|
||||||
// Elapsed print job time
|
// Elapsed print job time
|
||||||
info.print_job_elapsed = print_job_timer.duration();
|
info.print_job_elapsed = print_job_timer.duration();
|
||||||
|
@ -402,9 +402,9 @@ void PrintJobRecovery::resume() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Process commands from the old pending queue
|
// Process commands from the old pending queue
|
||||||
uint8_t c = info.commands_in_queue, r = info.cmd_queue_index_r;
|
uint8_t c = info.queue_length, r = info.queue_index_r;
|
||||||
for (; c--; r = (r + 1) % BUFSIZE)
|
for (; c--; r = (r + 1) % BUFSIZE)
|
||||||
gcode.process_subcommands_now(info.command_queue[r]);
|
gcode.process_subcommands_now(info.queue_buffer[r]);
|
||||||
|
|
||||||
// Resume the SD file from the last position
|
// Resume the SD file from the last position
|
||||||
char *fn = info.sd_filename;
|
char *fn = info.sd_filename;
|
||||||
|
@ -484,9 +484,9 @@ void PrintJobRecovery::resume() {
|
||||||
DEBUG_EOL();
|
DEBUG_EOL();
|
||||||
DEBUG_ECHOLNPAIR("retract_hop: ", info.retract_hop);
|
DEBUG_ECHOLNPAIR("retract_hop: ", info.retract_hop);
|
||||||
#endif
|
#endif
|
||||||
DEBUG_ECHOLNPAIR("cmd_queue_index_r: ", int(info.cmd_queue_index_r));
|
DEBUG_ECHOLNPAIR("queue_index_r: ", int(info.queue_index_r));
|
||||||
DEBUG_ECHOLNPAIR("commands_in_queue: ", int(info.commands_in_queue));
|
DEBUG_ECHOLNPAIR("queue_length: ", int(info.queue_length));
|
||||||
for (uint8_t i = 0; i < info.commands_in_queue; i++) DEBUG_ECHOLNPAIR("> ", info.command_queue[i]);
|
for (uint8_t i = 0; i < info.queue_length; i++) DEBUG_ECHOLNPAIR("> ", info.queue_buffer[i]);
|
||||||
DEBUG_ECHOLNPAIR("sd_filename: ", info.sd_filename);
|
DEBUG_ECHOLNPAIR("sd_filename: ", info.sd_filename);
|
||||||
DEBUG_ECHOLNPAIR("sdpos: ", info.sdpos);
|
DEBUG_ECHOLNPAIR("sdpos: ", info.sdpos);
|
||||||
DEBUG_ECHOLNPAIR("print_job_elapsed: ", info.print_job_elapsed);
|
DEBUG_ECHOLNPAIR("print_job_elapsed: ", info.print_job_elapsed);
|
||||||
|
|
|
@ -87,8 +87,8 @@ typedef struct {
|
||||||
bool relative_mode, relative_modes_e;
|
bool relative_mode, relative_modes_e;
|
||||||
|
|
||||||
// Command queue
|
// Command queue
|
||||||
uint8_t commands_in_queue, cmd_queue_index_r;
|
uint8_t queue_length, queue_index_r;
|
||||||
char command_queue[BUFSIZE][MAX_CMD_SIZE];
|
char queue_buffer[BUFSIZE][MAX_CMD_SIZE];
|
||||||
|
|
||||||
// SD Filename and position
|
// SD Filename and position
|
||||||
char sd_filename[MAXPATHNAMELENGTH];
|
char sd_filename[MAXPATHNAMELENGTH];
|
||||||
|
|
|
@ -650,7 +650,7 @@ void MMU2::set_filament_type(uint8_t index, uint8_t filamentType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::filament_runout() {
|
void MMU2::filament_runout() {
|
||||||
enqueue_and_echo_commands_P(PSTR(MMU2_FILAMENT_RUNOUT_SCRIPT));
|
queue.inject_P(PSTR(MMU2_FILAMENT_RUNOUT_SCRIPT));
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -966,7 +966,7 @@ G29_TYPE GcodeSuite::G29() {
|
||||||
#ifdef Z_PROBE_END_SCRIPT
|
#ifdef Z_PROBE_END_SCRIPT
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Z Probe End Script: ", Z_PROBE_END_SCRIPT);
|
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPAIR("Z Probe End Script: ", Z_PROBE_END_SCRIPT);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
enqueue_and_echo_commands_P(PSTR(Z_PROBE_END_SCRIPT));
|
queue.inject_P(PSTR(Z_PROBE_END_SCRIPT));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Auto Bed Leveling is complete! Enable if possible.
|
// Auto Bed Leveling is complete! Enable if possible.
|
||||||
|
|
|
@ -85,7 +85,7 @@ void GcodeSuite::G29() {
|
||||||
mbl.reset();
|
mbl.reset();
|
||||||
mbl_probe_index = 0;
|
mbl_probe_index = 0;
|
||||||
if (!ui.wait_for_bl_move) {
|
if (!ui.wait_for_bl_move) {
|
||||||
enqueue_and_echo_commands_P(PSTR("G28\nG29 S2"));
|
queue.inject_P(PSTR("G28\nG29 S2"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
state = MeshNext;
|
state = MeshNext;
|
||||||
|
|
|
@ -153,7 +153,7 @@ inline int32_t count_test_bytes(const char * const start_free_memory) {
|
||||||
SERIAL_CHAR('|'); // Point out non test bytes
|
SERIAL_CHAR('|'); // Point out non test bytes
|
||||||
for (uint8_t i = 0; i < 16; i++) {
|
for (uint8_t i = 0; i < 16; i++) {
|
||||||
char ccc = (char)start_free_memory[i]; // cast to char before automatically casting to char on assignment, in case the compiler is broken
|
char ccc = (char)start_free_memory[i]; // cast to char before automatically casting to char on assignment, in case the compiler is broken
|
||||||
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
|
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
|
||||||
if (!WITHIN(ccc, ' ', 0x7E)) ccc = ' ';
|
if (!WITHIN(ccc, ' ', 0x7E)) ccc = ' ';
|
||||||
}
|
}
|
||||||
else { // If not in the command buffer area, flag bytes that don't match the test byte
|
else { // If not in the command buffer area, flag bytes that don't match the test byte
|
||||||
|
|
|
@ -42,6 +42,5 @@ void GcodeSuite::M999() {
|
||||||
|
|
||||||
if (parser.boolval('S')) return;
|
if (parser.boolval('S')) return;
|
||||||
|
|
||||||
// gcode_LastN = Stopped_gcode_LastN;
|
queue.flush_and_request_resend();
|
||||||
flush_and_request_resend();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,7 +187,7 @@ void GcodeSuite::dwell(millis_t time) {
|
||||||
/**
|
/**
|
||||||
* Process the parsed command and dispatch it to its handler
|
* Process the parsed command and dispatch it to its handler
|
||||||
*/
|
*/
|
||||||
void GcodeSuite::process_parsed_command(const bool no_ok) {
|
void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||||
KEEPALIVE_STATE(IN_HANDLER);
|
KEEPALIVE_STATE(IN_HANDLER);
|
||||||
|
|
||||||
// Handle a known G, M, or T
|
// Handle a known G, M, or T
|
||||||
|
@ -798,7 +798,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok) {
|
||||||
|
|
||||||
KEEPALIVE_STATE(NOT_BUSY);
|
KEEPALIVE_STATE(NOT_BUSY);
|
||||||
|
|
||||||
if (!no_ok) ok_to_send();
|
if (!no_ok) queue.ok_to_send();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -806,16 +806,16 @@ void GcodeSuite::process_parsed_command(const bool no_ok) {
|
||||||
* This is called from the main loop()
|
* This is called from the main loop()
|
||||||
*/
|
*/
|
||||||
void GcodeSuite::process_next_command() {
|
void GcodeSuite::process_next_command() {
|
||||||
char * const current_command = command_queue[cmd_queue_index_r];
|
char * const current_command = queue.buffer[queue.index_r];
|
||||||
|
|
||||||
PORT_REDIRECT(command_queue_port[cmd_queue_index_r]);
|
PORT_REDIRECT(queue.port[queue.index_r]);
|
||||||
|
|
||||||
if (DEBUGGING(ECHO)) {
|
if (DEBUGGING(ECHO)) {
|
||||||
SERIAL_ECHO_START();
|
SERIAL_ECHO_START();
|
||||||
SERIAL_ECHOLN(current_command);
|
SERIAL_ECHOLN(current_command);
|
||||||
#if ENABLED(M100_FREE_MEMORY_DUMPER)
|
#if ENABLED(M100_FREE_MEMORY_DUMPER)
|
||||||
SERIAL_ECHOPAIR("slot:", cmd_queue_index_r);
|
SERIAL_ECHOPAIR("slot:", queue.index_r);
|
||||||
M100_dump_routine(PSTR(" Command Queue:"), (const char*)command_queue, (const char*)(command_queue) + sizeof(command_queue));
|
M100_dump_routine(PSTR(" Command Queue:"), queue.buffer, queue.buffer + sizeof(queue.buffer));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -315,7 +315,7 @@ public:
|
||||||
static void process_parsed_command(const bool no_ok=false);
|
static void process_parsed_command(const bool no_ok=false);
|
||||||
static void process_next_command();
|
static void process_next_command();
|
||||||
|
|
||||||
// Execute G-code as a macro, preserving parser state
|
// Execute G-code in-place, preserving current G-code parameters
|
||||||
static void process_subcommands_now_P(PGM_P pgcode);
|
static void process_subcommands_now_P(PGM_P pgcode);
|
||||||
static void process_subcommands_now(char * gcode);
|
static void process_subcommands_now(char * gcode);
|
||||||
|
|
||||||
|
|
|
@ -21,11 +21,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../gcode.h"
|
#include "../gcode.h"
|
||||||
#include "../queue.h" // for gcode_LastN
|
#include "../queue.h" // for last_N
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* M110: Set Current Line Number
|
* M110: Set Current Line Number
|
||||||
*/
|
*/
|
||||||
void GcodeSuite::M110() {
|
void GcodeSuite::M110() {
|
||||||
if (parser.seenval('N')) gcode_LastN = parser.value_long();
|
if (parser.seenval('N')) queue.last_N = parser.value_long();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
|
GCodeQueue queue;
|
||||||
|
|
||||||
#include "gcode.h"
|
#include "gcode.h"
|
||||||
|
|
||||||
#include "../lcd/ultralcd.h"
|
#include "../lcd/ultralcd.h"
|
||||||
|
@ -42,7 +44,7 @@
|
||||||
* sending commands to Marlin, and lines will be checked for sequentiality.
|
* sending commands to Marlin, and lines will be checked for sequentiality.
|
||||||
* M110 N<int> sets the current line number.
|
* M110 N<int> sets the current line number.
|
||||||
*/
|
*/
|
||||||
long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0;
|
long gcode_N, GCodeQueue::last_N, GCodeQueue::stopped_N = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GCode Command Queue
|
* GCode Command Queue
|
||||||
|
@ -53,17 +55,17 @@ long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0;
|
||||||
* the main loop. The gcode.process_next_command method parses the next
|
* the main loop. The gcode.process_next_command method parses the next
|
||||||
* command and hands off execution to individual handler functions.
|
* command and hands off execution to individual handler functions.
|
||||||
*/
|
*/
|
||||||
uint8_t commands_in_queue = 0, // Count of commands in the queue
|
uint8_t GCodeQueue::length = 0, // Count of commands in the queue
|
||||||
cmd_queue_index_r = 0, // Ring buffer read position
|
GCodeQueue::index_r = 0, // Ring buffer read position
|
||||||
cmd_queue_index_w = 0; // Ring buffer write position
|
GCodeQueue::index_w = 0; // Ring buffer write position
|
||||||
|
|
||||||
char command_queue[BUFSIZE][MAX_CMD_SIZE];
|
char GCodeQueue::buffer[BUFSIZE][MAX_CMD_SIZE];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The port that the command was received on
|
* The port that the command was received on
|
||||||
*/
|
*/
|
||||||
#if NUM_SERIAL > 1
|
#if NUM_SERIAL > 1
|
||||||
int16_t command_queue_port[BUFSIZE];
|
int16_t GCodeQueue::port[BUFSIZE];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,7 +84,7 @@ bool send_ok[BUFSIZE];
|
||||||
*/
|
*/
|
||||||
static PGM_P injected_commands_P = nullptr;
|
static PGM_P injected_commands_P = nullptr;
|
||||||
|
|
||||||
void queue_setup() {
|
GCodeQueue::GCodeQueue() {
|
||||||
// Send "ok" after commands by default
|
// Send "ok" after commands by default
|
||||||
for (uint8_t i = 0; i < COUNT(send_ok); i++) send_ok[i] = true;
|
for (uint8_t i = 0; i < COUNT(send_ok); i++) send_ok[i] = true;
|
||||||
}
|
}
|
||||||
|
@ -90,24 +92,24 @@ void queue_setup() {
|
||||||
/**
|
/**
|
||||||
* Clear the Marlin command queue
|
* Clear the Marlin command queue
|
||||||
*/
|
*/
|
||||||
void clear_command_queue() {
|
void GCodeQueue::clear() {
|
||||||
cmd_queue_index_r = cmd_queue_index_w = commands_in_queue = 0;
|
index_r = index_w = length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Once a new command is in the ring buffer, call this to commit it
|
* Once a new command is in the ring buffer, call this to commit it
|
||||||
*/
|
*/
|
||||||
inline void _commit_command(bool say_ok
|
void GCodeQueue::_commit_command(bool say_ok
|
||||||
#if NUM_SERIAL > 1
|
#if NUM_SERIAL > 1
|
||||||
, int16_t port = -1
|
, int16_t p/*=-1*/
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
send_ok[cmd_queue_index_w] = say_ok;
|
send_ok[index_w] = say_ok;
|
||||||
#if NUM_SERIAL > 1
|
#if NUM_SERIAL > 1
|
||||||
command_queue_port[cmd_queue_index_w] = port;
|
port[index_w] = p;
|
||||||
#endif
|
#endif
|
||||||
if (++cmd_queue_index_w >= BUFSIZE) cmd_queue_index_w = 0;
|
if (++index_w >= BUFSIZE) index_w = 0;
|
||||||
commands_in_queue++;
|
length++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -115,16 +117,16 @@ inline void _commit_command(bool say_ok
|
||||||
* Return true if the command was successfully added.
|
* Return true if the command was successfully added.
|
||||||
* Return false for a full buffer, or if the 'command' is a comment.
|
* Return false for a full buffer, or if the 'command' is a comment.
|
||||||
*/
|
*/
|
||||||
inline bool _enqueuecommand(const char* cmd, bool say_ok=false
|
bool GCodeQueue::_enqueue(const char* cmd, bool say_ok/*=false*/
|
||||||
#if NUM_SERIAL > 1
|
#if NUM_SERIAL > 1
|
||||||
, int16_t port = -1
|
, int16_t pn/*=-1*/
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
if (*cmd == ';' || commands_in_queue >= BUFSIZE) return false;
|
if (*cmd == ';' || length >= BUFSIZE) return false;
|
||||||
strcpy(command_queue[cmd_queue_index_w], cmd);
|
strcpy(buffer[index_w], cmd);
|
||||||
_commit_command(say_ok
|
_commit_command(say_ok
|
||||||
#if NUM_SERIAL > 1
|
#if NUM_SERIAL > 1
|
||||||
, port
|
, pn
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
|
@ -134,15 +136,15 @@ inline bool _enqueuecommand(const char* cmd, bool say_ok=false
|
||||||
* Enqueue with Serial Echo
|
* Enqueue with Serial Echo
|
||||||
* Return true if the command was consumed
|
* Return true if the command was consumed
|
||||||
*/
|
*/
|
||||||
bool enqueue_and_echo_command(const char* cmd) {
|
bool GCodeQueue::enqueue_one(const char* cmd) {
|
||||||
|
|
||||||
//SERIAL_ECHOPGM("enqueue_and_echo_command(\"");
|
//SERIAL_ECHOPGM("enqueue_one(\"");
|
||||||
//SERIAL_ECHO(cmd);
|
//SERIAL_ECHO(cmd);
|
||||||
//SERIAL_ECHOPGM("\") \n");
|
//SERIAL_ECHOPGM("\") \n");
|
||||||
|
|
||||||
if (*cmd == 0 || *cmd == '\n' || *cmd == '\r') return true;
|
if (*cmd == 0 || *cmd == '\n' || *cmd == '\r') return true;
|
||||||
|
|
||||||
if (_enqueuecommand(cmd)) {
|
if (_enqueue(cmd)) {
|
||||||
SERIAL_ECHO_START();
|
SERIAL_ECHO_START();
|
||||||
SERIAL_ECHOLNPAIR(MSG_ENQUEUEING, cmd, "\"");
|
SERIAL_ECHOLNPAIR(MSG_ENQUEUEING, cmd, "\"");
|
||||||
return true;
|
return true;
|
||||||
|
@ -150,104 +152,67 @@ bool enqueue_and_echo_command(const char* cmd) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAS_QUEUE_FRONT
|
|
||||||
|
|
||||||
bool early_cmd; // = false
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Insert a high Priority command from RAM into the main command buffer.
|
|
||||||
* Return true if the command was consumed
|
|
||||||
* Return false for a full buffer, or if the 'command' is a comment.
|
|
||||||
*/
|
|
||||||
inline bool _enqueuecommand_front(const char* cmd) {
|
|
||||||
if (*cmd == 0 || *cmd == '\n' || *cmd == '\r') return true;
|
|
||||||
if (*cmd == ';' || commands_in_queue >= BUFSIZE) return false;
|
|
||||||
if (cmd_queue_index_r == 0) cmd_queue_index_r = BUFSIZE;
|
|
||||||
--cmd_queue_index_r;
|
|
||||||
strcpy(command_queue[cmd_queue_index_r], cmd);
|
|
||||||
send_ok[cmd_queue_index_r] = false;
|
|
||||||
#if NUM_SERIAL > 1
|
|
||||||
command_queue_port[cmd_queue_index_r] = -1;
|
|
||||||
#endif
|
|
||||||
commands_in_queue++;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Insert in the front of queue, one or many commands to run from program memory.
|
|
||||||
* Aborts the current queue, if any.
|
|
||||||
* Note: drain_injected_commands_P() must be called repeatedly to drain the commands afterwards
|
|
||||||
*/
|
|
||||||
void enqueue_and_echo_commands_front_P(PGM_P const pgcode) {
|
|
||||||
early_cmd = true;
|
|
||||||
enqueue_and_echo_commands_P(pgcode);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inject the next "immediate" command, when possible, onto the front of the queue.
|
* Process the next "immediate" command.
|
||||||
* Return true if any immediate commands remain to inject.
|
|
||||||
* Do not inject a comment or use leading space!.
|
|
||||||
*/
|
*/
|
||||||
static bool drain_injected_commands_P() {
|
bool GCodeQueue::process_injected_command() {
|
||||||
while (injected_commands_P != nullptr) {
|
if (injected_commands_P == nullptr) return false;
|
||||||
size_t i = 0;
|
|
||||||
char c, cmd[60];
|
|
||||||
strncpy_P(cmd, injected_commands_P, sizeof(cmd) - 1);
|
|
||||||
cmd[sizeof(cmd) - 1] = '\0';
|
|
||||||
while ((c = cmd[i]) && c != '\n') i++; // find the end of this gcode command
|
|
||||||
cmd[i] = '\0';
|
|
||||||
|
|
||||||
if (
|
char c;
|
||||||
#if HAS_QUEUE_FRONT
|
size_t i = 0;
|
||||||
early_cmd ? _enqueuecommand_front(cmd) :
|
while ((c = pgm_read_byte(&injected_commands_P[i])) && c != '\n') i++;
|
||||||
#endif
|
if (!i) return false;
|
||||||
enqueue_and_echo_command(cmd)
|
|
||||||
) {
|
char cmd[i + 1];
|
||||||
injected_commands_P = c ? injected_commands_P + i + 1 : nullptr; // next command or done
|
memcpy_P(cmd, injected_commands_P, i);
|
||||||
#if HAS_QUEUE_FRONT
|
cmd[i] = '\0';
|
||||||
if (!c) early_cmd = false;
|
|
||||||
#endif
|
injected_commands_P = c ? injected_commands_P + i + 1 : nullptr;
|
||||||
}
|
|
||||||
else
|
parser.parse(cmd);
|
||||||
return true; // buffer is full (or command is comment);
|
PORT_REDIRECT(SERIAL_PORT);
|
||||||
}
|
gcode.process_parsed_command();
|
||||||
return false; // return whether any more remain
|
PORT_RESTORE();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enqueue one or many commands to run from program memory.
|
* Enqueue one or many commands to run from program memory.
|
||||||
|
* Do not inject a comment or use leading spaces!
|
||||||
* Aborts the current queue, if any.
|
* Aborts the current queue, if any.
|
||||||
* Note: drain_injected_commands_P() must be called repeatedly to drain the commands afterwards
|
* Note: process_injected_command() will be called to drain any commands afterwards
|
||||||
*/
|
*/
|
||||||
void enqueue_and_echo_commands_P(PGM_P const pgcode) {
|
void GCodeQueue::inject_P(PGM_P const pgcode) {
|
||||||
#if HAS_QUEUE_FRONT
|
|
||||||
early_cmd = false;
|
|
||||||
#endif
|
|
||||||
injected_commands_P = pgcode;
|
injected_commands_P = pgcode;
|
||||||
(void)drain_injected_commands_P(); // first command executed asap (when possible)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAS_QUEUE_NOW
|
/**
|
||||||
/**
|
* Enqueue and return only when commands are actually enqueued.
|
||||||
* Enqueue and return only when commands are actually enqueued.
|
* Never call this from a G-code handler!
|
||||||
* Never call this from a G-code handler!
|
*/
|
||||||
*/
|
void GCodeQueue::enqueue_one_now(const char* cmd) {
|
||||||
void enqueue_and_echo_command_now(const char* cmd) {
|
while (!enqueue_one(cmd)) idle();
|
||||||
while (!enqueue_and_echo_command(cmd)) idle();
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enqueue from program memory and return only when commands are actually enqueued
|
||||||
|
* Never call this from a G-code handler!
|
||||||
|
*/
|
||||||
|
void GCodeQueue::enqueue_now_P(PGM_P const pgcode) {
|
||||||
|
size_t i = 0;
|
||||||
|
PGM_P p = pgcode;
|
||||||
|
for (;;) {
|
||||||
|
char c;
|
||||||
|
while ((c = p[i]) && c != '\n') i++;
|
||||||
|
char cmd[i + 1];
|
||||||
|
memcpy_P(cmd, p, i);
|
||||||
|
cmd[i] = '\0';
|
||||||
|
enqueue_one_now(cmd);
|
||||||
|
if (!c) break;
|
||||||
|
p += i + 1;
|
||||||
}
|
}
|
||||||
#if HAS_LCD_QUEUE_NOW
|
}
|
||||||
/**
|
|
||||||
* Enqueue from program memory and return only when commands are actually enqueued
|
|
||||||
* Never call this from a G-code handler!
|
|
||||||
*/
|
|
||||||
void enqueue_and_echo_commands_now_P(PGM_P const pgcode) {
|
|
||||||
enqueue_and_echo_commands_P(pgcode);
|
|
||||||
while (drain_injected_commands_P()) idle();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send an "ok" message to the host, indicating
|
* Send an "ok" message to the host, indicating
|
||||||
|
@ -258,16 +223,16 @@ void enqueue_and_echo_commands_P(PGM_P const pgcode) {
|
||||||
* P<int> Planner space remaining
|
* P<int> Planner space remaining
|
||||||
* B<int> Block queue space remaining
|
* B<int> Block queue space remaining
|
||||||
*/
|
*/
|
||||||
void ok_to_send() {
|
void GCodeQueue::ok_to_send() {
|
||||||
#if NUM_SERIAL > 1
|
#if NUM_SERIAL > 1
|
||||||
const int16_t port = command_queue_port[cmd_queue_index_r];
|
const int16_t p = port[index_r];
|
||||||
if (port < 0) return;
|
if (p < 0) return;
|
||||||
PORT_REDIRECT(port);
|
PORT_REDIRECT(p);
|
||||||
#endif
|
#endif
|
||||||
if (!send_ok[cmd_queue_index_r]) return;
|
if (!send_ok[index_r]) return;
|
||||||
SERIAL_ECHOPGM(MSG_OK);
|
SERIAL_ECHOPGM(MSG_OK);
|
||||||
#if ENABLED(ADVANCED_OK)
|
#if ENABLED(ADVANCED_OK)
|
||||||
char* p = command_queue[cmd_queue_index_r];
|
char* p = buffer[index_r];
|
||||||
if (*p == 'N') {
|
if (*p == 'N') {
|
||||||
SERIAL_ECHO(' ');
|
SERIAL_ECHO(' ');
|
||||||
SERIAL_ECHO(*p++);
|
SERIAL_ECHO(*p++);
|
||||||
|
@ -275,7 +240,7 @@ void ok_to_send() {
|
||||||
SERIAL_ECHO(*p++);
|
SERIAL_ECHO(*p++);
|
||||||
}
|
}
|
||||||
SERIAL_ECHOPGM(" P"); SERIAL_ECHO(int(BLOCK_BUFFER_SIZE - planner.movesplanned() - 1));
|
SERIAL_ECHOPGM(" P"); SERIAL_ECHO(int(BLOCK_BUFFER_SIZE - planner.movesplanned() - 1));
|
||||||
SERIAL_ECHOPGM(" B"); SERIAL_ECHO(BUFSIZE - commands_in_queue);
|
SERIAL_ECHOPGM(" B"); SERIAL_ECHO(BUFSIZE - length);
|
||||||
#endif
|
#endif
|
||||||
SERIAL_EOL();
|
SERIAL_EOL();
|
||||||
}
|
}
|
||||||
|
@ -284,15 +249,15 @@ void ok_to_send() {
|
||||||
* Send a "Resend: nnn" message to the host to
|
* Send a "Resend: nnn" message to the host to
|
||||||
* indicate that a command needs to be re-sent.
|
* indicate that a command needs to be re-sent.
|
||||||
*/
|
*/
|
||||||
void flush_and_request_resend() {
|
void GCodeQueue::flush_and_request_resend() {
|
||||||
#if NUM_SERIAL > 1
|
#if NUM_SERIAL > 1
|
||||||
const int16_t port = command_queue_port[cmd_queue_index_r];
|
const int16_t p = port[index_r];
|
||||||
if (port < 0) return;
|
if (p < 0) return;
|
||||||
PORT_REDIRECT(port);
|
PORT_REDIRECT(p);
|
||||||
#endif
|
#endif
|
||||||
SERIAL_FLUSH();
|
SERIAL_FLUSH();
|
||||||
SERIAL_ECHOPGM(MSG_RESEND);
|
SERIAL_ECHOPGM(MSG_RESEND);
|
||||||
SERIAL_ECHOLN(gcode_LastN + 1);
|
SERIAL_ECHOLN(last_N + 1);
|
||||||
ok_to_send();
|
ok_to_send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,16 +280,6 @@ inline int read_serial(const uint8_t index) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gcode_line_error(PGM_P const err, const int8_t port) {
|
|
||||||
PORT_REDIRECT(port);
|
|
||||||
SERIAL_ERROR_START();
|
|
||||||
serialprintPGM(err);
|
|
||||||
SERIAL_ECHOLN(gcode_LastN);
|
|
||||||
while (read_serial(port) != -1); // clear out the RX buffer
|
|
||||||
flush_and_request_resend();
|
|
||||||
serial_count[port] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if ENABLED(BINARY_FILE_TRANSFER)
|
#if ENABLED(BINARY_FILE_TRANSFER)
|
||||||
|
|
||||||
inline bool serial_data_available(const uint8_t index) {
|
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) {
|
||||||
|
|
||||||
#endif // BINARY_FILE_TRANSFER
|
#endif // BINARY_FILE_TRANSFER
|
||||||
|
|
||||||
|
void GCodeQueue::gcode_line_error(PGM_P const err, const int8_t port) {
|
||||||
|
PORT_REDIRECT(port);
|
||||||
|
SERIAL_ERROR_START();
|
||||||
|
serialprintPGM(err);
|
||||||
|
SERIAL_ECHOLN(last_N);
|
||||||
|
while (read_serial(port) != -1); // clear out the RX buffer
|
||||||
|
flush_and_request_resend();
|
||||||
|
serial_count[port] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
FORCE_INLINE bool is_M29(const char * const cmd) { // matches "M29" & "M29 ", but not "M290", etc
|
FORCE_INLINE bool is_M29(const char * const cmd) { // matches "M29" & "M29 ", but not "M290", etc
|
||||||
const char * const m29 = strstr_P(cmd, PSTR("M29"));
|
const char * const m29 = strstr_P(cmd, PSTR("M29"));
|
||||||
return m29 && !NUMERIC(m29[3]);
|
return m29 && !NUMERIC(m29[3]);
|
||||||
|
@ -585,7 +550,7 @@ FORCE_INLINE bool is_M29(const char * const cmd) { // matches "M29" & "M29 ", b
|
||||||
* Exit when the buffer is full or when no more characters are
|
* Exit when the buffer is full or when no more characters are
|
||||||
* left on the serial port.
|
* left on the serial port.
|
||||||
*/
|
*/
|
||||||
inline void get_serial_commands() {
|
void GCodeQueue::get_serial_commands() {
|
||||||
static char serial_line_buffer[NUM_SERIAL][MAX_CMD_SIZE];
|
static char serial_line_buffer[NUM_SERIAL][MAX_CMD_SIZE];
|
||||||
static bool serial_comment_mode[NUM_SERIAL] = { false }
|
static bool serial_comment_mode[NUM_SERIAL] = { false }
|
||||||
#if ENABLED(PAREN_COMMENTS)
|
#if ENABLED(PAREN_COMMENTS)
|
||||||
|
@ -610,7 +575,7 @@ inline void get_serial_commands() {
|
||||||
#if NO_TIMEOUTS > 0
|
#if NO_TIMEOUTS > 0
|
||||||
static millis_t last_command_time = 0;
|
static millis_t last_command_time = 0;
|
||||||
const millis_t ms = millis();
|
const millis_t ms = millis();
|
||||||
if (commands_in_queue == 0 && !serial_data_available() && ELAPSED(ms, last_command_time + NO_TIMEOUTS)) {
|
if (length == 0 && !serial_data_available() && ELAPSED(ms, last_command_time + NO_TIMEOUTS)) {
|
||||||
SERIAL_ECHOLNPGM(MSG_WAIT);
|
SERIAL_ECHOLNPGM(MSG_WAIT);
|
||||||
last_command_time = ms;
|
last_command_time = ms;
|
||||||
}
|
}
|
||||||
|
@ -619,7 +584,7 @@ inline void get_serial_commands() {
|
||||||
/**
|
/**
|
||||||
* Loop while serial characters are incoming and the queue is not full
|
* Loop while serial characters are incoming and the queue is not full
|
||||||
*/
|
*/
|
||||||
while (commands_in_queue < BUFSIZE && serial_data_available()) {
|
while (length < BUFSIZE && serial_data_available()) {
|
||||||
for (uint8_t i = 0; i < NUM_SERIAL; ++i) {
|
for (uint8_t i = 0; i < NUM_SERIAL; ++i) {
|
||||||
int c;
|
int c;
|
||||||
if ((c = read_serial(i)) < 0) continue;
|
if ((c = read_serial(i)) < 0) continue;
|
||||||
|
@ -659,7 +624,7 @@ inline void get_serial_commands() {
|
||||||
|
|
||||||
gcode_N = strtol(npos + 1, nullptr, 10);
|
gcode_N = strtol(npos + 1, nullptr, 10);
|
||||||
|
|
||||||
if (gcode_N != gcode_LastN + 1 && !M110)
|
if (gcode_N != last_N + 1 && !M110)
|
||||||
return gcode_line_error(PSTR(MSG_ERR_LINE_NO), i);
|
return gcode_line_error(PSTR(MSG_ERR_LINE_NO), i);
|
||||||
|
|
||||||
char *apos = strrchr(command, '*');
|
char *apos = strrchr(command, '*');
|
||||||
|
@ -672,7 +637,7 @@ inline void get_serial_commands() {
|
||||||
else
|
else
|
||||||
return gcode_line_error(PSTR(MSG_ERR_NO_CHECKSUM), i);
|
return gcode_line_error(PSTR(MSG_ERR_NO_CHECKSUM), i);
|
||||||
|
|
||||||
gcode_LastN = gcode_N;
|
last_N = gcode_N;
|
||||||
}
|
}
|
||||||
#if ENABLED(SDSUPPORT)
|
#if ENABLED(SDSUPPORT)
|
||||||
// Pronterface "M29" and "M29 " has no line number
|
// Pronterface "M29" and "M29 " has no line number
|
||||||
|
@ -718,7 +683,7 @@ inline void get_serial_commands() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Add the command to the queue
|
// Add the command to the queue
|
||||||
_enqueuecommand(serial_line_buffer[i], true
|
_enqueue(serial_line_buffer[i], true
|
||||||
#if NUM_SERIAL > 1
|
#if NUM_SERIAL > 1
|
||||||
, i
|
, i
|
||||||
#endif
|
#endif
|
||||||
|
@ -760,7 +725,7 @@ inline void get_serial_commands() {
|
||||||
* or until the end of the file is reached. The special character '#'
|
* or until the end of the file is reached. The special character '#'
|
||||||
* can also interrupt buffering.
|
* can also interrupt buffering.
|
||||||
*/
|
*/
|
||||||
inline void get_sdcard_commands() {
|
inline void GCodeQueue::get_sdcard_commands() {
|
||||||
static bool stop_buffering = false,
|
static bool stop_buffering = false,
|
||||||
sd_comment_mode = false
|
sd_comment_mode = false
|
||||||
#if ENABLED(PAREN_COMMENTS)
|
#if ENABLED(PAREN_COMMENTS)
|
||||||
|
@ -777,11 +742,11 @@ inline void get_serial_commands() {
|
||||||
* due to checksums, however, no checksums are used in SD printing.
|
* due to checksums, however, no checksums are used in SD printing.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (commands_in_queue == 0) stop_buffering = false;
|
if (length == 0) stop_buffering = false;
|
||||||
|
|
||||||
uint16_t sd_count = 0;
|
uint16_t sd_count = 0;
|
||||||
bool card_eof = card.eof();
|
bool card_eof = card.eof();
|
||||||
while (commands_in_queue < BUFSIZE && !card_eof && !stop_buffering) {
|
while (length < BUFSIZE && !card_eof && !stop_buffering) {
|
||||||
const int16_t n = card.get();
|
const int16_t n = card.get();
|
||||||
char sd_char = (char)n;
|
char sd_char = (char)n;
|
||||||
card_eof = card.eof();
|
card_eof = card.eof();
|
||||||
|
@ -804,7 +769,7 @@ inline void get_serial_commands() {
|
||||||
#if ENABLED(PRINTER_EVENT_LEDS)
|
#if ENABLED(PRINTER_EVENT_LEDS)
|
||||||
printerEventLEDs.onPrintCompleted();
|
printerEventLEDs.onPrintCompleted();
|
||||||
#if HAS_RESUME_CONTINUE
|
#if HAS_RESUME_CONTINUE
|
||||||
enqueue_and_echo_commands_P(PSTR("M0 S"
|
inject_P(PSTR("M0 S"
|
||||||
#if HAS_LCD_MENU
|
#if HAS_LCD_MENU
|
||||||
"1800"
|
"1800"
|
||||||
#else
|
#else
|
||||||
|
@ -828,7 +793,7 @@ inline void get_serial_commands() {
|
||||||
// Skip empty lines and comments
|
// Skip empty lines and comments
|
||||||
if (!sd_count) { thermalManager.manage_heater(); continue; }
|
if (!sd_count) { thermalManager.manage_heater(); continue; }
|
||||||
|
|
||||||
command_queue[cmd_queue_index_w][sd_count] = '\0'; // terminate string
|
buffer[index_w][sd_count] = '\0'; // terminate string
|
||||||
sd_count = 0; // clear sd line buffer
|
sd_count = 0; // clear sd line buffer
|
||||||
|
|
||||||
_commit_command(false);
|
_commit_command(false);
|
||||||
|
@ -849,7 +814,7 @@ inline void get_serial_commands() {
|
||||||
#if ENABLED(PAREN_COMMENTS)
|
#if ENABLED(PAREN_COMMENTS)
|
||||||
&& ! sd_comment_paren_mode
|
&& ! sd_comment_paren_mode
|
||||||
#endif
|
#endif
|
||||||
) command_queue[cmd_queue_index_w][sd_count++] = sd_char;
|
) buffer[index_w][sd_count++] = sd_char;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -862,10 +827,7 @@ inline void get_serial_commands() {
|
||||||
* - The active serial input (usually USB)
|
* - The active serial input (usually USB)
|
||||||
* - The SD card file being actively printed
|
* - The SD card file being actively printed
|
||||||
*/
|
*/
|
||||||
void get_available_commands() {
|
void GCodeQueue::get_available_commands() {
|
||||||
|
|
||||||
// if any immediate commands remain, don't get other commands yet
|
|
||||||
if (drain_injected_commands_P()) return;
|
|
||||||
|
|
||||||
get_serial_commands();
|
get_serial_commands();
|
||||||
|
|
||||||
|
@ -877,14 +839,18 @@ void get_available_commands() {
|
||||||
/**
|
/**
|
||||||
* Get the next command in the queue, optionally log it to SD, then dispatch it
|
* Get the next command in the queue, optionally log it to SD, then dispatch it
|
||||||
*/
|
*/
|
||||||
void advance_command_queue() {
|
void GCodeQueue::advance() {
|
||||||
|
|
||||||
if (!commands_in_queue) return;
|
// Process immediate commands
|
||||||
|
if (process_injected_command()) return;
|
||||||
|
|
||||||
|
// Return if the G-code buffer is empty
|
||||||
|
if (!length) return;
|
||||||
|
|
||||||
#if ENABLED(SDSUPPORT)
|
#if ENABLED(SDSUPPORT)
|
||||||
|
|
||||||
if (card.flag.saving) {
|
if (card.flag.saving) {
|
||||||
char* command = command_queue[cmd_queue_index_r];
|
char* command = buffer[index_r];
|
||||||
if (is_M29(command)) {
|
if (is_M29(command)) {
|
||||||
// M29 closes the file
|
// M29 closes the file
|
||||||
card.closefile();
|
card.closefile();
|
||||||
|
@ -921,9 +887,9 @@ void advance_command_queue() {
|
||||||
#endif // SDSUPPORT
|
#endif // SDSUPPORT
|
||||||
|
|
||||||
// The queue may be reset by a command handler or by code invoked by idle() within a handler
|
// The queue may be reset by a command handler or by code invoked by idle() within a handler
|
||||||
if (commands_in_queue) {
|
if (length) {
|
||||||
--commands_in_queue;
|
--length;
|
||||||
if (++cmd_queue_index_r >= BUFSIZE) cmd_queue_index_r = 0;
|
if (++index_r >= BUFSIZE) index_r = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,109 +28,125 @@
|
||||||
|
|
||||||
#include "../inc/MarlinConfig.h"
|
#include "../inc/MarlinConfig.h"
|
||||||
|
|
||||||
/**
|
class GCodeQueue {
|
||||||
* GCode line number handling. Hosts may include line numbers when sending
|
public:
|
||||||
* commands to Marlin, and lines will be checked for sequentiality.
|
|
||||||
* M110 N<int> sets the current line number.
|
|
||||||
*/
|
|
||||||
extern long gcode_LastN, Stopped_gcode_LastN;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GCode Command Queue
|
|
||||||
* A simple ring buffer of BUFSIZE command strings.
|
|
||||||
*
|
|
||||||
* Commands are copied into this buffer by the command injectors
|
|
||||||
* (immediate, serial, sd card) and they are processed sequentially by
|
|
||||||
* the main loop. The gcode.process_next_command method parses the next
|
|
||||||
* command and hands off execution to individual handler functions.
|
|
||||||
*/
|
|
||||||
extern uint8_t commands_in_queue, // Count of commands in the queue
|
|
||||||
cmd_queue_index_r; // Ring buffer read position
|
|
||||||
|
|
||||||
extern char command_queue[BUFSIZE][MAX_CMD_SIZE];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The port that the command was received on
|
|
||||||
*/
|
|
||||||
#if NUM_SERIAL > 1
|
|
||||||
extern int16_t command_queue_port[BUFSIZE];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialization of queue for setup()
|
|
||||||
*/
|
|
||||||
void queue_setup();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear the Marlin command queue
|
|
||||||
*/
|
|
||||||
void clear_command_queue();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear the serial line and request a resend of
|
|
||||||
* the next expected line number.
|
|
||||||
*/
|
|
||||||
void flush_and_request_resend();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send an "ok" message to the host, indicating
|
|
||||||
* that a command was successfully processed.
|
|
||||||
*
|
|
||||||
* If ADVANCED_OK is enabled also include:
|
|
||||||
* N<int> Line number of the command, if any
|
|
||||||
* P<int> Planner space remaining
|
|
||||||
* B<int> Block queue space remaining
|
|
||||||
*/
|
|
||||||
void ok_to_send();
|
|
||||||
|
|
||||||
#if ENABLED(ADVANCED_PAUSE_FEATURE)
|
|
||||||
/**
|
/**
|
||||||
* Insert in the front of queue, one or many commands to run from program memory.
|
* GCode line number handling. Hosts may include line numbers when sending
|
||||||
* Aborts the current queue, if any.
|
* commands to Marlin, and lines will be checked for sequentiality.
|
||||||
* Note: drain_injected_commands_P() must be called repeatedly to drain the commands afterwards
|
* M110 N<int> sets the current line number.
|
||||||
*/
|
*/
|
||||||
void enqueue_and_echo_commands_front_P(PGM_P const pgcode);
|
static long last_N, stopped_N;
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
static inline void stop() { stopped_N = last_N; }
|
||||||
* Enqueue one or many commands to run from program memory.
|
|
||||||
* Aborts the current queue, if any.
|
|
||||||
* Note: drain_injected_commands_P() must be called repeatedly to drain the commands afterwards
|
|
||||||
*/
|
|
||||||
void enqueue_and_echo_commands_P(PGM_P const pgcode);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enqueue with Serial Echo
|
* GCode Command Queue
|
||||||
* Return true on success
|
* A simple ring buffer of BUFSIZE command strings.
|
||||||
*/
|
*
|
||||||
bool enqueue_and_echo_command(const char* cmd);
|
* Commands are copied into this buffer by the command injectors
|
||||||
|
* (immediate, serial, sd card) and they are processed sequentially by
|
||||||
|
* the main loop. The gcode.process_next_command method parses the next
|
||||||
|
* command and hands off execution to individual handler functions.
|
||||||
|
*/
|
||||||
|
static uint8_t length, // Count of commands in the queue
|
||||||
|
index_r; // Ring buffer read position
|
||||||
|
|
||||||
#define HAS_LCD_QUEUE_NOW (ENABLED(MALYAN_LCD) || (HAS_LCD_MENU && ANY(AUTO_BED_LEVELING_UBL, PID_AUTOTUNE_MENU, ADVANCED_PAUSE_FEATURE)))
|
static char buffer[BUFSIZE][MAX_CMD_SIZE];
|
||||||
#define HAS_QUEUE_NOW (ENABLED(SDSUPPORT) || HAS_LCD_QUEUE_NOW)
|
|
||||||
#define HAS_QUEUE_FRONT ENABLED(ADVANCED_PAUSE_FEATURE)
|
/*
|
||||||
|
* The port that the command was received on
|
||||||
|
*/
|
||||||
|
#if NUM_SERIAL > 1
|
||||||
|
static int16_t port[BUFSIZE];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GCodeQueue();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the Marlin command queue
|
||||||
|
*/
|
||||||
|
static void clear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enqueue one or many commands to run from program memory.
|
||||||
|
* Aborts the current queue, if any.
|
||||||
|
* Note: process_injected_command() will process them.
|
||||||
|
*/
|
||||||
|
static void inject_P(PGM_P const pgcode);
|
||||||
|
|
||||||
#if HAS_QUEUE_NOW
|
|
||||||
/**
|
/**
|
||||||
* Enqueue and return only when commands are actually enqueued
|
* Enqueue and return only when commands are actually enqueued
|
||||||
*/
|
*/
|
||||||
void enqueue_and_echo_command_now(const char* cmd);
|
static void enqueue_one_now(const char* cmd);
|
||||||
#if HAS_LCD_QUEUE_NOW
|
|
||||||
/**
|
/**
|
||||||
* Enqueue from program memory and return only when commands are actually enqueued
|
* Enqueue from program memory and return only when commands are actually enqueued
|
||||||
*/
|
*/
|
||||||
void enqueue_and_echo_commands_now_P(PGM_P const cmd);
|
static void enqueue_now_P(PGM_P const cmd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the next command in the queue, optionally log it to SD, then dispatch it
|
||||||
|
*/
|
||||||
|
static void advance();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add to the circular command queue the next command from:
|
||||||
|
* - The command-injection queue (injected_commands_P)
|
||||||
|
* - The active serial input (usually USB)
|
||||||
|
* - The SD card file being actively printed
|
||||||
|
*/
|
||||||
|
static void get_available_commands();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send an "ok" message to the host, indicating
|
||||||
|
* that a command was successfully processed.
|
||||||
|
*
|
||||||
|
* If ADVANCED_OK is enabled also include:
|
||||||
|
* N<int> Line number of the command, if any
|
||||||
|
* P<int> Planner space remaining
|
||||||
|
* B<int> Block queue space remaining
|
||||||
|
*/
|
||||||
|
static void ok_to_send();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the serial line and request a resend of
|
||||||
|
* the next expected line number.
|
||||||
|
*/
|
||||||
|
static void flush_and_request_resend();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static uint8_t index_w; // Ring buffer write position
|
||||||
|
|
||||||
|
static void get_serial_commands();
|
||||||
|
|
||||||
|
#if ENABLED(SDSUPPORT)
|
||||||
|
static void get_sdcard_commands();
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
static void _commit_command(bool say_ok
|
||||||
* Add to the circular command queue the next command from:
|
#if NUM_SERIAL > 1
|
||||||
* - The command-injection queue (injected_commands_P)
|
, int16_t p=-1
|
||||||
* - The active serial input (usually USB)
|
#endif
|
||||||
* - The SD card file being actively printed
|
);
|
||||||
*/
|
|
||||||
void get_available_commands();
|
|
||||||
|
|
||||||
/**
|
static bool _enqueue(const char* cmd, bool say_ok=false
|
||||||
* Get the next command in the queue, optionally log it to SD, then dispatch it
|
#if NUM_SERIAL > 1
|
||||||
*/
|
, int16_t p=-1
|
||||||
void advance_command_queue();
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
// Process the next "immediate" command
|
||||||
|
static bool process_injected_command();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enqueue with Serial Echo
|
||||||
|
* Return true on success
|
||||||
|
*/
|
||||||
|
static bool enqueue_one(const char* cmd);
|
||||||
|
|
||||||
|
static void gcode_line_error(PGM_P const err, const int8_t port);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
extern GCodeQueue queue;
|
||||||
|
|
|
@ -53,7 +53,7 @@ void GcodeSuite::M28() {
|
||||||
SERIAL_ECHOLN(p);
|
SERIAL_ECHOLN(p);
|
||||||
card.openFile(p, false);
|
card.openFile(p, false);
|
||||||
#if NUM_SERIAL > 1
|
#if NUM_SERIAL > 1
|
||||||
card.transfer_port_index = command_queue_port[cmd_queue_index_r];
|
card.transfer_port_index = queue.port[queue.index_r];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -777,10 +777,10 @@ namespace ExtUI {
|
||||||
float getFeedrate_percent() { return feedrate_percentage; }
|
float getFeedrate_percent() { return feedrate_percentage; }
|
||||||
|
|
||||||
void enqueueCommands_P(PGM_P const gcode) {
|
void enqueueCommands_P(PGM_P const gcode) {
|
||||||
enqueue_and_echo_commands_P(gcode);
|
queue.inject_P(gcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool commandsInQueue() { return (planner.movesplanned() || commands_in_queue); }
|
bool commandsInQueue() { return (planner.movesplanned() || queue.length); }
|
||||||
|
|
||||||
bool isAxisPositionKnown(const axis_t axis) {
|
bool isAxisPositionKnown(const axis_t axis) {
|
||||||
return TEST(axis_known_position, axis);
|
return TEST(axis_known_position, axis);
|
||||||
|
|
|
@ -190,8 +190,8 @@ void process_lcd_j_command(const char* command) {
|
||||||
case 'E':
|
case 'E':
|
||||||
// enable or disable steppers
|
// enable or disable steppers
|
||||||
// switch to relative
|
// switch to relative
|
||||||
enqueue_and_echo_commands_now_P(PSTR("G91"));
|
queue.enqueue_now_P(PSTR("G91"));
|
||||||
enqueue_and_echo_commands_now_P(steppers_enabled ? PSTR("M18") : PSTR("M17"));
|
queue.enqueue_now_P(steppers_enabled ? PSTR("M18") : PSTR("M17"));
|
||||||
steppers_enabled = !steppers_enabled;
|
steppers_enabled = !steppers_enabled;
|
||||||
break;
|
break;
|
||||||
case 'A':
|
case 'A':
|
||||||
|
@ -204,7 +204,7 @@ void process_lcd_j_command(const char* command) {
|
||||||
// The M200 class UI seems to send movement in .1mm values.
|
// The M200 class UI seems to send movement in .1mm values.
|
||||||
char cmd[20];
|
char cmd[20];
|
||||||
sprintf_P(cmd, PSTR("G1 %c%03.1f"), axis, atof(command + 1) / 10.0);
|
sprintf_P(cmd, PSTR("G1 %c%03.1f"), axis, atof(command + 1) / 10.0);
|
||||||
enqueue_and_echo_command_now(cmd);
|
queue.enqueue_one_now(cmd);
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
SERIAL_ECHOLNPAIR("UNKNOWN J COMMAND", command);
|
SERIAL_ECHOLNPAIR("UNKNOWN J COMMAND", command);
|
||||||
|
@ -247,7 +247,7 @@ void process_lcd_p_command(const char* command) {
|
||||||
true
|
true
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
clear_command_queue();
|
queue.clear();
|
||||||
quickstop_stepper();
|
quickstop_stepper();
|
||||||
print_job_timer.stop();
|
print_job_timer.stop();
|
||||||
thermalManager.disable_all_heaters();
|
thermalManager.disable_all_heaters();
|
||||||
|
@ -258,7 +258,7 @@ void process_lcd_p_command(const char* command) {
|
||||||
break;
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
// Home all axis
|
// Home all axis
|
||||||
enqueue_and_echo_commands_now_P(PSTR("G28"));
|
queue.enqueue_now_P(PSTR("G28"));
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
#if ENABLED(SDSUPPORT)
|
#if ENABLED(SDSUPPORT)
|
||||||
|
@ -321,7 +321,7 @@ void process_lcd_s_command(const char* command) {
|
||||||
|
|
||||||
case 'H':
|
case 'H':
|
||||||
// Home all axis
|
// Home all axis
|
||||||
enqueue_and_echo_command("G28");
|
queue.inject_P(PSTR("G28"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'L': {
|
case 'L': {
|
||||||
|
|
|
@ -99,7 +99,7 @@ void MarlinUI::goto_previous_screen() {
|
||||||
/////////// Common Menu Actions ////////////
|
/////////// Common Menu Actions ////////////
|
||||||
////////////////////////////////////////////
|
////////////////////////////////////////////
|
||||||
|
|
||||||
void MenuItem_gcode::action(PGM_P pgcode) { enqueue_and_echo_commands_P(pgcode); }
|
void MenuItem_gcode::action(PGM_P pgcode) { queue.inject_P(pgcode); }
|
||||||
|
|
||||||
////////////////////////////////////////////
|
////////////////////////////////////////////
|
||||||
/////////// Menu Editing Actions ///////////
|
/////////// Menu Editing Actions ///////////
|
||||||
|
@ -410,15 +410,15 @@ void MarlinUI::completion_feedback(const bool good/*=true*/) {
|
||||||
|
|
||||||
#if ANY(AUTO_BED_LEVELING_UBL, PID_AUTOTUNE_MENU, ADVANCED_PAUSE_FEATURE)
|
#if ANY(AUTO_BED_LEVELING_UBL, PID_AUTOTUNE_MENU, ADVANCED_PAUSE_FEATURE)
|
||||||
|
|
||||||
void lcd_enqueue_command(const char * const cmd) {
|
void lcd_enqueue_one_now(const char * const cmd) {
|
||||||
no_reentry = true;
|
no_reentry = true;
|
||||||
enqueue_and_echo_command_now(cmd);
|
queue.enqueue_one_now(cmd);
|
||||||
no_reentry = false;
|
no_reentry = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_enqueue_commands_P(PGM_P const cmd) {
|
void lcd_enqueue_one_now_P(PGM_P const cmd) {
|
||||||
no_reentry = true;
|
no_reentry = true;
|
||||||
enqueue_and_echo_commands_now_P(cmd);
|
queue.enqueue_now_P(cmd);
|
||||||
no_reentry = false;
|
no_reentry = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -375,8 +375,8 @@ void _lcd_draw_homing();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ANY(AUTO_BED_LEVELING_UBL, PID_AUTOTUNE_MENU, ADVANCED_PAUSE_FEATURE)
|
#if ANY(AUTO_BED_LEVELING_UBL, PID_AUTOTUNE_MENU, ADVANCED_PAUSE_FEATURE)
|
||||||
void lcd_enqueue_command(const char * const cmd);
|
void lcd_enqueue_one_now(const char * const cmd);
|
||||||
void lcd_enqueue_commands_P(PGM_P const cmd);
|
void lcd_enqueue_one_now_P(PGM_P const cmd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(LEVEL_BED_CORNERS)
|
#if ENABLED(LEVEL_BED_CORNERS)
|
||||||
|
|
|
@ -101,7 +101,7 @@ void menu_backlash();
|
||||||
// Set the home offset based on the current_position
|
// Set the home offset based on the current_position
|
||||||
//
|
//
|
||||||
void _lcd_set_home_offsets() {
|
void _lcd_set_home_offsets() {
|
||||||
enqueue_and_echo_commands_P(PSTR("M428"));
|
queue.inject_P(PSTR("M428"));
|
||||||
ui.return_to_status();
|
ui.return_to_status();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -255,7 +255,7 @@ void menu_backlash();
|
||||||
autotune_temp[e]
|
autotune_temp[e]
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
lcd_enqueue_command(cmd);
|
lcd_enqueue_one_now(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // PID_AUTOTUNE_MENU
|
#endif // PID_AUTOTUNE_MENU
|
||||||
|
|
|
@ -120,7 +120,7 @@ void _lcd_level_bed_corners() {
|
||||||
ui.defer_status_screen();
|
ui.defer_status_screen();
|
||||||
if (!all_axes_known()) {
|
if (!all_axes_known()) {
|
||||||
set_all_unhomed();
|
set_all_unhomed();
|
||||||
enqueue_and_echo_commands_P(PSTR("G28"));
|
queue.inject_P(PSTR("G28"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable leveling so the planner won't mess with us
|
// Disable leveling so the planner won't mess with us
|
||||||
|
|
|
@ -105,9 +105,9 @@
|
||||||
ui.wait_for_bl_move = true;
|
ui.wait_for_bl_move = true;
|
||||||
ui.goto_screen(_lcd_level_bed_done);
|
ui.goto_screen(_lcd_level_bed_done);
|
||||||
#if ENABLED(MESH_BED_LEVELING)
|
#if ENABLED(MESH_BED_LEVELING)
|
||||||
enqueue_and_echo_commands_P(PSTR("G29 S2"));
|
queue.inject_P(PSTR("G29 S2"));
|
||||||
#elif ENABLED(PROBE_MANUALLY)
|
#elif ENABLED(PROBE_MANUALLY)
|
||||||
enqueue_and_echo_commands_P(PSTR("G29 V1"));
|
queue.inject_P(PSTR("G29 V1"));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -157,9 +157,9 @@
|
||||||
// G29 Records Z, moves, and signals when it pauses
|
// G29 Records Z, moves, and signals when it pauses
|
||||||
ui.wait_for_bl_move = true;
|
ui.wait_for_bl_move = true;
|
||||||
#if ENABLED(MESH_BED_LEVELING)
|
#if ENABLED(MESH_BED_LEVELING)
|
||||||
enqueue_and_echo_commands_P(manual_probe_index ? PSTR("G29 S2") : PSTR("G29 S1"));
|
queue.inject_P(manual_probe_index ? PSTR("G29 S2") : PSTR("G29 S1"));
|
||||||
#elif ENABLED(PROBE_MANUALLY)
|
#elif ENABLED(PROBE_MANUALLY)
|
||||||
enqueue_and_echo_commands_P(PSTR("G29 V1"));
|
queue.inject_P(PSTR("G29 V1"));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@
|
||||||
ui.defer_status_screen();
|
ui.defer_status_screen();
|
||||||
set_all_unhomed();
|
set_all_unhomed();
|
||||||
ui.goto_screen(_lcd_level_bed_homing);
|
ui.goto_screen(_lcd_level_bed_homing);
|
||||||
enqueue_and_echo_commands_P(PSTR("G28"));
|
queue.inject_P(PSTR("G28"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // PROBE_MANUALLY || MESH_BED_LEVELING
|
#endif // PROBE_MANUALLY || MESH_BED_LEVELING
|
||||||
|
|
|
@ -127,7 +127,7 @@ static void lcd_factory_settings() {
|
||||||
|
|
||||||
auto _recalc_offsets = []{
|
auto _recalc_offsets = []{
|
||||||
if (active_extruder && all_axes_known()) { // For the 2nd extruder re-home so the next tool-change gets the new offsets.
|
if (active_extruder && all_axes_known()) { // For the 2nd extruder re-home so the next tool-change gets the new offsets.
|
||||||
enqueue_and_echo_commands_P(PSTR("G28")); // In future, we can babystep the 2nd extruder (if active), making homing unnecessary.
|
queue.inject_P(PSTR("G28")); // In future, we can babystep the 2nd extruder (if active), making homing unnecessary.
|
||||||
active_extruder = 0;
|
active_extruder = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void _lcd_user_gcode(PGM_P const cmd) {
|
void _lcd_user_gcode(PGM_P const cmd) {
|
||||||
enqueue_and_echo_commands_P(cmd);
|
queue.inject_P(cmd);
|
||||||
#if ENABLED(USER_SCRIPT_AUDIBLE_FEEDBACK)
|
#if ENABLED(USER_SCRIPT_AUDIBLE_FEEDBACK)
|
||||||
ui.completion_feedback();
|
ui.completion_feedback();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -73,7 +73,7 @@ void _man_probe_pt(const float &rx, const float &ry) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _lcd_delta_calibrate_home() {
|
void _lcd_delta_calibrate_home() {
|
||||||
enqueue_and_echo_commands_P(PSTR("G28"));
|
queue.inject_P(PSTR("G28"));
|
||||||
ui.goto_screen(_lcd_calibrate_homing);
|
ui.goto_screen(_lcd_calibrate_homing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ static void _change_filament_temp(const uint16_t temperature) {
|
||||||
char cmd[11];
|
char cmd[11];
|
||||||
sprintf_P(cmd, _change_filament_temp_command(), _change_filament_temp_extruder);
|
sprintf_P(cmd, _change_filament_temp_command(), _change_filament_temp_extruder);
|
||||||
thermalManager.setTargetHotend(temperature, _change_filament_temp_extruder);
|
thermalManager.setTargetHotend(temperature, _change_filament_temp_extruder);
|
||||||
lcd_enqueue_command(cmd);
|
lcd_enqueue_one_now(cmd);
|
||||||
}
|
}
|
||||||
inline void _lcd_change_filament_temp_1_func() { _change_filament_temp(ui.preheat_hotend_temp[0]); }
|
inline void _lcd_change_filament_temp_1_func() { _change_filament_temp(ui.preheat_hotend_temp[0]); }
|
||||||
inline void _lcd_change_filament_temp_2_func() { _change_filament_temp(ui.preheat_hotend_temp[1]); }
|
inline void _lcd_change_filament_temp_2_func() { _change_filament_temp(ui.preheat_hotend_temp[1]); }
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
static void lcd_power_loss_recovery_resume() {
|
static void lcd_power_loss_recovery_resume() {
|
||||||
ui.return_to_status();
|
ui.return_to_status();
|
||||||
enqueue_and_echo_commands_P(PSTR("M1000"));
|
queue.inject_P(PSTR("M1000"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lcd_power_loss_recovery_cancel() {
|
static void lcd_power_loss_recovery_cancel() {
|
||||||
|
|
|
@ -107,15 +107,15 @@ void lcd_z_offset_edit_setup(const float &initial) {
|
||||||
* UBL Build Custom Mesh Command
|
* UBL Build Custom Mesh Command
|
||||||
*/
|
*/
|
||||||
void _lcd_ubl_build_custom_mesh() {
|
void _lcd_ubl_build_custom_mesh() {
|
||||||
char UBL_LCD_GCODE[20];
|
char ubl_lcd_gcode[20];
|
||||||
enqueue_and_echo_commands_P(PSTR("G28"));
|
queue.inject_P(PSTR("G28"));
|
||||||
#if HAS_HEATED_BED
|
#if HAS_HEATED_BED
|
||||||
sprintf_P(UBL_LCD_GCODE, PSTR("M190 S%i"), custom_bed_temp);
|
sprintf_P(ubl_lcd_gcode, PSTR("M190 S%i"), custom_bed_temp);
|
||||||
lcd_enqueue_command(UBL_LCD_GCODE);
|
lcd_enqueue_one_now(ubl_lcd_gcode);
|
||||||
#endif
|
#endif
|
||||||
sprintf_P(UBL_LCD_GCODE, PSTR("M109 S%i"), custom_hotend_temp);
|
sprintf_P(ubl_lcd_gcode, PSTR("M109 S%i"), custom_hotend_temp);
|
||||||
lcd_enqueue_command(UBL_LCD_GCODE);
|
lcd_enqueue_one_now(ubl_lcd_gcode);
|
||||||
enqueue_and_echo_commands_P(PSTR("G29 P1"));
|
queue.inject_P(PSTR("G29 P1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,11 +141,11 @@ void _lcd_ubl_custom_mesh() {
|
||||||
* UBL Adjust Mesh Height Command
|
* UBL Adjust Mesh Height Command
|
||||||
*/
|
*/
|
||||||
void _lcd_ubl_adjust_height_cmd() {
|
void _lcd_ubl_adjust_height_cmd() {
|
||||||
char UBL_LCD_GCODE[16];
|
char ubl_lcd_gcode[16];
|
||||||
const int ind = ubl_height_amount > 0 ? 9 : 10;
|
const int ind = ubl_height_amount > 0 ? 9 : 10;
|
||||||
strcpy_P(UBL_LCD_GCODE, PSTR("G29 P6 C -"));
|
strcpy_P(ubl_lcd_gcode, PSTR("G29 P6 C -"));
|
||||||
sprintf_P(&UBL_LCD_GCODE[ind], PSTR(".%i"), ABS(ubl_height_amount));
|
sprintf_P(&ubl_lcd_gcode[ind], PSTR(".%i"), ABS(ubl_height_amount));
|
||||||
lcd_enqueue_command(UBL_LCD_GCODE);
|
lcd_enqueue_one_now(ubl_lcd_gcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -187,7 +187,7 @@ void _lcd_ubl_edit_mesh() {
|
||||||
* UBL Validate Custom Mesh Command
|
* UBL Validate Custom Mesh Command
|
||||||
*/
|
*/
|
||||||
void _lcd_ubl_validate_custom_mesh() {
|
void _lcd_ubl_validate_custom_mesh() {
|
||||||
char UBL_LCD_GCODE[24];
|
char ubl_lcd_gcode[24];
|
||||||
const int temp =
|
const int temp =
|
||||||
#if HAS_HEATED_BED
|
#if HAS_HEATED_BED
|
||||||
custom_bed_temp
|
custom_bed_temp
|
||||||
|
@ -195,9 +195,9 @@ void _lcd_ubl_validate_custom_mesh() {
|
||||||
0
|
0
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
sprintf_P(UBL_LCD_GCODE, PSTR("G26 C B%i H%i P"), temp, custom_hotend_temp);
|
sprintf_P(ubl_lcd_gcode, PSTR("G26 C B%i H%i P"), temp, custom_hotend_temp);
|
||||||
lcd_enqueue_commands_P(PSTR("G28"));
|
lcd_enqueue_one_now_P(PSTR("G28"));
|
||||||
lcd_enqueue_command(UBL_LCD_GCODE);
|
lcd_enqueue_one_now(ubl_lcd_gcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -228,9 +228,9 @@ void _lcd_ubl_validate_mesh() {
|
||||||
* UBL Grid Leveling Command
|
* UBL Grid Leveling Command
|
||||||
*/
|
*/
|
||||||
void _lcd_ubl_grid_level_cmd() {
|
void _lcd_ubl_grid_level_cmd() {
|
||||||
char UBL_LCD_GCODE[12];
|
char ubl_lcd_gcode[12];
|
||||||
sprintf_P(UBL_LCD_GCODE, PSTR("G29 J%i"), side_points);
|
sprintf_P(ubl_lcd_gcode, PSTR("G29 J%i"), side_points);
|
||||||
lcd_enqueue_command(UBL_LCD_GCODE);
|
lcd_enqueue_one_now(ubl_lcd_gcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -269,9 +269,9 @@ void _lcd_ubl_mesh_leveling() {
|
||||||
* UBL Fill-in Amount Mesh Command
|
* UBL Fill-in Amount Mesh Command
|
||||||
*/
|
*/
|
||||||
void _lcd_ubl_fillin_amount_cmd() {
|
void _lcd_ubl_fillin_amount_cmd() {
|
||||||
char UBL_LCD_GCODE[18];
|
char ubl_lcd_gcode[18];
|
||||||
sprintf_P(UBL_LCD_GCODE, PSTR("G29 P3 R C.%i"), ubl_fillin_amount);
|
sprintf_P(ubl_lcd_gcode, PSTR("G29 P3 R C.%i"), ubl_fillin_amount);
|
||||||
lcd_enqueue_command(UBL_LCD_GCODE);
|
lcd_enqueue_one_now(ubl_lcd_gcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -361,22 +361,22 @@ void _lcd_ubl_build_mesh() {
|
||||||
* UBL Load Mesh Command
|
* UBL Load Mesh Command
|
||||||
*/
|
*/
|
||||||
void _lcd_ubl_load_mesh_cmd() {
|
void _lcd_ubl_load_mesh_cmd() {
|
||||||
char UBL_LCD_GCODE[25];
|
char ubl_lcd_gcode[25];
|
||||||
sprintf_P(UBL_LCD_GCODE, PSTR("G29 L%i"), ubl_storage_slot);
|
sprintf_P(ubl_lcd_gcode, PSTR("G29 L%i"), ubl_storage_slot);
|
||||||
lcd_enqueue_command(UBL_LCD_GCODE);
|
lcd_enqueue_one_now(ubl_lcd_gcode);
|
||||||
sprintf_P(UBL_LCD_GCODE, PSTR("M117 " MSG_MESH_LOADED), ubl_storage_slot);
|
sprintf_P(ubl_lcd_gcode, PSTR("M117 " MSG_MESH_LOADED), ubl_storage_slot);
|
||||||
lcd_enqueue_command(UBL_LCD_GCODE);
|
lcd_enqueue_one_now(ubl_lcd_gcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UBL Save Mesh Command
|
* UBL Save Mesh Command
|
||||||
*/
|
*/
|
||||||
void _lcd_ubl_save_mesh_cmd() {
|
void _lcd_ubl_save_mesh_cmd() {
|
||||||
char UBL_LCD_GCODE[25];
|
char ubl_lcd_gcode[25];
|
||||||
sprintf_P(UBL_LCD_GCODE, PSTR("G29 S%i"), ubl_storage_slot);
|
sprintf_P(ubl_lcd_gcode, PSTR("G29 S%i"), ubl_storage_slot);
|
||||||
lcd_enqueue_command(UBL_LCD_GCODE);
|
lcd_enqueue_one_now(ubl_lcd_gcode);
|
||||||
sprintf_P(UBL_LCD_GCODE, PSTR("M117 " MSG_MESH_SAVED), ubl_storage_slot);
|
sprintf_P(ubl_lcd_gcode, PSTR("M117 " MSG_MESH_SAVED), ubl_storage_slot);
|
||||||
lcd_enqueue_command(UBL_LCD_GCODE);
|
lcd_enqueue_one_now(ubl_lcd_gcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -420,11 +420,11 @@ void _lcd_ubl_map_homing() {
|
||||||
* UBL LCD "radar" map point editing
|
* UBL LCD "radar" map point editing
|
||||||
*/
|
*/
|
||||||
void _lcd_ubl_map_lcd_edit_cmd() {
|
void _lcd_ubl_map_lcd_edit_cmd() {
|
||||||
char UBL_LCD_GCODE[50], str[10], str2[10];
|
char ubl_lcd_gcode[50], str[10], str2[10];
|
||||||
dtostrf(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]), 0, 2, str);
|
dtostrf(pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]), 0, 2, str);
|
||||||
dtostrf(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]), 0, 2, str2);
|
dtostrf(pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]), 0, 2, str2);
|
||||||
snprintf_P(UBL_LCD_GCODE, sizeof(UBL_LCD_GCODE), PSTR("G29 P4 X%s Y%s R%i"), str, str2, n_edit_pts);
|
snprintf_P(ubl_lcd_gcode, sizeof(ubl_lcd_gcode), PSTR("G29 P4 X%s Y%s R%i"), str, str2, n_edit_pts);
|
||||||
lcd_enqueue_command(UBL_LCD_GCODE);
|
lcd_enqueue_one_now(ubl_lcd_gcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -529,7 +529,7 @@ void _lcd_ubl_output_map_lcd() {
|
||||||
void _lcd_ubl_output_map_lcd_cmd() {
|
void _lcd_ubl_output_map_lcd_cmd() {
|
||||||
if (!all_axes_known()) {
|
if (!all_axes_known()) {
|
||||||
set_all_unhomed();
|
set_all_unhomed();
|
||||||
enqueue_and_echo_commands_P(PSTR("G28"));
|
queue.inject_P(PSTR("G28"));
|
||||||
}
|
}
|
||||||
ui.goto_screen(_lcd_ubl_map_homing);
|
ui.goto_screen(_lcd_ubl_map_homing);
|
||||||
}
|
}
|
||||||
|
|
|
@ -441,7 +441,7 @@ bool MarlinUI::get_blink() {
|
||||||
|
|
||||||
#endif // HAS_LCD_MENU
|
#endif // HAS_LCD_MENU
|
||||||
|
|
||||||
if (!homed && RRK(EN_KEYPAD_F1)) enqueue_and_echo_commands_P(PSTR("G28"));
|
if (!homed && RRK(EN_KEYPAD_F1)) queue.inject_P(PSTR("G28"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1461,9 +1461,9 @@ void MarlinUI::update() {
|
||||||
#if HAS_SPI_LCD
|
#if HAS_SPI_LCD
|
||||||
lcd_pause_show_message(PAUSE_MESSAGE_PAUSING, PAUSE_MODE_PAUSE_PRINT); // Show message immediately to let user know about pause in progress
|
lcd_pause_show_message(PAUSE_MESSAGE_PAUSING, PAUSE_MODE_PAUSE_PRINT); // Show message immediately to let user know about pause in progress
|
||||||
#endif
|
#endif
|
||||||
enqueue_and_echo_commands_front_P(PSTR("M25 P\nM24"));
|
queue.inject_P(PSTR("M25 P\nM24"));
|
||||||
#elif ENABLED(SDSUPPORT)
|
#elif ENABLED(SDSUPPORT)
|
||||||
enqueue_and_echo_commands_P(PSTR("M25"));
|
queue.inject_P(PSTR("M25"));
|
||||||
#elif defined(ACTION_ON_PAUSE)
|
#elif defined(ACTION_ON_PAUSE)
|
||||||
host_action_pause();
|
host_action_pause();
|
||||||
#endif
|
#endif
|
||||||
|
@ -1475,7 +1475,7 @@ void MarlinUI::update() {
|
||||||
wait_for_heatup = wait_for_user = false;
|
wait_for_heatup = wait_for_user = false;
|
||||||
#endif
|
#endif
|
||||||
#if ENABLED(SDSUPPORT)
|
#if ENABLED(SDSUPPORT)
|
||||||
if (card.isPaused()) enqueue_and_echo_commands_P(PSTR("M24"));
|
if (card.isPaused()) queue.inject_P(PSTR("M24"));
|
||||||
#endif
|
#endif
|
||||||
#ifdef ACTION_ON_RESUME
|
#ifdef ACTION_ON_RESUME
|
||||||
host_action_resume();
|
host_action_resume();
|
||||||
|
|
|
@ -735,7 +735,7 @@ class Planner {
|
||||||
if (cleaning_buffer_counter) {
|
if (cleaning_buffer_counter) {
|
||||||
--cleaning_buffer_counter;
|
--cleaning_buffer_counter;
|
||||||
#if ENABLED(SD_FINISHED_STEPPERRELEASE) && defined(SD_FINISHED_RELEASECOMMAND)
|
#if ENABLED(SD_FINISHED_STEPPERRELEASE) && defined(SD_FINISHED_RELEASECOMMAND)
|
||||||
if (!cleaning_buffer_counter) enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND));
|
if (!cleaning_buffer_counter) queue.inject_P(PSTR(SD_FINISHED_RELEASECOMMAND));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -367,8 +367,8 @@ void CardReader::openAndPrintFile(const char *name) {
|
||||||
char cmd[4 + strlen(name) + 1]; // Room for "M23 ", filename, and null
|
char cmd[4 + strlen(name) + 1]; // Room for "M23 ", filename, and null
|
||||||
sprintf_P(cmd, PSTR("M23 %s"), name);
|
sprintf_P(cmd, PSTR("M23 %s"), name);
|
||||||
for (char *c = &cmd[4]; *c; c++) *c = tolower(*c);
|
for (char *c = &cmd[4]; *c; c++) *c = tolower(*c);
|
||||||
enqueue_and_echo_command_now(cmd);
|
queue.enqueue_one_now(cmd);
|
||||||
enqueue_and_echo_commands_P(PSTR("M24"));
|
queue.inject_P(PSTR("M24"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardReader::startFileprint() {
|
void CardReader::startFileprint() {
|
||||||
|
@ -1001,7 +1001,7 @@ void CardReader::printingHasFinished() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
print_job_timer.stop();
|
print_job_timer.stop();
|
||||||
if (print_job_timer.duration() > 60) enqueue_and_echo_commands_P(PSTR("M31"));
|
if (print_job_timer.duration() > 60) queue.inject_P(PSTR("M31"));
|
||||||
|
|
||||||
#if ENABLED(SDCARD_SORT_ALPHA)
|
#if ENABLED(SDCARD_SORT_ALPHA)
|
||||||
presort();
|
presort();
|
||||||
|
|
Loading…
Reference in a new issue