From 2242b98248a50a2a3a8a29c9ec4f40308a2a0450 Mon Sep 17 00:00:00 2001 From: Chris Pepper Date: Wed, 25 Apr 2018 12:44:26 +0100 Subject: [PATCH] [LPC176x] Emergency Parser Feature (#10516) --- Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp | 95 +------------- Marlin/src/HAL/HAL_AVR/MarlinSerial.h | 4 - Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.cpp | 93 +------------- Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.h | 4 - Marlin/src/HAL/HAL_LPC1768/HardwareSerial.cpp | 10 +- Marlin/src/HAL/HAL_LPC1768/HardwareSerial.h | 4 +- Marlin/src/HAL/HAL_LPC1768/SanityCheck.h | 4 - Marlin/src/HAL/HAL_LPC1768/include/Arduino.h | 1 + Marlin/src/HAL/HAL_LPC1768/include/serial.h | 4 - Marlin/src/HAL/HAL_LPC1768/watchdog.cpp | 3 + Marlin/src/core/serial.h | 17 --- Marlin/src/feature/emergency_parser.cpp | 121 ++++++++++++++++++ Marlin/src/feature/emergency_parser.h | 61 +++++++++ Marlin/src/module/temperature.cpp | 6 +- frameworks/CMSIS/LPC1768/lib/usb/cdcuser.cpp | 8 ++ 15 files changed, 216 insertions(+), 219 deletions(-) create mode 100644 Marlin/src/feature/emergency_parser.cpp create mode 100644 Marlin/src/feature/emergency_parser.h diff --git a/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp b/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp index c156594381..a9ce865ca2 100644 --- a/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp +++ b/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp @@ -80,97 +80,8 @@ #endif #if ENABLED(EMERGENCY_PARSER) - - bool killed_by_M112; // = false - - #include "../../module/stepper.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 uint8_t 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 "../../feature/emergency_parser.h" + #endif FORCE_INLINE void store_rxd_char() { @@ -249,7 +160,7 @@ #endif // SERIAL_XON_XOFF #if ENABLED(EMERGENCY_PARSER) - emergency_parser(c); + emergency_parser.update(c); #endif } diff --git a/Marlin/src/HAL/HAL_AVR/MarlinSerial.h b/Marlin/src/HAL/HAL_AVR/MarlinSerial.h index 5e21535e48..4bddd5f505 100644 --- a/Marlin/src/HAL/HAL_AVR/MarlinSerial.h +++ b/Marlin/src/HAL/HAL_AVR/MarlinSerial.h @@ -94,10 +94,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/src/HAL/HAL_DUE/MarlinSerial_Due.cpp b/Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.cpp index 0790c43464..22f33d89c6 100644 --- a/Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.cpp +++ b/Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.cpp @@ -107,95 +107,8 @@ #define sw_barrier() asm volatile("": : :"memory"); #if ENABLED(EMERGENCY_PARSER) - - bool killed_by_M112; // = false - - // 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 uint8_t 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 "../../feature/emergency_parser.h" + #endif FORCE_INLINE void store_rxd_char() { @@ -269,7 +182,7 @@ #endif // SERIAL_XON_XOFF #if ENABLED(EMERGENCY_PARSER) - emergency_parser(c); + emergency_parser.update(c); #endif } diff --git a/Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.h b/Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.h index 01dcd05d52..a28beaeb14 100644 --- a/Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.h +++ b/Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.h @@ -74,10 +74,6 @@ extern ring_buffer_pos_t rx_max_enqueued; #endif -#if ENABLED(EMERGENCY_PARSER) - extern bool killed_by_M112; -#endif - class MarlinSerial { public: diff --git a/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.cpp b/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.cpp index 6b575ca9d3..fc2358b703 100644 --- a/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.cpp +++ b/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.cpp @@ -22,9 +22,14 @@ #ifdef TARGET_LPC1768 -#include "../../inc/MarlinConfig.h" #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 @@ -248,6 +253,9 @@ void HardwareSerial::IRQHandler() { if (IIRValue == UART_IIR_INTID_RDA) { // Clear the FIFO while (UART_Receive(UARTx, &byte, 1, NONE_BLOCKING)) { + #if ENABLED(EMERGENCY_PARSER) + emergency_parser.update(byte); + #endif if ((RxQueueWritePos + 1) % RX_BUFFER_SIZE != RxQueueReadPos) { RxBuffer[RxQueueWritePos] = byte; RxQueueWritePos = (RxQueueWritePos + 1) % RX_BUFFER_SIZE; diff --git a/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.h b/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.h index 7796257240..33358d207c 100644 --- a/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.h +++ b/Marlin/src/HAL/HAL_LPC1768/HardwareSerial.h @@ -32,6 +32,8 @@ extern "C" { #include "lpc17xx_pinsel.h" } +#include "../../inc/MarlinConfigPre.h" + class HardwareSerial : public Stream { private: LPC_UART_TypeDef *UARTx; @@ -138,8 +140,6 @@ public: printf("%f" , value ); } - - void println(const char value[]) { printf("%s\n" , value); } diff --git a/Marlin/src/HAL/HAL_LPC1768/SanityCheck.h b/Marlin/src/HAL/HAL_LPC1768/SanityCheck.h index 16aef997d2..a408a6c587 100644 --- a/Marlin/src/HAL/HAL_LPC1768/SanityCheck.h +++ b/Marlin/src/HAL/HAL_LPC1768/SanityCheck.h @@ -74,7 +74,3 @@ || MB(RAMPS_14_RE_ARM_SF)) #error "Re-ARM with REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER and TMC2130 require TMC_USE_SW_SPI" #endif - -#if ENABLED(EMERGENCY_PARSER) - #error "EMERGENCY_PARSER is not yet implemented for LPC1768. Disable EMERGENCY_PARSER to continue." -#endif diff --git a/Marlin/src/HAL/HAL_LPC1768/include/Arduino.h b/Marlin/src/HAL/HAL_LPC1768/include/Arduino.h index 645a9c79ed..d43021b290 100644 --- a/Marlin/src/HAL/HAL_LPC1768/include/Arduino.h +++ b/Marlin/src/HAL/HAL_LPC1768/include/Arduino.h @@ -95,6 +95,7 @@ extern "C" void GpioDisableInt(uint32_t port, uint32_t pin); #define vsnprintf_P vsnprintf #define strcpy_P strcpy #define snprintf_P snprintf +#define strlen_P strlen // Time functions extern "C" { diff --git a/Marlin/src/HAL/HAL_LPC1768/include/serial.h b/Marlin/src/HAL/HAL_LPC1768/include/serial.h index b0c4b27cd7..782db40536 100644 --- a/Marlin/src/HAL/HAL_LPC1768/include/serial.h +++ b/Marlin/src/HAL/HAL_LPC1768/include/serial.h @@ -26,10 +26,6 @@ #include #include -extern "C" { -#include -} - /** * Generic RingBuffer * T type of the buffer array diff --git a/Marlin/src/HAL/HAL_LPC1768/watchdog.cpp b/Marlin/src/HAL/HAL_LPC1768/watchdog.cpp index 0c7f31bed0..589e05ebd6 100644 --- a/Marlin/src/HAL/HAL_LPC1768/watchdog.cpp +++ b/Marlin/src/HAL/HAL_LPC1768/watchdog.cpp @@ -50,6 +50,9 @@ void watchdog_reset() { #endif } +#else + void HAL_clear_reset_source(void) {} + uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; } #endif // USE_WATCHDOG #endif // TARGET_LPC1768 diff --git a/Marlin/src/core/serial.h b/Marlin/src/core/serial.h index f25791324a..335976d26e 100644 --- a/Marlin/src/core/serial.h +++ b/Marlin/src/core/serial.h @@ -44,23 +44,6 @@ enum DebugFlags : unsigned char { DEBUG_ALL = 0xFF }; -#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 - extern uint8_t marlin_debug_flags; #define DEBUGGING(F) (marlin_debug_flags & (DEBUG_## F)) diff --git a/Marlin/src/feature/emergency_parser.cpp b/Marlin/src/feature/emergency_parser.cpp new file mode 100644 index 0000000000..21b1f3c8fc --- /dev/null +++ b/Marlin/src/feature/emergency_parser.cpp @@ -0,0 +1,121 @@ +/** + * 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 "../inc/MarlinConfigPre.h" + +#if ENABLED(EMERGENCY_PARSER) + +#include "emergency_parser.h" + +extern volatile bool wait_for_user, wait_for_heatup; +void quickstop_stepper(); + +EmergencyParser::State EmergencyParser::state = EmergencyParser::State::RESET; +bool EmergencyParser::killed_by_M112; // = false + +EmergencyParser emergency_parser; + +void EmergencyParser::update(const uint8_t c) { + + switch (state) { + case EmergencyParser::State::RESET: + switch (c) { + case ' ': break; + case 'N': state = EmergencyParser::State::N; break; + case 'M': state = EmergencyParser::State::M; break; + default: state = EmergencyParser::State::IGNORE; + } + break; + + case EmergencyParser::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 = EmergencyParser::State::M; break; + default: state = EmergencyParser::State::IGNORE; + } + break; + + case EmergencyParser::State::M: + switch (c) { + case ' ': break; + case '1': state = EmergencyParser::State::M1; break; + case '4': state = EmergencyParser::State::M4; break; + default: state = EmergencyParser::State::IGNORE; + } + break; + + case EmergencyParser::State::M1: + switch (c) { + case '0': state = EmergencyParser::State::M10; break; + case '1': state = EmergencyParser::State::M11; break; + default: state = EmergencyParser::State::IGNORE; + } + break; + + case EmergencyParser::State::M10: + state = (c == '8') ? EmergencyParser::State::M108 : EmergencyParser::State::IGNORE; + break; + + case EmergencyParser::State::M11: + state = (c == '2') ? EmergencyParser::State::M112 : EmergencyParser::State::IGNORE; + break; + + case EmergencyParser::State::M4: + state = (c == '1') ? EmergencyParser::State::M41 : EmergencyParser::State::IGNORE; + break; + + case EmergencyParser::State::M41: + state = (c == '0') ? EmergencyParser::State::M410 : EmergencyParser::State::IGNORE; + break; + + case EmergencyParser::State::IGNORE: + if (c == '\n') state = EmergencyParser::State::RESET; + break; + + default: + if (c == '\n') { + switch (state) { + case EmergencyParser::State::M108: + wait_for_user = wait_for_heatup = false; + break; + case EmergencyParser::State::M112: + killed_by_M112 = true; + break; + case EmergencyParser::State::M410: + quickstop_stepper(); + break; + default: + break; + } + state = EmergencyParser::State::RESET; + } + } +} + +#endif // EMERGENCY_PARSER diff --git a/Marlin/src/feature/emergency_parser.h b/Marlin/src/feature/emergency_parser.h new file mode 100644 index 0000000000..140200be19 --- /dev/null +++ b/Marlin/src/feature/emergency_parser.h @@ -0,0 +1,61 @@ +/** + * 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_ + +class EmergencyParser { + + // Currently looking for: M108, M112, M410 + enum State : char { + RESET, + N, + M, + M1, + M10, + M108, + M11, + M112, + M4, + M41, + M410, + IGNORE // to '\n' + }; + +public: + + static EmergencyParser::State state; + static bool killed_by_M112; + + EmergencyParser() {} + + static void update(const uint8_t c); + +}; + +extern EmergencyParser emergency_parser; + +#endif // _EMERGENCY_PARSER_H_ diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index d5da6e4eb7..de5812dfd4 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -49,6 +49,10 @@ #include "../feature/filwidth.h" #endif +#if ENABLED(EMERGENCY_PARSER) + #include "../feature/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 }; @@ -792,7 +796,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; diff --git a/frameworks/CMSIS/LPC1768/lib/usb/cdcuser.cpp b/frameworks/CMSIS/LPC1768/lib/usb/cdcuser.cpp index a5b96c6f08..9aa8cd6114 100644 --- a/frameworks/CMSIS/LPC1768/lib/usb/cdcuser.cpp +++ b/frameworks/CMSIS/LPC1768/lib/usb/cdcuser.cpp @@ -39,6 +39,11 @@ 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; /*---------------------------------------------------------------------------- @@ -52,6 +57,9 @@ uint32_t CDC_WrOutBuf(const char *buffer, uint32_t *length) { bytesWritten = bytesToWrite; while (bytesToWrite) { + #if ENABLED(EMERGENCY_PARSER) + emergency_parser.update(*buffer); + #endif usb_serial.receive_buffer.write(*buffer++); // Copy Data to buffer bytesToWrite--; }