From 25789966316195f779f6578f9a18c5f7068f6dc4 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Wed, 25 Apr 2018 20:58:00 -0500 Subject: [PATCH] [2.0.x] Emergency parser for multiple serial ports (#10524) --- Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp | 6 +- Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.cpp | 6 +- Marlin/src/HAL/HAL_LPC1768/HardwareSerial.cpp | 8 +- Marlin/src/HAL/HAL_LPC1768/HardwareSerial.h | 13 ++- Marlin/src/HAL/HAL_LPC1768/include/serial.h | 10 +++ Marlin/src/feature/emergency_parser.cpp | 86 +----------------- Marlin/src/feature/emergency_parser.h | 90 ++++++++++++++++++- frameworks/CMSIS/LPC1768/lib/usb/cdcuser.cpp | 8 +- 8 files changed, 121 insertions(+), 106 deletions(-) diff --git a/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp b/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp index a9ce865ca2..7d10ca74b8 100644 --- a/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp +++ b/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp @@ -85,6 +85,10 @@ FORCE_INLINE void store_rxd_char() { + #if ENABLED(EMERGENCY_PARSER) + static EmergencyParser::State emergency_state; // = EP_RESET + #endif + const ring_buffer_pos_t h = rx_buffer.head, i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1); @@ -160,7 +164,7 @@ #endif // SERIAL_XON_XOFF #if ENABLED(EMERGENCY_PARSER) - emergency_parser.update(c); + emergency_parser.update(emergency_state, c); #endif } diff --git a/Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.cpp b/Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.cpp index 22f33d89c6..8413c002ab 100644 --- a/Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.cpp +++ b/Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.cpp @@ -112,6 +112,10 @@ FORCE_INLINE void store_rxd_char() { + #if ENABLED(EMERGENCY_PARSER) + static EmergencyParser::State emergency_state; // = EP_RESET + #endif + const ring_buffer_pos_t h = rx_buffer.head, i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1); @@ -182,7 +186,7 @@ #endif // SERIAL_XON_XOFF #if ENABLED(EMERGENCY_PARSER) - emergency_parser.update(c); + emergency_parser.update(emergency_state, c); #endif } diff --git a/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.cpp b/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.cpp index fc2358b703..98ea4f8fc6 100644 --- a/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.cpp +++ b/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.cpp @@ -24,12 +24,6 @@ #include "HardwareSerial.h" -#include "../../inc/MarlinConfigPre.h" - -#if ENABLED(EMERGENCY_PARSER) - #include "../../feature/emergency_parser.h" -#endif - #if SERIAL_PORT == 0 || SERIAL_PORT_2 == 0 HardwareSerial Serial = HardwareSerial(LPC_UART0); #elif SERIAL_PORT == 1 || SERIAL_PORT_2 == 1 @@ -254,7 +248,7 @@ void HardwareSerial::IRQHandler() { // Clear the FIFO while (UART_Receive(UARTx, &byte, 1, NONE_BLOCKING)) { #if ENABLED(EMERGENCY_PARSER) - emergency_parser.update(byte); + emergency_parser.update(emergency_state, byte); #endif if ((RxQueueWritePos + 1) % RX_BUFFER_SIZE != RxQueueReadPos) { RxBuffer[RxQueueWritePos] = byte; diff --git a/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.h b/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.h index 33358d207c..0f96652410 100644 --- a/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.h +++ b/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.h @@ -23,6 +23,11 @@ #ifndef HARDWARE_SERIAL_H_ #define HARDWARE_SERIAL_H_ +#include "../../inc/MarlinConfigPre.h" +#if ENABLED(EMERGENCY_PARSER) + #include "../../feature/emergency_parser.h" +#endif + #include #include #include @@ -32,8 +37,6 @@ extern "C" { #include "lpc17xx_pinsel.h" } -#include "../../inc/MarlinConfigPre.h" - class HardwareSerial : public Stream { private: LPC_UART_TypeDef *UARTx; @@ -48,6 +51,9 @@ private: uint32_t TxQueueWritePos; uint32_t TxQueueReadPos; #endif + #if ENABLED(EMERGENCY_PARSER) + EmergencyParser::State emergency_state; + #endif public: HardwareSerial(LPC_UART_TypeDef *UARTx) @@ -59,6 +65,9 @@ public: , TxQueueWritePos(0) , TxQueueReadPos(0) #endif + #if ENABLED(EMERGENCY_PARSER) + , emergency_state(EmergencyParser::State::EP_RESET) + #endif { } diff --git a/Marlin/src/HAL/HAL_LPC1768/include/serial.h b/Marlin/src/HAL/HAL_LPC1768/include/serial.h index 782db40536..fd5c58254c 100644 --- a/Marlin/src/HAL/HAL_LPC1768/include/serial.h +++ b/Marlin/src/HAL/HAL_LPC1768/include/serial.h @@ -23,6 +23,11 @@ #ifndef _HAL_SERIAL_H_ #define _HAL_SERIAL_H_ +#include "../../../inc/MarlinConfigPre.h" +#if ENABLED(EMERGENCY_PARSER) + #include "../../../feature/emergency_parser.h" +#endif + #include #include @@ -73,6 +78,11 @@ private: class HalSerial { public: + + #if ENABLED(EMERGENCY_PARSER) + EmergencyParser::State emergency_state; + #endif + HalSerial() { host_connected = false; } void begin(int32_t baud) { diff --git a/Marlin/src/feature/emergency_parser.cpp b/Marlin/src/feature/emergency_parser.cpp index c914e2dab0..3c9cbf12e5 100644 --- a/Marlin/src/feature/emergency_parser.cpp +++ b/Marlin/src/feature/emergency_parser.cpp @@ -30,92 +30,10 @@ #include "emergency_parser.h" -extern volatile bool wait_for_user, wait_for_heatup; -void quickstop_stepper(); - -EmergencyParser::State EmergencyParser::state = EP_RESET; +// Static data members bool EmergencyParser::killed_by_M112; // = false +// Global instance EmergencyParser emergency_parser; -void EmergencyParser::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; - } - } -} - #endif // EMERGENCY_PARSER diff --git a/Marlin/src/feature/emergency_parser.h b/Marlin/src/feature/emergency_parser.h index be2bf3d7a2..127b5c20da 100644 --- a/Marlin/src/feature/emergency_parser.h +++ b/Marlin/src/feature/emergency_parser.h @@ -27,8 +27,14 @@ #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, @@ -45,14 +51,90 @@ class EmergencyParser { EP_IGNORE // to '\n' }; -public: - - static EmergencyParser::State state; static bool killed_by_M112; EmergencyParser() {} - static void update(const uint8_t c); + __attribute__((always_inline)) inline + static void update(State &state, 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; + } + } + } }; diff --git a/frameworks/CMSIS/LPC1768/lib/usb/cdcuser.cpp b/frameworks/CMSIS/LPC1768/lib/usb/cdcuser.cpp index 9aa8cd6114..8fd08f00eb 100644 --- a/frameworks/CMSIS/LPC1768/lib/usb/cdcuser.cpp +++ b/frameworks/CMSIS/LPC1768/lib/usb/cdcuser.cpp @@ -39,12 +39,6 @@ unsigned short CDC_DepInEmpty = 1; // Data IN EP is empty unsigned short CDC_LineState = 0; unsigned short CDC_SerialState = 0; -#include "../../../../../Marlin/src/inc/MarlinConfigPre.h" - -#if ENABLED(EMERGENCY_PARSER) - #include "../../../../../Marlin/src/feature/emergency_parser.h" -#endif - extern HalSerial usb_serial; /*---------------------------------------------------------------------------- write data to CDC_OutBuf @@ -58,7 +52,7 @@ uint32_t CDC_WrOutBuf(const char *buffer, uint32_t *length) { while (bytesToWrite) { #if ENABLED(EMERGENCY_PARSER) - emergency_parser.update(*buffer); + emergency_parser.update(usb_serial.emergency_state, *buffer); #endif usb_serial.receive_buffer.write(*buffer++); // Copy Data to buffer bytesToWrite--;