[2.0.x] Emergency parser for multiple serial ports (#10524)

This commit is contained in:
Scott Lahteine 2018-04-25 20:58:00 -05:00 committed by GitHub
parent 8cc31d1b2e
commit 2578996631
Signed by: GitHub
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 121 additions and 106 deletions

View file

@ -85,6 +85,10 @@
FORCE_INLINE void store_rxd_char() { 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, const ring_buffer_pos_t h = rx_buffer.head,
i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1); i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1);
@ -160,7 +164,7 @@
#endif // SERIAL_XON_XOFF #endif // SERIAL_XON_XOFF
#if ENABLED(EMERGENCY_PARSER) #if ENABLED(EMERGENCY_PARSER)
emergency_parser.update(c); emergency_parser.update(emergency_state, c);
#endif #endif
} }

View file

@ -112,6 +112,10 @@
FORCE_INLINE void store_rxd_char() { 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, const ring_buffer_pos_t h = rx_buffer.head,
i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1); i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1);
@ -182,7 +186,7 @@
#endif // SERIAL_XON_XOFF #endif // SERIAL_XON_XOFF
#if ENABLED(EMERGENCY_PARSER) #if ENABLED(EMERGENCY_PARSER)
emergency_parser.update(c); emergency_parser.update(emergency_state, c);
#endif #endif
} }

View file

@ -24,12 +24,6 @@
#include "HardwareSerial.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 #if SERIAL_PORT == 0 || SERIAL_PORT_2 == 0
HardwareSerial Serial = HardwareSerial(LPC_UART0); HardwareSerial Serial = HardwareSerial(LPC_UART0);
#elif SERIAL_PORT == 1 || SERIAL_PORT_2 == 1 #elif SERIAL_PORT == 1 || SERIAL_PORT_2 == 1
@ -254,7 +248,7 @@ void HardwareSerial::IRQHandler() {
// Clear the FIFO // Clear the FIFO
while (UART_Receive(UARTx, &byte, 1, NONE_BLOCKING)) { while (UART_Receive(UARTx, &byte, 1, NONE_BLOCKING)) {
#if ENABLED(EMERGENCY_PARSER) #if ENABLED(EMERGENCY_PARSER)
emergency_parser.update(byte); emergency_parser.update(emergency_state, byte);
#endif #endif
if ((RxQueueWritePos + 1) % RX_BUFFER_SIZE != RxQueueReadPos) { if ((RxQueueWritePos + 1) % RX_BUFFER_SIZE != RxQueueReadPos) {
RxBuffer[RxQueueWritePos] = byte; RxBuffer[RxQueueWritePos] = byte;

View file

@ -23,6 +23,11 @@
#ifndef HARDWARE_SERIAL_H_ #ifndef HARDWARE_SERIAL_H_
#define HARDWARE_SERIAL_H_ #define HARDWARE_SERIAL_H_
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(EMERGENCY_PARSER)
#include "../../feature/emergency_parser.h"
#endif
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <Stream.h> #include <Stream.h>
@ -32,8 +37,6 @@ extern "C" {
#include "lpc17xx_pinsel.h" #include "lpc17xx_pinsel.h"
} }
#include "../../inc/MarlinConfigPre.h"
class HardwareSerial : public Stream { class HardwareSerial : public Stream {
private: private:
LPC_UART_TypeDef *UARTx; LPC_UART_TypeDef *UARTx;
@ -48,6 +51,9 @@ private:
uint32_t TxQueueWritePos; uint32_t TxQueueWritePos;
uint32_t TxQueueReadPos; uint32_t TxQueueReadPos;
#endif #endif
#if ENABLED(EMERGENCY_PARSER)
EmergencyParser::State emergency_state;
#endif
public: public:
HardwareSerial(LPC_UART_TypeDef *UARTx) HardwareSerial(LPC_UART_TypeDef *UARTx)
@ -59,6 +65,9 @@ public:
, TxQueueWritePos(0) , TxQueueWritePos(0)
, TxQueueReadPos(0) , TxQueueReadPos(0)
#endif #endif
#if ENABLED(EMERGENCY_PARSER)
, emergency_state(EmergencyParser::State::EP_RESET)
#endif
{ {
} }

View file

@ -23,6 +23,11 @@
#ifndef _HAL_SERIAL_H_ #ifndef _HAL_SERIAL_H_
#define _HAL_SERIAL_H_ #define _HAL_SERIAL_H_
#include "../../../inc/MarlinConfigPre.h"
#if ENABLED(EMERGENCY_PARSER)
#include "../../../feature/emergency_parser.h"
#endif
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
@ -73,6 +78,11 @@ private:
class HalSerial { class HalSerial {
public: public:
#if ENABLED(EMERGENCY_PARSER)
EmergencyParser::State emergency_state;
#endif
HalSerial() { host_connected = false; } HalSerial() { host_connected = false; }
void begin(int32_t baud) { void begin(int32_t baud) {

View file

@ -30,92 +30,10 @@
#include "emergency_parser.h" #include "emergency_parser.h"
extern volatile bool wait_for_user, wait_for_heatup; // Static data members
void quickstop_stepper();
EmergencyParser::State EmergencyParser::state = EP_RESET;
bool EmergencyParser::killed_by_M112; // = false bool EmergencyParser::killed_by_M112; // = false
// Global instance
EmergencyParser emergency_parser; 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 #endif // EMERGENCY_PARSER

View file

@ -27,8 +27,14 @@
#ifndef _EMERGENCY_PARSER_H_ #ifndef _EMERGENCY_PARSER_H_
#define _EMERGENCY_PARSER_H_ #define _EMERGENCY_PARSER_H_
// External references
extern volatile bool wait_for_user, wait_for_heatup;
void quickstop_stepper();
class EmergencyParser { class EmergencyParser {
public:
// Currently looking for: M108, M112, M410 // Currently looking for: M108, M112, M410
enum State : char { enum State : char {
EP_RESET, EP_RESET,
@ -45,14 +51,90 @@ class EmergencyParser {
EP_IGNORE // to '\n' EP_IGNORE // to '\n'
}; };
public:
static EmergencyParser::State state;
static bool killed_by_M112; static bool killed_by_M112;
EmergencyParser() {} 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;
}
}
}
}; };

View file

@ -39,12 +39,6 @@ unsigned short CDC_DepInEmpty = 1; // Data IN EP is empty
unsigned short CDC_LineState = 0; unsigned short CDC_LineState = 0;
unsigned short CDC_SerialState = 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; extern HalSerial usb_serial;
/*---------------------------------------------------------------------------- /*----------------------------------------------------------------------------
write data to CDC_OutBuf write data to CDC_OutBuf
@ -58,7 +52,7 @@ uint32_t CDC_WrOutBuf(const char *buffer, uint32_t *length) {
while (bytesToWrite) { while (bytesToWrite) {
#if ENABLED(EMERGENCY_PARSER) #if ENABLED(EMERGENCY_PARSER)
emergency_parser.update(*buffer); emergency_parser.update(usb_serial.emergency_state, *buffer);
#endif #endif
usb_serial.receive_buffer.write(*buffer++); // Copy Data to buffer usb_serial.receive_buffer.write(*buffer++); // Copy Data to buffer
bytesToWrite--; bytesToWrite--;