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;