diff --git a/Marlin/src/HAL/STM32F1/HAL.h b/Marlin/src/HAL/STM32F1/HAL.h
index 5a0b046009..f76d8c54a0 100644
--- a/Marlin/src/HAL/STM32F1/HAL.h
+++ b/Marlin/src/HAL/STM32F1/HAL.h
@@ -46,6 +46,8 @@
#include "msc_sd.h"
#endif
+#include "MarlinSerial.h"
+
// ------------------------
// Defines
// ------------------------
@@ -64,17 +66,6 @@
#else
#define UsbSerial MarlinCompositeSerial
#endif
- #define MSerial1 Serial1
- #define MSerial2 Serial2
- #define MSerial3 Serial3
- #define MSerial4 Serial4
- #define MSerial5 Serial5
-#else
- #define MSerial1 Serial
- #define MSerial2 Serial1
- #define MSerial3 Serial2
- #define MSerial4 Serial3
- #define MSerial5 Serial4
#endif
#if SERIAL_PORT == 0
diff --git a/Marlin/src/HAL/STM32F1/MarlinSerial.cpp b/Marlin/src/HAL/STM32F1/MarlinSerial.cpp
new file mode 100644
index 0000000000..f965bc99cf
--- /dev/null
+++ b/Marlin/src/HAL/STM32F1/MarlinSerial.cpp
@@ -0,0 +1,93 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 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 .
+ *
+ */
+
+#include "../../inc/MarlinConfigPre.h"
+#include "MarlinSerial.h"
+#include
+
+// Copied from ~/.platformio/packages/framework-arduinoststm32-maple/STM32F1/system/libmaple/usart_private.h
+// Changed to handle Emergency Parser
+static inline __always_inline void my_usart_irq(ring_buffer *rb, ring_buffer *wb, usart_reg_map *regs, MarlinSerial &serial) {
+ /* Handle RXNEIE and TXEIE interrupts.
+ * RXNE signifies availability of a byte in DR.
+ *
+ * See table 198 (sec 27.4, p809) in STM document RM0008 rev 15.
+ * We enable RXNEIE.
+ */
+ if ((regs->CR1 & USART_CR1_RXNEIE) && (regs->SR & USART_SR_RXNE)) {
+ uint8_t c = (uint8)regs->DR;
+ #ifdef USART_SAFE_INSERT
+ // If the buffer is full and the user defines USART_SAFE_INSERT,
+ // ignore new bytes.
+ rb_safe_insert(rb, c);
+ #else
+ // By default, push bytes around in the ring buffer.
+ rb_push_insert(rb, c);
+ #endif
+ #if ENABLED(EMERGENCY_PARSER)
+ emergency_parser.update(serial.emergency_state, c);
+ #endif
+ }
+ // TXE signifies readiness to send a byte to DR.
+ if ((regs->CR1 & USART_CR1_TXEIE) && (regs->SR & USART_SR_TXE)) {
+ if (!rb_is_empty(wb))
+ regs->DR=rb_remove(wb);
+ else
+ regs->CR1 &= ~((uint32)USART_CR1_TXEIE); // disable TXEIE
+ }
+}
+
+#define DEFINE_HWSERIAL_MARLIN(name, n) \
+ MarlinSerial name(USART##n, \
+ BOARD_USART##n##_TX_PIN, \
+ BOARD_USART##n##_RX_PIN); \
+ extern "C" void __irq_usart##n(void) { \
+ my_usart_irq(USART##n->rb, USART##n->wb, USART##n##_BASE, MSerial##n); \
+ }
+
+#define DEFINE_HWSERIAL_UART_MARLIN(name, n) \
+ MarlinSerial name(UART##n, \
+ BOARD_USART##n##_TX_PIN, \
+ BOARD_USART##n##_RX_PIN); \
+ extern "C" void __irq_usart##n(void) { \
+ my_usart_irq(USART##n->rb, USART##n->wb, USART##n##_BASE, MSerial##n); \
+ }
+
+#if SERIAL_PORT == 1 || SERIAL_PORT_2 == 1 || DGUS_SERIAL_PORT == 1
+ DEFINE_HWSERIAL_MARLIN(MSerial1, 1);
+#endif
+
+#if SERIAL_PORT == 2 || SERIAL_PORT_2 == 2 || DGUS_SERIAL_PORT == 2
+ DEFINE_HWSERIAL_MARLIN(MSerial2, 2);
+#endif
+
+#if SERIAL_PORT == 3 || SERIAL_PORT_2 == 3 || DGUS_SERIAL_PORT == 3
+ DEFINE_HWSERIAL_MARLIN(MSerial3, 3);
+#endif
+
+#if SERIAL_PORT == 4 || SERIAL_PORT_2 == 4 || DGUS_SERIAL_PORT == 4
+ DEFINE_HWSERIAL_UART_MARLIN(MSerial4, 4);
+#endif
+
+#if SERIAL_PORT == 5 || SERIAL_PORT_2 == 5 || DGUS_SERIAL_PORT == 5
+ DEFINE_HWSERIAL_UART_MARLIN(MSerial5, 5);
+#endif
diff --git a/Marlin/src/HAL/STM32F1/MarlinSerial.h b/Marlin/src/HAL/STM32F1/MarlinSerial.h
new file mode 100644
index 0000000000..4e8a47d2f9
--- /dev/null
+++ b/Marlin/src/HAL/STM32F1/MarlinSerial.h
@@ -0,0 +1,50 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 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 .
+ *
+ */
+#pragma once
+
+#include
+#include
+
+#include "../../inc/MarlinConfigPre.h"
+#if ENABLED(EMERGENCY_PARSER)
+ #include "../../feature/e_parser.h"
+#endif
+
+class MarlinSerial : public HardwareSerial {
+public:
+ MarlinSerial(struct usart_dev *usart_device, uint8 tx_pin, uint8 rx_pin) :
+ HardwareSerial(usart_device, tx_pin, rx_pin)
+ #if ENABLED(EMERGENCY_PARSER)
+ , emergency_state(EmergencyParser::State::EP_RESET)
+ #endif
+ { }
+
+ #if ENABLED(EMERGENCY_PARSER)
+ EmergencyParser::State emergency_state;
+ #endif
+};
+
+extern MarlinSerial MSerial1;
+extern MarlinSerial MSerial2;
+extern MarlinSerial MSerial3;
+extern MarlinSerial MSerial4;
+extern MarlinSerial MSerial5;
diff --git a/Marlin/src/HAL/STM32F1/inc/SanityCheck.h b/Marlin/src/HAL/STM32F1/inc/SanityCheck.h
index c0cb486952..9d5026fbab 100644
--- a/Marlin/src/HAL/STM32F1/inc/SanityCheck.h
+++ b/Marlin/src/HAL/STM32F1/inc/SanityCheck.h
@@ -25,10 +25,6 @@
* Test STM32F1-specific configuration values for errors at compile-time.
*/
-#if ENABLED(EMERGENCY_PARSER)
- #error "EMERGENCY_PARSER is not yet implemented for STM32F1. Disable EMERGENCY_PARSER to continue."
-#endif
-
#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY
#error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on STM32F1."
#endif