From 99af086cea57c8b6ead0cbd2fd717ceedeaf407b Mon Sep 17 00:00:00 2001 From: etagle Date: Sat, 9 Jun 2018 21:07:06 -0300 Subject: [PATCH] Add hidden Serial overflow debug options --- Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp | 21 +++++++++++++++++++++ Marlin/src/HAL/HAL_AVR/MarlinSerial.h | 19 +++++++++++++++++++ Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.cpp | 21 +++++++++++++++++++++ Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.h | 16 ++++++++++++++++ Marlin/src/gcode/control/M111.cpp | 17 +++++++++++++++++ 5 files changed, 94 insertions(+) diff --git a/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp b/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp index 35735802b..6c165a4af 100644 --- a/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp +++ b/Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp @@ -72,6 +72,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 @@ -99,6 +107,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/src/HAL/HAL_AVR/MarlinSerial.h b/Marlin/src/HAL/HAL_AVR/MarlinSerial.h index d0274ebe4..8c2b3f318 100644 --- a/Marlin/src/HAL/HAL_AVR/MarlinSerial.h +++ b/Marlin/src/HAL/HAL_AVR/MarlinSerial.h @@ -62,6 +62,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) @@ -91,6 +94,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 @@ -112,6 +123,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/src/HAL/HAL_DUE/MarlinSerial_Due.cpp b/Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.cpp index 257833b8e..0ff98e62f 100644 --- a/Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.cpp +++ b/Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.cpp @@ -98,6 +98,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 @@ -308,6 +316,19 @@ // Acknowledge errors if ((status & UART_SR_OVRE) || (status & UART_SR_FRAME)) { + + #if ENABLED(SERIAL_STATS_DROPPED_RX) + if (status & UART_SR_OVRE && !++rx_dropped_bytes) --rx_dropped_bytes; + #endif + + #if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS) + if (status & UART_SR_OVRE && !++rx_buffer_overruns) --rx_buffer_overruns; + #endif + + #if ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS) + if (status & UART_SR_FRAME && !++rx_framing_errors) --rx_framing_errors; + #endif + // TODO: error reporting outside ISR HWUART->UART_CR = UART_CR_RSTSTA; } diff --git a/Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.h b/Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.h index c180bb5d0..2f5a07f51 100644 --- a/Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.h +++ b/Marlin/src/HAL/HAL_DUE/MarlinSerial_Due.h @@ -70,6 +70,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 @@ -91,6 +99,14 @@ public: 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/src/gcode/control/M111.cpp b/Marlin/src/gcode/control/M111.cpp index d3c332f8c..d4c362229 100644 --- a/Marlin/src/gcode/control/M111.cpp +++ b/Marlin/src/gcode/control/M111.cpp @@ -58,6 +58,23 @@ void GcodeSuite::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 // !defined(__AVR__) || !defined(USBCON) } SERIAL_EOL(); }