|
@ -89,7 +89,7 @@ char GCodeQueue::command_buffer[BUFSIZE][MAX_CMD_SIZE]; |
|
|
* The port that the command was received on |
|
|
* The port that the command was received on |
|
|
*/ |
|
|
*/ |
|
|
#if HAS_MULTI_SERIAL |
|
|
#if HAS_MULTI_SERIAL |
|
|
int16_t GCodeQueue::port[BUFSIZE]; |
|
|
serial_index_t GCodeQueue::port[BUFSIZE]; |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
/**
|
|
|
/**
|
|
@ -136,11 +136,11 @@ void GCodeQueue::clear() { |
|
|
*/ |
|
|
*/ |
|
|
void GCodeQueue::_commit_command(bool say_ok |
|
|
void GCodeQueue::_commit_command(bool say_ok |
|
|
#if HAS_MULTI_SERIAL |
|
|
#if HAS_MULTI_SERIAL |
|
|
, int16_t p/*=-1*/ |
|
|
, serial_index_t serial_ind/*=-1*/ |
|
|
#endif |
|
|
#endif |
|
|
) { |
|
|
) { |
|
|
send_ok[index_w] = say_ok; |
|
|
send_ok[index_w] = say_ok; |
|
|
TERN_(HAS_MULTI_SERIAL, port[index_w] = p); |
|
|
TERN_(HAS_MULTI_SERIAL, port[index_w] = serial_ind); |
|
|
TERN_(POWER_LOSS_RECOVERY, recovery.commit_sdpos(index_w)); |
|
|
TERN_(POWER_LOSS_RECOVERY, recovery.commit_sdpos(index_w)); |
|
|
if (++index_w >= BUFSIZE) index_w = 0; |
|
|
if (++index_w >= BUFSIZE) index_w = 0; |
|
|
length++; |
|
|
length++; |
|
@ -153,14 +153,14 @@ void GCodeQueue::_commit_command(bool say_ok |
|
|
*/ |
|
|
*/ |
|
|
bool GCodeQueue::_enqueue(const char* cmd, bool say_ok/*=false*/ |
|
|
bool GCodeQueue::_enqueue(const char* cmd, bool say_ok/*=false*/ |
|
|
#if HAS_MULTI_SERIAL |
|
|
#if HAS_MULTI_SERIAL |
|
|
, int16_t pn/*=-1*/ |
|
|
, serial_index_t serial_ind/*=-1*/ |
|
|
#endif |
|
|
#endif |
|
|
) { |
|
|
) { |
|
|
if (*cmd == ';' || length >= BUFSIZE) return false; |
|
|
if (*cmd == ';' || length >= BUFSIZE) return false; |
|
|
strcpy(command_buffer[index_w], cmd); |
|
|
strcpy(command_buffer[index_w], cmd); |
|
|
_commit_command(say_ok |
|
|
_commit_command(say_ok |
|
|
#if HAS_MULTI_SERIAL |
|
|
#if HAS_MULTI_SERIAL |
|
|
, pn |
|
|
, serial_ind |
|
|
#endif |
|
|
#endif |
|
|
); |
|
|
); |
|
|
return true; |
|
|
return true; |
|
@ -289,9 +289,9 @@ void GCodeQueue::enqueue_now_P(PGM_P const pgcode) { |
|
|
*/ |
|
|
*/ |
|
|
void GCodeQueue::ok_to_send() { |
|
|
void GCodeQueue::ok_to_send() { |
|
|
#if HAS_MULTI_SERIAL |
|
|
#if HAS_MULTI_SERIAL |
|
|
const int16_t pn = command_port(); |
|
|
const serial_index_t serial_ind = command_port(); |
|
|
if (pn < 0) return; |
|
|
if (serial_ind < 0) return; // Never mind. Command came from SD or Flash Drive
|
|
|
PORT_REDIRECT(pn); // Reply to the serial port that sent the command
|
|
|
PORT_REDIRECT(serial_ind); // Reply to the serial port that sent the command
|
|
|
#endif |
|
|
#endif |
|
|
if (!send_ok[index_r]) return; |
|
|
if (!send_ok[index_r]) return; |
|
|
SERIAL_ECHOPGM(STR_OK); |
|
|
SERIAL_ECHOPGM(STR_OK); |
|
@ -314,14 +314,14 @@ void GCodeQueue::ok_to_send() { |
|
|
* indicate that a command needs to be re-sent. |
|
|
* indicate that a command needs to be re-sent. |
|
|
*/ |
|
|
*/ |
|
|
void GCodeQueue::flush_and_request_resend() { |
|
|
void GCodeQueue::flush_and_request_resend() { |
|
|
const int16_t pn = command_port(); |
|
|
const serial_index_t serial_ind = command_port(); |
|
|
#if HAS_MULTI_SERIAL |
|
|
#if HAS_MULTI_SERIAL |
|
|
if (pn < 0) return; |
|
|
if (serial_ind < 0) return; // Never mind. Command came from SD or Flash Drive
|
|
|
PORT_REDIRECT(pn); // Reply to the serial port that sent the command
|
|
|
PORT_REDIRECT(serial_ind); // Reply to the serial port that sent the command
|
|
|
#endif |
|
|
#endif |
|
|
SERIAL_FLUSH(); |
|
|
SERIAL_FLUSH(); |
|
|
SERIAL_ECHOPGM(STR_RESEND); |
|
|
SERIAL_ECHOPGM(STR_RESEND); |
|
|
SERIAL_ECHOLN(last_N[pn] + 1); |
|
|
SERIAL_ECHOLN(last_N[serial_ind] + 1); |
|
|
ok_to_send(); |
|
|
ok_to_send(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -348,14 +348,14 @@ inline int read_serial(const uint8_t index) { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void GCodeQueue::gcode_line_error(PGM_P const err, const int8_t pn) { |
|
|
void GCodeQueue::gcode_line_error(PGM_P const err, const serial_index_t serial_ind) { |
|
|
PORT_REDIRECT(pn); // Reply to the serial port that sent the command
|
|
|
PORT_REDIRECT(serial_ind); // Reply to the serial port that sent the command
|
|
|
SERIAL_ERROR_START(); |
|
|
SERIAL_ERROR_START(); |
|
|
serialprintPGM(err); |
|
|
serialprintPGM(err); |
|
|
SERIAL_ECHOLN(last_N[pn]); |
|
|
SERIAL_ECHOLN(last_N[serial_ind]); |
|
|
while (read_serial(pn) != -1); // Clear out the RX buffer
|
|
|
while (read_serial(serial_ind) != -1); // Clear out the RX buffer
|
|
|
flush_and_request_resend(); |
|
|
flush_and_request_resend(); |
|
|
serial_count[pn] = 0; |
|
|
serial_count[serial_ind] = 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
|
|
@ -473,13 +473,13 @@ void GCodeQueue::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 (length < BUFSIZE && serial_data_available()) { |
|
|
while (length < BUFSIZE && serial_data_available()) { |
|
|
LOOP_L_N(i, NUM_SERIAL) { |
|
|
LOOP_L_N(p, NUM_SERIAL) { |
|
|
|
|
|
|
|
|
const int c = read_serial(i); |
|
|
const int c = read_serial(p); |
|
|
if (c < 0) continue; |
|
|
if (c < 0) continue; |
|
|
|
|
|
|
|
|
#if ENABLED(MEATPACK) |
|
|
#if ENABLED(MEATPACK) |
|
|
meatpack.handle_rx_char(uint8_t(c)); |
|
|
meatpack.handle_rx_char(uint8_t(c), p); |
|
|
char c_res[2] = { 0, 0 }; |
|
|
char c_res[2] = { 0, 0 }; |
|
|
const uint8_t char_count = meatpack.get_result_char(c_res); |
|
|
const uint8_t char_count = meatpack.get_result_char(c_res); |
|
|
#else |
|
|
#else |
|
@ -492,10 +492,10 @@ void GCodeQueue::get_serial_commands() { |
|
|
if (ISEOL(serial_char)) { |
|
|
if (ISEOL(serial_char)) { |
|
|
|
|
|
|
|
|
// Reset our state, continue if the line was empty
|
|
|
// Reset our state, continue if the line was empty
|
|
|
if (process_line_done(serial_input_state[i], serial_line_buffer[i], serial_count[i])) |
|
|
if (process_line_done(serial_input_state[p], serial_line_buffer[p], serial_count[p])) |
|
|
continue; |
|
|
continue; |
|
|
|
|
|
|
|
|
char* command = serial_line_buffer[i]; |
|
|
char* command = serial_line_buffer[p]; |
|
|
|
|
|
|
|
|
while (*command == ' ') command++; // Skip leading spaces
|
|
|
while (*command == ' ') command++; // Skip leading spaces
|
|
|
char *npos = (*command == 'N') ? command : nullptr; // Require the N parameter to start the line
|
|
|
char *npos = (*command == 'N') ? command : nullptr; // Require the N parameter to start the line
|
|
@ -511,25 +511,25 @@ void GCodeQueue::get_serial_commands() { |
|
|
|
|
|
|
|
|
const long gcode_N = strtol(npos + 1, nullptr, 10); |
|
|
const long gcode_N = strtol(npos + 1, nullptr, 10); |
|
|
|
|
|
|
|
|
if (gcode_N != last_N[i] + 1 && !M110) |
|
|
if (gcode_N != last_N[p] + 1 && !M110) |
|
|
return gcode_line_error(PSTR(STR_ERR_LINE_NO), i); |
|
|
return gcode_line_error(PSTR(STR_ERR_LINE_NO), p); |
|
|
|
|
|
|
|
|
char *apos = strrchr(command, '*'); |
|
|
char *apos = strrchr(command, '*'); |
|
|
if (apos) { |
|
|
if (apos) { |
|
|
uint8_t checksum = 0, count = uint8_t(apos - command); |
|
|
uint8_t checksum = 0, count = uint8_t(apos - command); |
|
|
while (count) checksum ^= command[--count]; |
|
|
while (count) checksum ^= command[--count]; |
|
|
if (strtol(apos + 1, nullptr, 10) != checksum) |
|
|
if (strtol(apos + 1, nullptr, 10) != checksum) |
|
|
return gcode_line_error(PSTR(STR_ERR_CHECKSUM_MISMATCH), i); |
|
|
return gcode_line_error(PSTR(STR_ERR_CHECKSUM_MISMATCH), p); |
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
|
return gcode_line_error(PSTR(STR_ERR_NO_CHECKSUM), i); |
|
|
return gcode_line_error(PSTR(STR_ERR_NO_CHECKSUM), p); |
|
|
|
|
|
|
|
|
last_N[i] = gcode_N; |
|
|
last_N[p] = gcode_N; |
|
|
} |
|
|
} |
|
|
#if ENABLED(SDSUPPORT) |
|
|
#if ENABLED(SDSUPPORT) |
|
|
// Pronterface "M29" and "M29 " has no line number
|
|
|
// Pronterface "M29" and "M29 " has no line number
|
|
|
else if (card.flag.saving && !is_M29(command)) |
|
|
else if (card.flag.saving && !is_M29(command)) |
|
|
return gcode_line_error(PSTR(STR_ERR_NO_CHECKSUM), i); |
|
|
return gcode_line_error(PSTR(STR_ERR_NO_CHECKSUM), p); |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
//
|
|
|
//
|
|
@ -547,7 +547,7 @@ void GCodeQueue::get_serial_commands() { |
|
|
#if ENABLED(BEZIER_CURVE_SUPPORT) |
|
|
#if ENABLED(BEZIER_CURVE_SUPPORT) |
|
|
case 5: |
|
|
case 5: |
|
|
#endif |
|
|
#endif |
|
|
PORT_REDIRECT(i); // Reply to the serial port that sent the command
|
|
|
PORT_REDIRECT(p); // Reply to the serial port that sent the command
|
|
|
SERIAL_ECHOLNPGM(STR_ERR_STOPPED); |
|
|
SERIAL_ECHOLNPGM(STR_ERR_STOPPED); |
|
|
LCD_MESSAGEPGM(MSG_STOPPED); |
|
|
LCD_MESSAGEPGM(MSG_STOPPED); |
|
|
break; |
|
|
break; |
|
@ -569,14 +569,14 @@ void GCodeQueue::get_serial_commands() { |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
// Add the command to the queue
|
|
|
// Add the command to the queue
|
|
|
_enqueue(serial_line_buffer[i], true |
|
|
_enqueue(serial_line_buffer[p], true |
|
|
#if HAS_MULTI_SERIAL |
|
|
#if HAS_MULTI_SERIAL |
|
|
, i |
|
|
, p |
|
|
#endif |
|
|
#endif |
|
|
); |
|
|
); |
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
|
process_stream_char(serial_char, serial_input_state[i], serial_line_buffer[i], serial_count[i]); |
|
|
process_stream_char(serial_char, serial_input_state[p], serial_line_buffer[p], serial_count[p]); |
|
|
|
|
|
|
|
|
} // char_count loop
|
|
|
} // char_count loop
|
|
|
|
|
|
|
|
|