diff --git a/Marlin/src/HAL/STM32F1/HAL.cpp b/Marlin/src/HAL/STM32F1/HAL.cpp
index c1e29a843c..2f29b9b0e3 100644
--- a/Marlin/src/HAL/STM32F1/HAL.cpp
+++ b/Marlin/src/HAL/STM32F1/HAL.cpp
@@ -84,7 +84,32 @@
 
 #if defined(SERIAL_USB) && !HAS_SD_HOST_DRIVE
   USBSerial SerialUSB;
-  DefaultSerial MSerial(false, SerialUSB);
+  DefaultSerial MSerial(true, SerialUSB);
+
+  #if ENABLED(EMERGENCY_PARSER)
+    #include "../libmaple/usb/stm32f1/usb_reg_map.h"
+    #include "libmaple/usb_cdcacm.h"
+    // The original callback is not called (no way to retrieve address).
+    // That callback detects a special STM32 reset sequence: this functionality is not essential
+    // as M997 achieves the same.
+    void my_rx_callback(unsigned int, void*) {
+      // max length of 16 is enough to contain all emergency commands
+      uint8 buf[16];
+
+      //rx is usbSerialPart.endpoints[2]
+      uint16 len = usb_get_ep_rx_count(USB_CDCACM_RX_ENDP);
+      uint32 total = usb_cdcacm_data_available();
+
+      if (len == 0 || total == 0 || !WITHIN(total, len, COUNT(buf)))
+        return;
+
+      // cannot get character by character due to bug in composite_cdcacm_peek_ex
+      len = usb_cdcacm_peek(buf, total);
+
+      for (uint32 i = 0; i < len; i++)
+        emergency_parser.update(MSerial.emergency_state, buf[i + total - len]);
+    }
+  #endif
 #endif
 
 uint16_t HAL_adc_result;
@@ -254,6 +279,8 @@ void HAL_init() {
   #endif
   #if HAS_SD_HOST_DRIVE
     MSC_SD_init();
+  #elif BOTH(SERIAL_USB, EMERGENCY_PARSER)
+    usb_cdcacm_set_hooks(USB_CDCACM_HOOK_RX, my_rx_callback);
   #endif
   #if PIN_EXISTS(USB_CONNECT)
     OUT_WRITE(USB_CONNECT_PIN, !USB_CONNECT_INVERTING);  // USB clear connection
diff --git a/Marlin/src/HAL/STM32F1/msc_sd.cpp b/Marlin/src/HAL/STM32F1/msc_sd.cpp
index 548a6dbc57..a916184999 100644
--- a/Marlin/src/HAL/STM32F1/msc_sd.cpp
+++ b/Marlin/src/HAL/STM32F1/msc_sd.cpp
@@ -19,6 +19,7 @@
 
 #include "msc_sd.h"
 #include "SPI.h"
+#include "usb_reg_map.h"
 
 #define PRODUCT_ID 0x29
 
@@ -41,14 +42,27 @@ Serial0Type<USBCompositeSerial> MarlinCompositeSerial(true);
 #endif
 
 #if ENABLED(EMERGENCY_PARSER)
-  void (*real_rx_callback)(void);
 
-  void my_rx_callback(void) {
-    real_rx_callback();
-    int len = MarlinCompositeSerial.available();
-    while (len-- > 0) // >0 because available() may return a negative value
-      emergency_parser.update(MarlinCompositeSerial.emergency_state, MarlinCompositeSerial.peek());
-  }
+// The original callback is not called (no way to retrieve address).
+// That callback detects a special STM32 reset sequence: this functionality is not essential
+// as M997 achieves the same.
+void my_rx_callback(unsigned int, void*) {
+  // max length of 16 is enough to contain all emergency commands
+  uint8 buf[16];
+
+  //rx is usbSerialPart.endpoints[2]
+  uint16 len = usb_get_ep_rx_count(usbSerialPart.endpoints[2].address);
+  uint32 total = composite_cdcacm_data_available();
+
+  if (len == 0 || total == 0 || !WITHIN(total, len, COUNT(buf)))
+    return;
+
+  // cannot get character by character due to bug in composite_cdcacm_peek_ex
+  len = composite_cdcacm_peek(buf, total);
+
+  for (uint32 i = 0; i < len; i++)
+    emergency_parser.update(MarlinCompositeSerial.emergency_state, buf[i+total-len]);
+}
 #endif
 
 void MSC_SD_init() {
@@ -73,9 +87,7 @@ void MSC_SD_init() {
   MarlinCompositeSerial.registerComponent();
   USBComposite.begin();
   #if ENABLED(EMERGENCY_PARSER)
-    //rx is usbSerialPart.endpoints[2]
-    real_rx_callback = usbSerialPart.endpoints[2].callback;
-    usbSerialPart.endpoints[2].callback = my_rx_callback;
+  	composite_cdcacm_set_hooks(USBHID_CDCACM_HOOK_RX, my_rx_callback);
   #endif
 }