diff --git a/Marlin/MarlinSerial.cpp b/Marlin/MarlinSerial.cpp index 24a0222566..0207be3166 100644 --- a/Marlin/MarlinSerial.cpp +++ b/Marlin/MarlinSerial.cpp @@ -71,6 +71,14 @@ uint8_t rx_dropped_bytes = 0; #endif + #if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS) + uint8_t rx_buffer_overruns = 0; + #endif + + #if ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS) + uint8_t rx_framing_errors = 0; + #endif + #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) ring_buffer_pos_t rx_max_enqueued = 0; #endif @@ -94,6 +102,19 @@ // Get the next element ring_buffer_pos_t i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(RX_BUFFER_SIZE - 1); + // This must read the M_UCSRxA register before reading the received byte to detect error causes + #if ENABLED(SERIAL_STATS_DROPPED_RX) + if (TEST(M_UCSRxA, M_DORx) && !++rx_dropped_bytes) --rx_dropped_bytes; + #endif + + #if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS) + if (TEST(M_UCSRxA, M_DORx) && !++rx_buffer_overruns) --rx_buffer_overruns; + #endif + + #if ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS) + if (TEST(M_UCSRxA, M_FEx) && !++rx_framing_errors) --rx_framing_errors; + #endif + // Read the character from the USART uint8_t c = M_UDRx; diff --git a/Marlin/MarlinSerial.h b/Marlin/MarlinSerial.h index 6de1c88dbc..d8bd5346c6 100644 --- a/Marlin/MarlinSerial.h +++ b/Marlin/MarlinSerial.h @@ -60,6 +60,9 @@ #define M_TXCx SERIAL_REGNAME(TXC,SERIAL_PORT,) #define M_RXCIEx SERIAL_REGNAME(RXCIE,SERIAL_PORT,) #define M_UDREx SERIAL_REGNAME(UDRE,SERIAL_PORT,) +#define M_FEx SERIAL_REGNAME(FE,SERIAL_PORT,) +#define M_DORx SERIAL_REGNAME(DOR,SERIAL_PORT,) +#define M_UPEx SERIAL_REGNAME(UPE,SERIAL_PORT,) #define M_UDRIEx SERIAL_REGNAME(UDRIE,SERIAL_PORT,) #define M_UDRx SERIAL_REGNAME(UDR,SERIAL_PORT,) #define M_UBRRxH SERIAL_REGNAME(UBRR,SERIAL_PORT,H) @@ -98,6 +101,14 @@ extern uint8_t rx_dropped_bytes; #endif + #if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS) + extern uint8_t rx_buffer_overruns; + #endif + + #if ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS) + extern uint8_t rx_framing_errors; + #endif + #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) extern ring_buffer_pos_t rx_max_enqueued; #endif @@ -119,6 +130,14 @@ FORCE_INLINE static uint32_t dropped() { return rx_dropped_bytes; } #endif + #if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS) + FORCE_INLINE static uint32_t buffer_overruns() { return rx_buffer_overruns; } + #endif + + #if ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS) + FORCE_INLINE static uint32_t framing_errors() { return rx_framing_errors; } + #endif + #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return rx_max_enqueued; } #endif diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index dd44cc073d..cf1cdb1191 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -8364,6 +8364,23 @@ inline void gcode_M111() { } else { SERIAL_ECHOPGM(MSG_DEBUG_OFF); + #if !defined(__AVR__) || !defined(USBCON) + #if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS) + SERIAL_ECHOLNPAIR("Buffer Overruns: ", customizedSerial.buffer_overruns()); + #endif + + #if ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS) + SERIAL_ECHOLNPAIR("Framing Errors: ", customizedSerial.framing_errors()); + #endif + + #if ENABLED(SERIAL_STATS_DROPPED_RX) + SERIAL_ECHOLNPAIR("Dropped bytes: ", customizedSerial.dropped()); + #endif + + #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) + SERIAL_ECHOLNPAIR("Max RX Queue Size: ", customizedSerial.rxMaxEnqueued()); + #endif + #endif // !__AVR__ || !USBCON } SERIAL_EOL(); }