diff --git a/Marlin/MarlinSerial.cpp b/Marlin/MarlinSerial.cpp
index 1b288b67b..cd4dd03ad 100644
--- a/Marlin/MarlinSerial.cpp
+++ b/Marlin/MarlinSerial.cpp
@@ -79,98 +79,8 @@
#endif
#if ENABLED(EMERGENCY_PARSER)
-
- bool killed_by_M112; // = false
-
- #include "stepper.h"
- #include "language.h"
-
- // Currently looking for: M108, M112, M410
- // If you alter the parser please don't forget to update the capabilities in Conditionals_post.h
-
- FORCE_INLINE void emergency_parser(const unsigned char c) {
-
- static e_parser_state state = state_RESET;
-
- switch (state) {
- case state_RESET:
- switch (c) {
- case ' ': break;
- case 'N': state = state_N; break;
- case 'M': state = state_M; break;
- default: state = state_IGNORE;
- }
- break;
-
- case state_N:
- switch (c) {
- case '0': case '1': case '2':
- case '3': case '4': case '5':
- case '6': case '7': case '8':
- case '9': case '-': case ' ': break;
- case 'M': state = state_M; break;
- default: state = state_IGNORE;
- }
- break;
-
- case state_M:
- switch (c) {
- case ' ': break;
- case '1': state = state_M1; break;
- case '4': state = state_M4; break;
- default: state = state_IGNORE;
- }
- break;
-
- case state_M1:
- switch (c) {
- case '0': state = state_M10; break;
- case '1': state = state_M11; break;
- default: state = state_IGNORE;
- }
- break;
-
- case state_M10:
- state = (c == '8') ? state_M108 : state_IGNORE;
- break;
-
- case state_M11:
- state = (c == '2') ? state_M112 : state_IGNORE;
- break;
-
- case state_M4:
- state = (c == '1') ? state_M41 : state_IGNORE;
- break;
-
- case state_M41:
- state = (c == '0') ? state_M410 : state_IGNORE;
- break;
-
- case state_IGNORE:
- if (c == '\n') state = state_RESET;
- break;
-
- default:
- if (c == '\n') {
- switch (state) {
- case state_M108:
- wait_for_user = wait_for_heatup = false;
- break;
- case state_M112:
- killed_by_M112 = true;
- break;
- case state_M410:
- quickstop_stepper();
- break;
- default:
- break;
- }
- state = state_RESET;
- }
- }
- }
-
- #endif // EMERGENCY_PARSER
+ #include "emergency_parser.h"
+ #endif
FORCE_INLINE void store_rxd_char() {
const ring_buffer_pos_t h = rx_buffer.head,
@@ -246,7 +156,7 @@
#endif // SERIAL_XON_XOFF
#if ENABLED(EMERGENCY_PARSER)
- emergency_parser(c);
+ emergency_parser.update(c);
#endif
}
diff --git a/Marlin/MarlinSerial.h b/Marlin/MarlinSerial.h
index 0cd15a599..9060f668a 100644
--- a/Marlin/MarlinSerial.h
+++ b/Marlin/MarlinSerial.h
@@ -101,10 +101,6 @@
extern ring_buffer_pos_t rx_max_enqueued;
#endif
- #if ENABLED(EMERGENCY_PARSER)
- extern bool killed_by_M112;
- #endif
-
class MarlinSerial { //: public Stream
public:
diff --git a/Marlin/emergency_parser.cpp b/Marlin/emergency_parser.cpp
new file mode 100644
index 000000000..c1cab3a2c
--- /dev/null
+++ b/Marlin/emergency_parser.cpp
@@ -0,0 +1,40 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+/**
+ * emergency_parser.cpp - Intercept special commands directly in the serial stream
+ */
+
+#include "MarlinConfig.h"
+
+#if ENABLED(EMERGENCY_PARSER)
+
+#include "emergency_parser.h"
+
+// Static data members
+bool EmergencyParser::killed_by_M112; // = false
+EmergencyParser::State EmergencyParser::state; // = EP_RESET
+
+// Global instance
+EmergencyParser emergency_parser;
+
+#endif // EMERGENCY_PARSER
diff --git a/Marlin/emergency_parser.h b/Marlin/emergency_parser.h
new file mode 100644
index 000000000..73981cc38
--- /dev/null
+++ b/Marlin/emergency_parser.h
@@ -0,0 +1,144 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+/**
+ * emergency_parser.h - Intercept special commands directly in the serial stream
+ */
+
+#ifndef _EMERGENCY_PARSER_H_
+#define _EMERGENCY_PARSER_H_
+
+// External references
+extern volatile bool wait_for_user, wait_for_heatup;
+void quickstop_stepper();
+
+class EmergencyParser {
+
+public:
+
+ // Currently looking for: M108, M112, M410
+ enum State : char {
+ EP_RESET,
+ EP_N,
+ EP_M,
+ EP_M1,
+ EP_M10,
+ EP_M108,
+ EP_M11,
+ EP_M112,
+ EP_M4,
+ EP_M41,
+ EP_M410,
+ EP_IGNORE // to '\n'
+ };
+
+ static bool killed_by_M112;
+ static State state;
+
+ EmergencyParser() {}
+
+ __attribute__((always_inline)) inline
+ static void update(const uint8_t c) {
+
+ switch (state) {
+ case EP_RESET:
+ switch (c) {
+ case ' ': break;
+ case 'N': state = EP_N; break;
+ case 'M': state = EP_M; break;
+ default: state = EP_IGNORE;
+ }
+ break;
+
+ case EP_N:
+ switch (c) {
+ case '0': case '1': case '2':
+ case '3': case '4': case '5':
+ case '6': case '7': case '8':
+ case '9': case '-': case ' ': break;
+ case 'M': state = EP_M; break;
+ default: state = EP_IGNORE;
+ }
+ break;
+
+ case EP_M:
+ switch (c) {
+ case ' ': break;
+ case '1': state = EP_M1; break;
+ case '4': state = EP_M4; break;
+ default: state = EP_IGNORE;
+ }
+ break;
+
+ case EP_M1:
+ switch (c) {
+ case '0': state = EP_M10; break;
+ case '1': state = EP_M11; break;
+ default: state = EP_IGNORE;
+ }
+ break;
+
+ case EP_M10:
+ state = (c == '8') ? EP_M108 : EP_IGNORE;
+ break;
+
+ case EP_M11:
+ state = (c == '2') ? EP_M112 : EP_IGNORE;
+ break;
+
+ case EP_M4:
+ state = (c == '1') ? EP_M41 : EP_IGNORE;
+ break;
+
+ case EP_M41:
+ state = (c == '0') ? EP_M410 : EP_IGNORE;
+ break;
+
+ case EP_IGNORE:
+ if (c == '\n') state = EP_RESET;
+ break;
+
+ default:
+ if (c == '\n') {
+ switch (state) {
+ case EP_M108:
+ wait_for_user = wait_for_heatup = false;
+ break;
+ case EP_M112:
+ killed_by_M112 = true;
+ break;
+ case EP_M410:
+ quickstop_stepper();
+ break;
+ default:
+ break;
+ }
+ state = EP_RESET;
+ }
+ }
+ }
+
+};
+
+extern EmergencyParser emergency_parser;
+
+#endif // _EMERGENCY_PARSER_H_
diff --git a/Marlin/enum.h b/Marlin/enum.h
index 8764b8679..378e47f32 100644
--- a/Marlin/enum.h
+++ b/Marlin/enum.h
@@ -104,23 +104,6 @@ enum EndstopEnum : char {
Z2_MAX
};
-#if ENABLED(EMERGENCY_PARSER)
- enum e_parser_state : char {
- state_RESET,
- state_N,
- state_M,
- state_M1,
- state_M10,
- state_M108,
- state_M11,
- state_M112,
- state_M4,
- state_M41,
- state_M410,
- state_IGNORE // to '\n'
- };
-#endif
-
#if ENABLED(ADVANCED_PAUSE_FEATURE)
enum AdvancedPauseMenuResponse : char {
ADVANCED_PAUSE_RESPONSE_WAIT_FOR,
diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp
index e1e845164..ca9b814bf 100644
--- a/Marlin/temperature.cpp
+++ b/Marlin/temperature.cpp
@@ -48,6 +48,10 @@
#include "watchdog.h"
#endif
+#if ENABLED(EMERGENCY_PARSER)
+ #include "emergency_parser.h"
+#endif
+
#if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
static void* heater_ttbl_map[2] = { (void*)HEATER_0_TEMPTABLE, (void*)HEATER_1_TEMPTABLE };
static uint8_t heater_ttbllen_map[2] = { HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN };
@@ -773,7 +777,7 @@ void Temperature::manage_heater() {
#endif
#if ENABLED(EMERGENCY_PARSER)
- if (killed_by_M112) kill(PSTR(MSG_KILLED));
+ if (emergency_parser.killed_by_M112) kill(PSTR(MSG_KILLED));
#endif
if (!temp_meas_ready) return;