[2.0.x] Emergency parser for multiple serial ports (#10524)
This commit is contained in:
parent
8cc31d1b2e
commit
2578996631
8 changed files with 121 additions and 106 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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--;
|
||||||
|
|
Reference in a new issue